首页 > 数据库 > > RocksDB写流程梳理
写入数据的入口函数是:DBImpl::WriteImpl
rocksdb将每个将要写入的WriteBatch对象封装为一个Writer对象,其中记录了:
因为数据库系统随时都会有接连不断的写请求涌入,为了处理并发,rocksdb将多个writer对象用链表串起来,组成一个WriteGroup, 一个WriterGroup会选出一个leader来管理当前group的写过程。而任意时刻只会有一个WriteGroup被写入。
每个writer写入前要先加入一个WriteGroup。加入的过程其实将writer对象加入到writer链表尾端。每个DB对象都对应一个这样的writer链表,writer链表的尾端由newest_writer_记录。即:

当writer被加入链表以后:
对于作为leader的writer来说,具体的步骤如下:

对于一个write group来说,处于链表头的writer会作为本组的writer。第二步从leader开始向后遍历writer链表,在向后遍历的过程中,任何一个writer的wal配置与leader的wal配置不同,则停止构建write group。例如,假设writer3的配置与leader不一致,则构建的write group的元素为writer1和writer2,writer group会有一个last_writer指针指向本write group中的最后一个writer。


计算好每个writer的sequence后,leader将当前write group的所有writer的状态设置为STATE_PARALLEL_MEMTABLE_WRITER,并将本组的其余writer唤醒,然后将自己的数据写入memtable。
对于作为非leader的writer来说
当leader或者非leader是本组中最后一个完成写memtable的writer,它们都要做一些收尾工作,流程如下:

3. 将本组所有writer的状态置为STATE_COMPLETED,表示完成,然后写流程结束。
写memtable的入口函数为InsertInto,InsertInto会根据是由write group写入或是单个writer写入进行重载,不过基本过程一致,下面以put操作为例说明写memtable的过程:
MemTableInserter: 记录写操作起始的sequence,该sequence会随着写操作的进行自增。
ColumnFamilyMemTables: 对ColumnFamilySet的封装,可以获取每个ColumnFamily的memtable,即:ColumnFamilySet[ColumnFamily_ID].memtable()。
FlushScheduler: 一个装有元素类型为ColumnFamilyData的链表,记录了所有需要刷memtable的ColumnFamily2. 调用当前writer记录的write batch对象的Iterate函数。该函数会遍历当前write batch的所有kv数据对,然后根据操作类型(增删改)调用MemTableInserter对象封装的处理逻辑。
3. MemTableInserter对象的put接口的执行流程如下:
1). 根据column_family_id获取对应的memtable
2). 根据用户指定的配置,如果写模式不是inplace update类型,则将对应的记录加入到memtable中
3). 如果写模式是inplace update类型,则先在memtable中查找对应的key,如果找到了则更新该key对应的value,未找到则加入到memtable
4). 写完一条数据后sequence自增
5). 如果当前memtable需要flush(也就是memtable的size已经达到了配置的阈值),则将memtable对应的ColumnFamily加入FlushScheduler链表中,等待后台线程处理
注意: 如果采用原地更新的话,那么就不能支持多writer并发写了,原因是如果不是原地更新的话,那么同一个key可能会有多个版本:(keyX, sequence1, val1), (keyX, sequence2, val2), (keyX, sequence3, val3),多个writer并发插数据到跳表的时候,一定能够保证,对于相同的key,sequence越大的排在跳表的后面,这可以保证mvcc或者事务的正确性。如果是原地更新,那么同一个key在跳表中只对应一个节点,多writer并发写的时候,无法保证sequence最大的writer最后写入相关的节点。
来源 https://zhuanlan.zhihu.com/p/369384686
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69999831/viewspace-3157900/ ,如需转载,请注明出处,否则将追究法律责任。