美文网首页HADOOP从入门到放弃spark||flink||scalaElasticsearch
换个角度看“顺序写”和“随机写”,以及 LSM tree 理解

换个角度看“顺序写”和“随机写”,以及 LSM tree 理解

作者: 陈半仙儿 | 来源:发表于2018-11-25 21:25 被阅读147次

顺序写

每个 fd 都关联一个 当前的 offset,每次写入 offset 都会更新。

顺序写入就是所有的写都是写当前的 offset,
随机写就是 offset 会从[0~max]里随机取值写,这些随机的 offset 最后都可能会导致磁头的移动。

那么应用层面什么样的数据写入方式能保证磁盘层面是顺序写呢,简单来说就是,

  1. update-in-place 原地更新
  2. append-only btree/copy on write tree 顺序文件末尾追加

LSM - tree

关系数据库和键值数据库存储引擎对比

传统的关系数据库存储采用 B+ 树,数据被按照特定方式放置,能大幅度提升读性能,但写性能下降。

而 no-sql 一般 将整个磁盘就看做事一个日志,在日志中存放永久性数据及其索引,每次都添加到日志末尾。

将数据添加到文件,因为完全顺序,所以写操作性能优秀。但从日志文件读一些数据将比写操作消耗更多的时间,需要倒序扫描直到找到所需内容。相当于牺牲了部分读性能换来了写性能的提升。

深入理解 Log-Structured Merge-Tree(LSM-tree)

对比上面,其实就是 将一个大的查找结构(B+ tree),变换为 将写操作顺序地保存到一些相似的有序文件(sstable/HBASE) 中。每个文件包含了短时间段内的一些改动。因为文件有序,后续查找也会很快。所以这种方式 文件不可修改,永远不会更新,新操作只会写到新文件中,通过周期性的合并来减少文件的个数。

总结一下就是:1. 让操作顺序化,不断追加而不是修改(写性能高);延迟更新,批量写入硬盘。

简单对比读写:写操作被分批处理,只写到顺序块上;读操作有可能访问大量的文件(散乱的读)。

写操作步骤:

  1. 发出写操作
  2. 内存缓存(memtable)中使用树结构来保持key有序
  3. WAL写磁盘(防丢/恢复)
  4. 达到一定规模刷到磁盘上一个新文件里
  5. 越多的数据到存储系统中,就会有越多的不可修改的顺序sstable文件被创建(他们代表了小的、按时间顺序的修改)
  6. 系统周期性发起 compaction,合并文件并删除重复冗余,减少文件个数(因为sstable 是有序结构,可以才用归并排序的思想,所以合并非常高效)

读操作步骤:

  1. 发出读操作
  2. 先检查内存数据(memtable)
  3. 没有这个key
  4. 逆序一个个检查 sstable 直到找到

对比读写操作:
因为需要遍历所有sstable,当数量过多性能就会下降。一方面系统周期性合并sstable、用 cache 等技术;另一方面使用布隆过滤器来避免大量的读文件操作。

相关文章

网友评论

    本文标题:换个角度看“顺序写”和“随机写”,以及 LSM tree 理解

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