LevelDB概述

LevelDB是google开源的key-value,单机,持久化存储引擎:

  • 写操作:写Log的顺序磁盘写和内存中对memtable的操作;
  • 读操作:设计一系列策略保证读的效率;

整体的架构如下:

在写入操作的时候,会先把要写入的操作顺序地写到日志文件中。这样,就算是在memtable的操作中失败了,重新启动的时候也是会从日志文件中还原,这样可靠性就得到了保障。又因为日志文件时顺序的IO,这样也提高了写的效率。日志文件的格式如下:

为了在重启db后可以恢复到退出前的状态,需要把db的状态保存在mainifest文件中:只在mainifest开始保存完整的状态信息,接下来只保存每次compact产生的操作(VersionEdit)。重启db时:获得开头的起始状态,并且依次将VersionEdit重新执行。

在日志文件中,文件开始部分用来存放一些信息,在读取的时候跳过。日志文件是按照块来处理的:一个块中会有一些Record,每个Record有四种类型:头、中、尾、全,这样在顺序读取的时候就能根据Record中的Type字段来获取完整的记录。

在完成Log文件的写入之后就需要来写Memtable,采用跳表的方式组织:

LevelDB中的跳表最多有12层,而且是只能插入。为了保证无锁操作的安全性,插入的Record的Key是不能重复的。所以,Record中的Key并非是用户传入的Key,而是结合SequenceNumber和KeyType生成的内部Key。

在Memtable足够大的时候,就会将其保存到磁盘上,也就是SSTable中,同时生成新的Memtable来接受写入请求。SSTable的结构如下:

 

在data_block中的每一个entry就是一条记录,由于使用前缀压缩的方法,所以需要记录公共前缀的长度。采用前缀压缩的坏处:在根据下标取得其中一条记录时需要从头开始遍历,这样的效率比较低,所以在Data_block中将所有的记录分成几个区域,在restarts中保存了分割的方法。

在每个SSTable中用footer来保存数据块等结构开始的位置。

在Index_block中保存了每个Data_block的最大的Key(大概可以这么说)以及偏移量,这样通过二分能加快查找速度。

LevelDB可能将Memtable结构Dump成多个SSTable,这些文件中的Key的范围可能有重叠部分。所有的SSTable文件可以分为7个Level,刚Dump成的文件属于Level-0,也只有这个Level中的文件的Key存在重叠。
LevelDB根据可以查找的过程大致如下:

LevelDB中包括两种Compaction操作:

  • minor:把Memtable中的数据保存到SSTable中;
  • major:合并不同层级的SSTable文件;

当一个层级中的SSTable文件超过一定数目(应该是随着Level数按指数增长)就会从该层的SSTable文件中选择一个文件和高一层中的文件进行合并操作。对应Level-0和其他层级有不同的操作:

  • Level-0:因为可能有其他文件和被选中的文件中的Key范围有重叠,这时候要将所有有重叠的文件都进行合并;
  • Level-N:因为该层的任意两个文件不存在重叠,所以只合并选中的文件;

在底层选择要合并文件时采用轮流的方式,而在高层选择时,为了保证合并之后各层的文件仍然是有序的,所以要选出所有更高层中与该文件的范围有重叠的文件进行合并。现在的问题是什么时候执行compaction操作?

  • 对于Level-0,因为是无序的,内容太多会严重地影响查询的速度,所以如果文件总大小超过一定限制的时候就会触发compact;
  • 对于Level-N,因为这些是有序的可以进行二分查找,所以影响查询速度的重点是文件数目;

上面的操作貌似大部分都是在磁盘上的,LevelDB会对文件“元信息”和数据信息做缓存,在查找的时候会先尝试从内存中获取。

转载:http://blog.chinaunix.net/uid-22954220-id-5114798.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值