LevelDB 1. 基础数据结构

Slice

作用

  • Slice包括length和一个指向外部字节数组的指针。
  • 相比返回std::tring,返回Slice的开销会小的多(没有拷贝,Slice中没有实际数据,只有指向数据的指针,开销低)。
  • leveldb允许key和value包含’\0’。

兼容性

可以方便实现与std::string的互转。

注意事项

slice的数据是外部管理的,因此slice的使用者需要保证生命周期内外部数组是有效的。

Varint

作用

Varint是一种比较特殊的整数类型,它包含有Varint32和Varint64两种,它相比于int32和int64最大的特点是长度可变。

机制

  • varint是一种紧凑的表示数字的方法,它用一个或多个字节来表示一个数字,值越小的数字使用越少的字节数。采用Varint,对于很小的int32类型的数字,则可以用1个字节来表示。大的数字则可能需要5个字节来表示。

  • varint中的每个字节的最高位(bit)有特殊含义,如果该位为1,表示后续的字节也是这个数字的一部分,如果该位为0,则结束。其他的7位(bit)都表示数字。

7位能表示的最大数是127,因此小于128的数字都可以用一个字节表示。

大于等于128的数字,比如说300,会用两个字节在内存中表示为:
原始二进制:     100101100
编码后二进制: 10 10101100
低                   高
10101100      00000010

InternalKey

作用

  • 用户角度:使用slice作为key
  • leveldb内部:使用InternalKey作为key
  • 结构:[Slice user_key] + [SequenceNumber<<8 + ValueType],后半部分固定64位,即8字节。

LookupKey

作用

当需要在leveldb查找对象的时候,查找顺序是从第0层到第n层遍历查找,找到为止(最新的修改或者删除的数据会优先被找到,所以不会出现一个键有多个值的情况)。由于不同层的键值不同,所以LookupKey提供了不同层所需的键值。

结构

Key结构:
A: klength    varint32               <-- start_
B: userkey  char[klength]          <-- kstart_ 
C: tag          uint64    
                                    <-- end_

A意义:user_key.size() + 8 变长编码后的值
B意义:userkey
C意义:64位整型顺序号<<8+值类型 64位定长编码后的值

memtable_key = A + B + C
internal_key = B + C
user_key = B

Comparator

作用

Comparator是个抽象类,主要用于数据键值比较的,毕竟leveldb是按照键有序存储的,所以比较器算是一个比较通用的类型。

注意

以上的用std::string作为类型,其实数据中可能存在’\0’。在很多情况需要用一些特殊的字符做分割,比如 std::string a=[‘a’, ‘b’, ‘c’, ‘\0’, ‘d’],a的长度是5而不是3。

BytewiseComparatorImpl

作用

  • 因为Slice并没有规定Key具体类型,所以leveldb是支持用户自定义比较器的,在创建leveldb数据库对象的时候通过Option指定。
  • BytewiseComparatorImpl是leveldb默认的比较器,基于二进制比较。默认配置相见 options.cc

InternalKeyComparator

作用

  • 用于内部的Key比较器。
  • cmp原则
    • 1)userkey
    • 2)seq大小,越大越新。
  • FindShortestSeparator / FindShortSuccessor
    • 1)提取userkey,通过userkey查找;
    • 2)追加kMaxSequenceNumber + kValueTypeForSeek。

LevelDB 的整体架构

levelDB-Compaction

MemTable

内存数据结构,具体实现是 SkipList。 接受用户的读写请求,新的数据会先在这里写入。

Immutable MemTable

当 MemTable 的大小达到设定的阈值后,会被转换成 Immutable MemTable,只接受读操作,不再接受写操作,然后由后台线程 flush 到磁盘上 —— 这个过程称为 minor compaction。

Log

数据写入 MemTable 之前会先写日志,用于防止宕机导致 MemTable 的数据丢失。一个日志文件对应到一个 MemTable。

SSTable

Sorted String Table。分为 level-0 到 level-n 多层,每一层包含多个 SSTable,文件内数据有序。除了 level-0 之外,每一层内部的 SSTable 的 key 范围都不相交。

Manifest

Manifest 文件中记录 SSTable 在不同 level 的信息,包括每一层由哪些 SSTable,每个 SSTable 的文件大小、最大 key、最小 key 等信息。

Current

重启时,LevelDB 会重新生成 Manifest,所以 Manifest 文件可能同时存在多个,Current 记录的是当前使用的 Manifest 文件名。

TableCache

TableCache 用于缓存 SSTable 的文件描述符、索引和 filter。

BlockCache

SSTable 的数据是被组织成一个个 block。BlockCache 用于缓存这些 block(解压后)的数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值