美文网首页
leveldb读取流程

leveldb读取流程

作者: 总裁大爷 | 来源:发表于2018-02-28 22:53 被阅读0次

leveldb查找操作主函数:

Status DBImpl::Get(const ReadOptions& options,
                   const Slice& key,
                   std::string* value) {
  Status s;
  MutexLock l(&mutex_);
  SequenceNumber snapshot;
  if (options.snapshot != NULL) {
    snapshot = reinterpret_cast<const SnapshotImpl*>(options.snapshot)->number_;
  } else {
    snapshot = versions_->LastSequence();
  }

  MemTable* mem = mem_;
  MemTable* imm = imm_;
  Version* current = versions_->current();
  mem->Ref();
  if (imm != NULL) imm->Ref();
  current->Ref();

  bool have_stat_update = false;
  Version::GetStats stats;

  // Unlock while reading from files and memtables
  {
    mutex_.Unlock();
    // First look in the memtable, then in the immutable memtable (if any).
    LookupKey lkey(key, snapshot);
    if (mem->Get(lkey, value, &s)) {
      // Done
    } else if (imm != NULL && imm->Get(lkey, value, &s)) {
      // Done
    } else {
      s = current->Get(options, lkey, value, &stats);
      have_stat_update = true;
    }
    mutex_.Lock();
  }

  if (have_stat_update && current->UpdateStats(stats)) {
    MaybeScheduleCompaction();
  }
  mem->Unref();
  if (imm != NULL) imm->Unref();
  current->Unref();
  return s;
}

Get函数主体流程很简单,先从memtable中查找,再从Immutable中查找,最后从磁盘Table中查找。但是查找过程中可以考虑几个问题:
多版本控制
    查找时指定某个快照版本时如何找到数据
    先后插入了数据 "wcc":28, "wcc":29, "wcc":30, 此时查找过程如何
    先插入了数据 "wcc":28 然后删除了数据 "wcc":28, 此时查找过程如何
并发控制
    读数据的时候 其他的写线程会造成哪些影响

对于memtable(底层数据结构是skiplist),插入的数据格式为:


key.png

而skiplist插入查找元素时使用的比较函数是:

// aaa:101  aab:101      -->  aaa:101, aab:101   //user key小的会排在前面
// aaa:101  aaa:102      -->  aaa:102, aaa:101   //user key相同, sequence大的会排在前面(教新的操作)
int InternalKeyComparator::Compare(const Slice& akey, const Slice& bkey) const {
  // Order by:
  //    increasing user key (according to user-supplied comparator)
  //    decreasing sequence number
  //    decreasing type (though sequence# should be enough to disambiguate)
  int r = user_comparator_->Compare(ExtractUserKey(akey), ExtractUserKey(bkey));
  //userkey相同时,比较 (sequence num << 8 | value_type) 
  //实际上sequence num已经能完全区分了
  if (r == 0) {
    const uint64_t anum = DecodeFixed64(akey.data() + akey.size() - 8);
    const uint64_t bnum = DecodeFixed64(bkey.data() + bkey.size() - 8);
    if (anum > bnum) {
      r = -1;
    } else if (anum < bnum) {
      r = +1;
    }
  }
  return r;
}

因此:
 当需要从指定快照版本查找数据时,ReadOptions::snapshot 应该设置成指定版本。查找key时会把 key,快照版本号组合起来进行查找。
 当数据被修改(多次插入),如果没指定版本号,会根据当前最新版本号,找到最后一次插入的数据值。
  当数据插入后被删除,因为删除操作的sequence number更大,因此查找时优先返回,然后根据valueType是kTypeDeletion 告知调用者key对应的数据不存在。

对于磁盘中的Table, compact数据时会保证,如果key的sequence number比最小的snapshot 大的话, delete的数据也不会被drop掉.

相关文章

  • leveldb读取流程

    leveldb查找操作主函数: Get函数主体流程很简单,先从memtable中查找,再从Immutable中查找...

  • Leveldb之并发写入

    这篇文章想分析下Leveldb的写入流程以及Leveldb是如何处理并发写入问题的。阅读https://githu...

  • 庖丁解LevelDB之Iterator

    通过之前对LevelDB的整体流程,数据存储以及元信息管理的介绍,我们已经基本完整的了解了LevelDB。接下来两...

  • Rocksdb整理1--JoinBatchGroup

    Rocksdb相对于leveldb的很重要的一个改进点就是写聚合流程的改进。在leveldb中,写的互斥就一把锁搞...

  • LevelDB写流程分析

    虽然网上关于leveldb源码分析的文章挺多,但还是想写下来记录自己的再次学习过程,早几年前看过一些leveldb...

  • 10. LevelDB源码剖析之缓存机制

    10.1 基本原理 缓存机制一直是性能优化的重要方式,LevelDB在读取SSTable、Block中均采用了缓存...

  • LevelDb之manifest文件

    从这篇文章开始想写写leveldb的小知识。先了解manifest文件,因为这个文件关系到实例的读取。至于这个文件...

  • 从leveldb中学编码技巧(5)

    在读取一个key的值时,leveldb会按照如下顺序查找这个key: 在memtable中查询 在level0中查...

  • 六、HBase读取流程

    1、HBase读取流程 流程分四步: 1.1、Client-Server读取交互逻辑 1.1.1、Client从Z...

  • Python处理excle的方式

    Python处理excle 流程 读取表格 读取excle表格内容 写入表格

网友评论

      本文标题:leveldb读取流程

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