美文网首页
数据存储的一些思考

数据存储的一些思考

作者: 码农苍耳 | 来源:发表于2017-10-02 16:05 被阅读22次

    上篇主要讲述了我们在平时iOS开发中常见的一些缓存及其区别,虽然这已经满足了绝大多数的场景,但是当我们遇到特殊场景的时候,又该如何呢。

    缓存策略

    一般来说,客户端使用LRU的缓存策略就已经足够,但是在特定场合就不是那么适用了。比如淘宝每秒百万级别的查询,如果使用LRU,那么可能有些热门商品就会被清理出缓存,从而得不偿失了。

    • First In First Out (FIFO)
    • Last In First Out (LIFO)
    • Least Recently Used (LRU)
    • Time aware Least Recently Used (TLRU)
      拥有过期时间的LRU,常见的比如http缓存
    • Most Recently Used (MRU)
    • Random Replacement (RR)
    • Segmented LRU (SLRU)
    • Least-Frequently Used (LFU)
    • Least Frequent Recently Used (LFRU)
    • LFU with Dynamic Aging (LFUDA)

    如果真的有如此特殊的场景,就需要我们去选择最优的策略来保证缓存的命中率了。

    memory map

    其中很多方案都提到了内存映射的技术。

    内存映射会少去很多的解析编码、内存拷贝操作,所以性能上会优于普通的文件读写。

    但是内存映射本身就存在一些缺陷,比如32/64操作系统的兼容性,大端小端的兼容性,字节对齐问题。所以并不是任何情况下都适合使用内存映射。如果需要保证兼容性,则需要在设计的时候就要考虑到这样的问题。

    搜索优化

    作为数据存储最频繁的当然是查询功能,那么如何保证查询的性能呢,那么就涉及到索引了。

    操作系统本身的文件系统就带有B/B+数所做的索引,所以我们在目录下查找一个文件其实是很快的,就算这个文件夹下内容非常的多。所以一般情况下我们并不需要为文件系统做额外的索引优化。

    如果是内存中的缓存,那么使用hash表是最通用的一种方式了。如果是数组则要考虑好承载能力了,少量的数据可能没有问题,当数量到达一定程度后就会暴露出来。这时候可以使用自平衡二叉树、B树、跳跃链表等来做优化了。

    sqlite是我们使用最多的一种数据存储方式,提升sqlite搜索速度的方式就是对某列增加索引,具体需要根据具体情况来分析。默认的sqlite索引是B树,也可以配置为R树索引,在坐标数据库表可能会表现更优秀。

    存储格式

    数据的存储格式也是非常关键的一个部分。

    像UserDefault这种全量更新的方式,在单一数据变化的时候就需要全部重新序列化并且全部保存,所以如果拥有大量数据或者数据非常庞大的时候,就会变得效率低下。

    像ImageCache这种按照单文件保存,如果是小数据,每次都需要去读磁盘,反而效率会降低。由于磁盘的读取和写入并不是单字节的,都是按块读写是最有效率的,所以多个小数据可以一次性读取和写入。

    如果是像sqlite那样按照chunk来局部更新文件,则需要非常小心的处理每个数据存储模块,同时也要非常小心处理多线程的问题。另外也需要添加索引来确保效率。

    如果是随机读为主的情况下,sqlite能够完成这个任务,但是如果是以写为主,那么sqlite就可能出现性能问题(虽然按照移动客户端来说不太可能有这么大的写的需求)。

    最后

    如何去选择缓存和存储方案,还是需要根据实际情况,通常一个通用的方案已经足够,但是在某些特殊场景还是需要我们去自己设计这一套方案。

    相关文章

      网友评论

          本文标题:数据存储的一些思考

          本文链接:https://www.haomeiwen.com/subject/qiltyxtx.html