《设计数据密集型应用》- Designing Data-Intensive Application - 第3章 存储与检索 读书笔记

14 篇文章 0 订阅
10 篇文章 0 订阅

在这里插入图片描述

存储引擎

面向日志

问题:数据量大时由于需要遍历整个日志文件,性能急剧下降

  • 解决方案:索引

    • 索引写性能弱于追加文件的性能

    • 方案一:HASHMAP保存KEY->文件偏移量

      • 实例:bitcask

      • 适用场景:KEY数不多,但更新频繁的场景,索引可以放在内存

      • 单个日志文件过大时,关闭该文件,开启新的日志段文件,对旧的段日志文件进行重写压缩

        • 相关实例:REDIS AOF重写
      • 段文件之间也可以进行合并,每个段维护各自的HASHMAP

        • 合并旧段可防止文件碎片化问题
      • 当客户端请求KEY时,先查询最新段文件对应的HASHMAP,没有再找第二最新,依此类推

      • 并发时,由于追加写文件,只有一个写线程,而读可以有多个线程

      • 存在问题

        • 数据库重启或机器重启HASHMAP丢失,从段日志文件恢复时如果文件比较大,恢复时间会很长

          • 解决方案:Bitcask对hashmap进行快照,并存储在磁盘
        • 写日志时数据崩溃,日志文件不完整

          • 解决方案:记录增加校验和,检验不通过丢弃数据
        • HASHMAP需要全部加载至内存,如果在磁盘上维护,会有大量的随机IO导致性能下降

        • 连续性区间查询如bag-book效率低,需要逐个查询

    • 方案二:SSTable

      • 实例:LevelDB RocksDB Hbase Lucene的倒排索引(KEY为单词,VALUE为文档ID)

      • 方案一内存中存储了所有键的HASHMAP,将日志文件的key-value按key排序,就可以不必保存所有KEY的HASHMAP,减少HASHMAP的存储量

        • 节约内存空间
        • 键排序后获取连续性的键值时可进行顺序读
      • 具体实现方案

        • 在内存中借助红黑树或AVL树维护一张内存表

        • 当内存表大小阈值超过一定值时,将内存表落盘(此时磁盘上的KEY是排序的),创建新的内存表实例

          • 落盘时,SSTable通常会进行分层合并,每一层文件保存各自的数据文件与SSTable文件

        • SSTable压缩

          • Tiered Compaction

          • Leveled Compaction

          • 参考链接:

            • https://docs.scylladb.com/architecture/compaction/compaction-strategies/#compaction-strategies
            • https://www.jianshu.com/p/8de55d5df05e
        • 客户端请求KEY时,先在内存表中查询,没有找磁盘最新段文件,再次新等等

        • 如果数据库崩溃,未落盘的数据会丢失,此时需要借助追加式日志(非排序,WAL)恢复

        • 写放大:写入一条数据会引起落盘、合并等写操作

        • 读放大:在查询一个KEY时会按照内存表->逐级SSTable文件的顺序查询,当查询的KEY不存在,会有较大延迟。

          • 缓解方案:Bloom滤波器

            • 这里需要指出基础Bloom filter由于Hash映射的有限性,会有误将不存在的元素判定为存在的可能性;另外,对于删除元素操作,bloom filter也无法直接重置标志位。衍生出的变种filter包括:Counting Bloom Filter Partial Bloom Filter Compressed Bloom Filter

面向页

B-Tree

  • 特点:

    • 原地更新
  • 让B树更可靠性

    • WAL配合(Redo Log),以便在更新页时数据库发生崩溃进行恢复
  • B树优化

    • 使用COW,而不是WAL与页面覆盖进行更新操作,即修改的页面写至不同的位置,并创建新的树的父级页指向它完成

    • 尽量使得树的页面在磁盘上按顺序存储以加速顺序查找,但随着树的增长,维持该顺序是相当困难的

    • 叶子页面添加到兄弟节点的指针

      • B+ Tree 非叶子节点只存指向下一级节点的指针;相邻叶子节点间有指针指向
  • LSM B-Tree对比

    • LSM优点

      • 顺序写SSTable,写入吞吐量高,B树随着树的增大,节点分裂,随机读写的概率会增大
      • 压缩得更好,产生的文件较B树更小
    • LSM缺点

      • Compaction开销大,查询时延在Compaction时会加大,时延不可控,而B树行为具有更好的预测性
      • B树中的键只存在于磁盘上的一个位置,而LSMTREE在磁盘上会有多份数据,B树在事务上有强大语义支持

事务处理

面向列

列存储

  • Parquet是一种列式存储格式

列压缩

  • 如位图BITMAP编码
  • 对于稀疏度较高的,还可以用游程编码

列排序

  • 排序是针对所有列的,仅对一列作排序无意义
  • 排序有助于进行数据压缩,如使用游程编码,但仅对第一排序列有较大压缩效果

写入列存储

  • 使用LSM树,如果选用B树,则插入操作需要更新所有的列,而对于LSM树,则可将内容先写入内存,随后落盘进行文件合并。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值