LevelDb日知录之七:读取记录

        LevelDb是针对大规模Key/Value数据的单机存储库从应用的角度来看LevelDb就是一个存储工具而作为称职的存储工具常见的调用接口无非是新增KV删除KV读取KV更新Key对应的Value值这么几种操作LevelDb的接口没有直接支持更新操作的接口如果需要更新某个KeyValue,你可以选择直接生猛地插入新的KV保持Key相同这样系统内的key对应的value就会被更新或者你可以先删除旧的KV 之后再插入新的KV这样比较委婉地完成KV的更新操作

        假设应用提交一个Key下面我们看看LevelDb是如何从存储的数据中读出其对应的Value值的1LevelDb读取过程的整体示意图


        LevelDb首先会去查看内存中的Memtable如果Memtable中包含key及其对应的value则返回value值即可如果在Memtable没有读到key则接下来到同样处于内存中的Immutable Memtable中去读取类似地如果读到就返回若是没有读到,那么只能万般无奈下从磁盘中的大量SSTable文件中查找因为SSTable数量较多而且分成多个Level所以在SSTable中读数据是相当蜿蜒曲折的一段旅程总的读取原则是这样的首先从属于level 0的文件中查找如果找到则返回对应的value如果没有找到那么到level1中的文件中去找如此循环往复直到在某层SSTable文件中找到这个key对应的value为止或者查到最高level查找失败说明整个系统中不存在这个Key)

        那么为什么是从MemtableImmutableMemtable再从ImmutableMemtable到文件而文件中为何是从低level到高level这么一个查询路径呢道理何在之所以选择这么个查询路径是因为从信息的更新时间来说很明显Memtable存储的是最新鲜的KVImmutable Memtable中存储的KV数据对的新鲜程度次之而所有SSTable文件中的KV数据新鲜程度一定不如内存中的MemtableImmutableMemtable对于SSTable文件来说如果同时在level LLevelL+1找到同一个keylevelL的信息一定比level L+1的要新也就是说上面列出的查找路径就是按照数据新鲜程度排列出来的越新鲜的越先查找

        为啥要优先查找新鲜的数据呢这个道理不言而喻举个例子比如我们先往levelDb里面插入一条数据{key="www.samecity.com" value="我们"},过了几天samecity网站改名为69同城此时我们插入数据{key="www.samecity.com" value="69同城"}同样的key,不同的value逻辑上理解好像levelDb中只有一个存储记录即第二个记录但是在levelDb中很可能存在两条记录即上面的两个记录都在levelDb中存储了此时如果用户查询key="www.samecity.com",我们当然希望找到最新的更新记录也就是第二个记录返回这就是为何要优先查找新鲜数据的原因

        前文有讲对于SSTable文件来说如果同时在level LLevelL+1找到同一个keylevelL的信息一定比level L+1的要新这是一个结论理论上需要一个证明过程否则会招致如下的问题为神马呢从道理上讲呢很明白因为Level L+1的数据不是从石头缝里蹦出来的也不是做梦梦到的那它是从哪里来的Level L+1的数据是从LevelL 经过Compaction后得到的如果您不知道什么是Compaction那么........也许以后会知道的),也就是说您看到的现在的Level L+1层的SSTable数据是从原来的LevelL中来的现在的LevelL比原来的Level L数据要新鲜所以可证现在的Level L比现在的LevelL+1的数据要新鲜

        SSTable文件很多如何快速地找到key对应的valueLevelDblevel 0一直都爱搞特殊化level 0和其它level中查找某个key的过程是不一样的因为level 0下的不同文件可能key的范围有重叠某个要查询的key有可能多个文件都包含这样的话LevelDb的策略是先找出level0中哪些文件包含这个keymanifest文件中记载了level和对应的文件及文件里key的范围信息LevelDb在内存中保留这种映射表), 之后按照文件的新鲜程度排序新的文件排在前面之后依次查找读出key对应的value而如果是非level 0的话因为这个level的文件之间key是不重叠的所以只从一个文件就可以找到key对应的value

        最后一个问题,如果给定一个要查询的key和某个keyrange包含这个keySSTable文件那么levelDb是如何进行具体查找过程的呢levelDb一般会先在内存中的Cache中查找是否包含这个文件的缓存记录如果包含则从缓存中读取如果不包含则打开SSTable文件同时将这个文件的索引部分加载到内存中并放入Cache 这样Cache里面就有了这个SSTable的缓存项但是只有索引部分在内存中之后levelDb根据索引可以定位到哪个内容Block会包含这条key从文件中读出这个Block的内容在根据记录一一比较如果找到则返回结果如果没有找到那么说明这个levelSSTable文件并不包含这个key所以到下一级别的SSTable中去查找

        从之前介绍的LevelDb的写操作和这里介绍的读操作可以看出相对写操作读操作处理起来要复杂很多所以写的速度必然要远远高于读数据的速度也就是说LevelDb比较适合写操作多于读操作的应用场合而如果应用是很多读操作类型的那么顺序读取效率会比较高因为这样大部分内容都会在缓存中找到尽可能避免大量的随机读取操作

备注:本文转载自朗格科技:http://www.samecity.com/blog/Article.asp?ItemID=122

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值