[RocksDB剖析系列] 写入流程

1iin

WAL

参考资料:

在RocksDB中,WAL的写入是单线程顺序串行写入的,而MemTable则是可以并发多线程写入的(通过allow_concurrent_memtable_write配置打开),或许在系统压力到一定阶段的时候, 写入WAL会成为性能的瓶颈。

多个写线程会组合成一个链表形式的write_group,而第一个进入链表的会成为leader,其他为follower。

创建完成该链表之后,则开始计算有多少个写请求可以批量的进行,同时更新写请求组write_group中的批量写尺寸以及个数等信息。该操作完成之后,则将进入写WAL的流程,根据write_group生成一个merged_batch,该merged_batch中记录着应当被写入WAL的内容。接着就通过WriteToWAL将merged_batch写入WAL中,这里会根据WriteOptions.sync配置来决定是否对WAL进行落盘操作。

如果WriteOptions.sync为false,WAL不会被同步进硬盘。除非操作系统认为这些数据必须被flush(例如产生了太多的dirty pages),用户不需要等待任何写入IO。这种模式下,WAL的写不是crash safe的。

在WAL的写入完成后,leader会唤醒follower,并行地(可配置)向Memtable写入。当Immutable Memtable被flush或是WAL的文件大小达到max_total_wal_size(默认为Memtable大小的四倍)时,新的WAL会被创建出来。而后者的创建也会和Memtable的flush一块进行。

如果开启enable_pipelined_write配置,将引入流水线,第一个group的WAL提交后,在它执行memtable写入时,下一个group同时开启,以到达Pipeline写入的效果。

Manifest

参考:
https://gocode.cc/project/13/...

在rocksdb中,为了恢复磁盘上数据的一致性状态,引入了Version概念,通过记录每一次的Version变更,形成MANIFEST日志。

每次Immutable memtable落盘后,就会修改一次磁盘的SST文件列表,这时候会产生一次VersionEdit同时通过此VersionEdit来生成一个新版本。该VersionEdit会写入到一个日志中,该日志存储着最近的所有VersionEdit,该文件就被称之为Manifest log。当一个Manifest log被写满之后,则会生成一个新的Manifest log。

在生成了新文件并且写入完毕之后,在CURRENT文件中的内容更改为最新的Manifest log文件名。

当一个操作通过迭代器迭代数据的时候,会引用当前最新的Version,该Version会存在于VersionSet中,即使经过了Compact后该文件被移除了,亦或者是新增了新的SST后产生了新的Version,都不会影响当前迭代器所可见的数据范围。当迭代器迭代结束之后,则会解除对该Version引用。当一个Version没有被引用且不是最新的版本时,则可以被移除,同时对其包含的所有SST解除引用。相似的,当某个SST文件没有被任何的Version引用的时候,也会被清理。

阅读 963

Move on.

4 声望
3 粉丝
0 条评论

Move on.

4 声望
3 粉丝
文章目录
宣传栏