Lucene底层原理和优化经验分享(2)-Lucene优化经验总结

  系统优化遵从木桶原理:一只木桶能盛多少水,并不取决于最高的木板,而取决于最短的那块木板。优化Lucene也同样,找到性能瓶颈,找对解决方法,才能事半功倍,本文将从三方面阐述我们的Lucene优化经验:
  1. 找准方向 -> Lucene性能瓶颈分析。
  2. 找对方法 -> Lucene代码架构分析。
  3. 方法落地 -> 优化经验总结。

1. Lucene性能瓶颈分析

  上篇Lucene底层原理分析了Lucene索引结构:内存+磁盘,打开索引库时只有tip和fdx文件会被加载到内存中,tip为FST的前缀索引,fdx为正向文件索引,其他文件tim、doc、fdt都放在硬盘,一次完整的检索过程与索引文件的交互过程如图:
这里写图片描述 
  整个流程至少发生三次随机IO:
  1. 读后缀词块
  2. 读倒排表
  3. 取文档(如果文档号跳跃性很大或者因为打分完全乱序,那么会发生更多次随机IO,极端情况就是取多少文档就发生多少次随机IO)
  当前机械硬盘随机IO响应时间平均在10ms左右,远大于CPU+内存计算时间,而且这只是针对一个查询条件,若多个查询条件、跨多列、甚至模糊查询,随机IO请求更多,因此Lucene查询性能瓶颈主要集中磁盘IO性能上,尤其随机IO性能。所以我们的优化方向就是:
  1. 减少IO请求。
  2. 顺序IO代替随机IO。

2. Lucene代码架构

  上一节分析了Lucene性能瓶颈,这一节分析Lucene代码架构,找到从哪里下手去实现优化。
  Lucene从4.0版本后,代码全面模块化,并开放了很多接口,包括索引格式接口Codec、打分接口Similarity、文档收集接口Collector,开发者想基于Lucene再开发,不再需要侵入式修改源代码,而是基于接口,插件式修改。我们结合业务场景和开放接口自定义了Lucene检索模式。
  Lucene检索大致时序图:
  这里写图片描述   
  1. APP解析用户查询生成查询条件Query。
  2. IndexSearcher重写Query并生成Weight。
  3. Weight会生成Scorer,Scorer创建相应查询条件的倒排表迭代器。
  4. 调用scoreALl(),遍历所有文档ID,依次传给传给Collector。
  5. Collector得到文档ID后,调用打分模块Similarity得到文档分值,并根据分值和文档收集器具体实现决定是否返回。Lucene默认的收集器TopScoreDocCollector,会根据用户定义的文档数如100,返回分值前100的文档ID。
  
  我们对Lucene的修改主要在图中标红的文档收集过程,一是屏蔽打分,二是修改文档收集模式,下一节会详细阐述。

3. 优化经验总结

  基于底层原理和代码架构,我们知道了需要做什么和怎么做:IO、IO、还是IO,以下我们全文检索系统的主要优化方案:

3.1单盘优化

解决问题:
  硬盘随机IO性能低。
解决方案:
  1. 将原先的Raid5拆分,改用单盘,因为Raid5随机读写性能 < n*单盘。
  2. 将索引文件tim、doc使用固态硬盘SSD存放,正向文件fdt使用机械硬盘,这样综合了SSD随机读写性能高,机械硬盘成本低、存储空间大的优点。
  3. 对同一磁盘上索引库进行统一管理,单线程处理对同一硬盘上索引库的检索请求,防止同一硬盘多库之间同时访问降低磁盘性能。这里可以根据实际测试情况调整具体线程数,但线程数不宜过多。
  

3.2布隆过滤器

解决问题:
  有些单词不在索引库里,但还需要进索引库查询,发起不必要的IO请求。

解决方案:
  使用布隆过滤器,预先判断单词是不是在该索引库里。布隆过滤器原理很简单,对一单词哈希,并映射到相应bit,设置为1,判断时同样做哈希,并去相应bit位取值,若为1,则可能存在,进库查询,若为0,则肯定不存在,不需进库查询。
这里写图片描述

  对Lucene实现布隆过滤器有两种方式:
  1. 在应用层,Lucene之外实现。
  2. 改写Lucene的Codec接口,添加布隆过滤器功能,使用布隆过滤器预先过滤查询条件。
  后来我们经过测试,选用了第一种方案,因为布隆过滤器十分消耗内存、加载时间很长,而且我们同一索引库为提

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值