美文网首页
RocksDB系列十九:Iterator Implementat

RocksDB系列十九:Iterator Implementat

作者: 薛少佳 | 来源:发表于2018-07-24 17:28 被阅读0次

    RocksDB Iterator

      RocksDB Iterator提供用户以有序的方式前向或者后向遍历DB,也可以seek 到DB的特定key上。为了做到这样,Iterator必须以有序流的方式访问DB。RocksDB Iterator的实现类命名为DBIter。

    DBIter

    • Implementation: db/db_iter.cc
    • Interface: Iterator

      DBIter是InternalIterator的封装。DBIter的任务就是解析由InternalIterator 暴露出来的InternalKeys,最后以user key的形式展现。
    Example:
    The underlying InternalIterator exposed

    InternalKey(user_key="Key1", seqno=10, Type=Put)    | Value = "KEY1_VAL2"
    InternalKey(user_key="Key1", seqno=9,  Type=Put)    | Value = "KEY1_VAL1"
    InternalKey(user_key="Key2", seqno=16, Type=Put)    | Value = "KEY2_VAL2"
    InternalKey(user_key="Key2", seqno=15, Type=Delete) | Value = "KEY2_VAL1"
    InternalKey(user_key="Key3", seqno=7,  Type=Delete) | Value = "KEY3_VAL1"
    InternalKey(user_key="Key4", seqno=5,  Type=Put)    | Value = "KEY4_VAL1"
    

    But what DBIter will expose to the user is

    Key="Key1"  | Value = "KEY1_VAL2"
    Key="Key2"  | Value = "KEY2_VAL2"
    Key="Key4"  | Value = "KEY4_VAL1"
    

    MergingIterator

    • implementation: table/merging_iterator.cc
    • Interface: InternalIterator
      MergingIterator 包括很多 child iterators,MergingIterator 是一个Iterators堆。在MergingIterator 中,我们把所有的child Iterator放进heap中,以一种有序的流形式暴露。
      Example:
      The underlying child Iterators exposed:
    = Child Iterator 1 =
    InternalKey(user_key="Key1", seqno=10, Type=Put)    | Value = "KEY1_VAL2"
    
    = Child Iterator 2 =
    InternalKey(user_key="Key1", seqno=9,  Type=Put)    | Value = "KEY1_VAL1"
    InternalKey(user_key="Key2", seqno=15, Type=Delete) | Value = "KEY2_VAL1"
    InternalKey(user_key="Key4", seqno=5,  Type=Put)    | Value = "KEY4_VAL1"
    
    = Child Iterator 3 =
    InternalKey(user_key="Key2", seqno=16, Type=Put)    | Value = "KEY2_VAL2"
    InternalKey(user_key="Key3", seqno=7,  Type=Delete) | Value = "KEY3_VAL1"
    

    MergingIterator 将所有的child Iterators 放到堆中,以有序流的形式暴露。

    InternalKey(user_key="Key1", seqno=10, Type=Put)    | Value = "KEY1_VAL2"
    InternalKey(user_key="Key1", seqno=9,  Type=Put)    | Value = "KEY1_VAL1"
    InternalKey(user_key="Key2", seqno=16, Type=Put)    | Value = "KEY2_VAL2"
    InternalKey(user_key="Key2", seqno=15, Type=Delete) | Value = "KEY2_VAL1"
    InternalKey(user_key="Key3", seqno=7,  Type=Delete) | Value = "KEY3_VAL1"
    InternalKey(user_key="Key4", seqno=5,  Type=Put)    | Value = "KEY4_VAL1"
    

    MemtableIterator

    • Implementation: db/memtable.cc
    • Interface: InternalIterator

    MemtableIterator是MemtableRep::Iterator的封装,内存表实现自己Iterator都是以keys/values的有序流的形式暴露。

    BlockIter

    • Implementation:table/block.h
    • Interface: InternalIterator

    这个Iterator用来从SST file中读取blocks,与blocks是Index blocks或者data block是无关。由于,SST file blocks是有序的且不可更变的,所以我们可以load block数据到memory总,然后为这个有序的数据创建一个BlockIter。

    TwoLevelIterator

    • Implementation: table/two_level_iterator.cc
    • Interface: InternalIterator

    一个TwoLevelIterator 包含两个Iterators

    • First level Iterator (first_level_iter_)
    • Second level Iterator (second_level_iter_)

    first_level_iter_用来计算出接下来要使用的second_level_iter_,second_level_iter_指向我们要读取的实际数据。
    Example:
    RocksDB使用TwoLevelIterator 来读取SST file,first_level_iter_ 是SST File Index block上的BlockIter,second_level_iter_ 是Data Block上的BlockIter。
    下面看一个简单的SST file,有4个Data blocks和1个Index Block

    [Data block, offset: 0x0000]
    KEY1  | VALUE1
    KEY2  | VALUE2
    KEY3  | VALUE3
    
    [Data Block, offset: 0x0100]
    KEY4  | VALUE4
    KEY7  | VALUE7
    
    [Data Block, offset: 0x0250]
    KEY8  | VALUE8
    KEY9  | VALUE9
    
    [Data Block, offset: 0x0350]
    KEY11 | VALUE11
    KEY15 | VALUE15
    
    [Index Block, offset: 0x0500]
    KEY3  | 0x0000
    KEY7  | 0x0100
    KEY9  | 0x0250
    KEY15 | 0x0500
    

    要想读这个file,我们要创建一个TwoLevelIterator

    • first_level_iter_ => BlockIter over Index block
    • second_level_iter_ => BlockIter over Data block that will be determined by first_level_iter_

    当通过TwoLevelIterator seek到KEY8时,首先使用first_level_iter_ (BlockIter over Index block)计算出哪个block可能包含这个key,结果是设置second_level_iter_ to be (BlockIter over data block with offset 0x0250)。然后我们使用second_level_iter_ 在data block中读取key &value

    相关文章

      网友评论

          本文标题:RocksDB系列十九:Iterator Implementat

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