Tair LDB基于Prefixkey的范围查找性能优化项目之后续问题解决记录

本文记录了Tair LDB基于Prefixkey的范围查找性能优化项目后遇到的问题及其解决方案。问题包括:无prefixkey的scan接口处理和delete时携带prefix信息。解决方案涉及ReadOptions参数调整、特殊key的识别以及Delete操作中添加Prefix key支持。

项目是按照“Tair LDB基于Prefixkey的范围查找性能优化项目提议方案”的步骤一步步完成的,目前方案中提出的三个重点问题已经全部解决,如下所示:


虽然已经使用prefix bloomfilter对prefix key进行过滤来提升范围查找的性能,经过实验测试也达到了一定的效果。但是这个问题的解决方案又导致了新问题的产生,即产生了下面两个问题:

问题1. ldb_instance.cpp(客户端和ldb底层交互的接口)中还有类似begin_scan(扫描某一个bucket)的接口。这些scan的key是没有prefixkey的,且编码信息也不完整(并非是前几次文章所说的前面9字节元信息和area信息编码+后面8字节sequence和valueType编码)。如果这时候也按之前的方法提取prefix key必然会产生错误,而且这种情况也不需要prefix key和bloomfilter,因此需要这块需要考虑。

问题2. delete的时候也需要带入prefix的相关信息。 如果不带,那么在get_range的时候,可能会出现已经delete了,但是依然被扫描出来了。 这个怎么理解呢?一开始我也没搞明白,因为觉得delete操作是根据delete标记来判断是否查找到的数据是否是delete过的,如果是就不取就是了,跟prefix key没什么关系。后来在导师的指导下才彻底搞懂,原来自己忽略了一个非常重要的事实:delete和put相同的某个key可能存储在sst不同的block上,甚至在不同的sst文件里。下面是导师的指导:
1. bloomfilter是在sst的block中的。
2. prefix_put时,会在某个sst(比如B)中写入该prefixkey bloomfilter
3. prefix_remove的时候(即delete时),该delete key在其他sst的可能性非常大。 而其它sst中是没有该prefix key的bloomfilter。 而其它sst(比如A)一般会在低层level
4. get_range中用merge iterator遍历时,遍历到A时,先判断prefixkey bloomfilter,结果为无(因为A的prefix bloomfilter中没有存储delete key的prefix,因此这次判断实际上是错误的),则遍历B,判断prefixkey bloomfilter,结果为有。最终结果暴露了本该删除的数据


问题来了就要解决,下面是在导师指导及自己思考下提供的解决方案,方案不唯一,这里提供一个参考。

问题1解决方案

对于类似begin_scan里的key没有prefix的情况,需要在prefix bloomfilter过滤之前进行判断,如果是这种情况的key则不需要经过bloomfilter。对于这个问题,有两种解决方案:

方法1:通过每次操作的option传入参数,这里的option指的是ReadOptions,在里面添加参数bool use_prefix_bloom;默认值是true,然后在begin_scan等方法中在扫描之前设置该参数为false,下面是添加了use_prefix_bloom参数的ReadOptions:

// Options that control read operations
struct ReadOptions {
    
    
  // If true, all data read from underlying storage will be
  // verified against corresponding checksums.
  // Default: false
  bool verify_checksums;

  // Should the data read for this iteration be cached in memory?
  // Callers may wish to set this field to false for bulk scans.
  // Default: true
  bool fill_cache;

  // If "snapshot" is non-NULL, read as of the supplied snapshot
  // (which must belong to the DB that is being read and which must
  // not have been released).  If "snapshot" is NULL, use an impliicit
  // snapshot of the state at the beginning of this read operation.
  // Default: NULL
  const Snapshot* snapshot;

  bool use_prefix_bloom;

  ReadOptions()
      : verify_checksums
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值