Lucene Hack之通过缩小搜索结果集来提升性能

2024-02-13 05:18

本文主要是介绍Lucene Hack之通过缩小搜索结果集来提升性能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、缘起

Lucene在索引文件上G之后的搜索性能下降很严重,随便跑个搜索就要上0.x秒。如果是单线程搜索那么性能尚可,总可以在0.x秒返回结果,如果是Web式的多线程访问,由于Lucene的内部机制导致数据被大量载入内存,用完后立即丢弃,随之引起JVM频繁GC,性能极其低下,1-10秒的长连接比比皆是。这也是世人为之诟病的Lucene应用瓶颈问题,那么是否有解决方法呢?

 

二、思路

我们来观察Google, Baidu的搜索,有一个总体的感觉就是搜索结果多的关键词耗时比较少,结果少的关键词耗时反而多,且结果多的时候会说“约******个结果”。隐士猜测Google, Baidu的算法是找到前n个结果后停止扫描索引,根据前n个结果来推断总共有多少个结果,此猜想可由Google, Baidu翻页限制而得到部分验证。

再看Lucene,其Hits.length()返回的总是精确的结果,如果可以让Lucene也返回模糊的结果,那么索引文件就算是10G也可以轻松应对了。

 

三、探索

隐士带着这个问题访名山、觅高人,可惜没有找到前人的成果,可能是隐士走的路不够勤,如有类似的解决方案,隐士不吝赐教。

无奈之下,隐士详细研究了Lucene 2.1.0源码,准备重新发明轮子。

一般来说大多数搜索应用中的Query都会落在BooleanQuery上,隐士就拿它开刀。一路看来,BooleanScorer2里的一个method吸引了隐士,代码如下:

 

	public void score(HitCollector hc) throws IOException {if (countingSumScorer == null) {initCountingSumScorer();}while (countingSumScorer.next()) {hc.collect(countingSumScorer.doc(), score());}}

  

 

 

while循环里嵌入写日志代码可证结果集有多大,此处就循环了多少次。countingSumScorer.next()的意思是找到下一个符合boolean规则的document,找到后放入HitCollector,这HitCollector后面会换个马甲放在大家熟悉的Hits里面。

         如果可以在这个while循环里嵌一个break,到一定数量就break出来,性能提升将相当明显。这个代码相当简单,果然大幅提高了性能,带来的副作用是结果不太准,这个可以通过调整业务模型、逻辑来修正。毕竟这是一条提升Lucene性能的有效方法。

细细想来,正是由于这个break会导致结果集大的关键词提前出来,搜索时间少,结果集小的关键词不可避免会走完整个索引,相应的搜索时间会长一点。

 

四、效果

由于具体嵌入代码的过程极其繁琐,隐士将在第二回详细讲解。这第一回先来个Big picture 历尽千辛万苦,隐士终于搞定了这套程序,效果可以从隐士做的视频搜索http://so.mdbchina.com/video/%E7%BE%8E%E5%A5%B3看出。

 

这个关键词“美女”可以找到18万个视频,平均0.5秒返回结果,现在用上了新算法,只要0.06x秒返回结果,而且返回结果足够好了,估算的8.5万个结果虽然离18万有很大差距,不过由于是估算的,差2-3倍应属可以接受的。

 

由算法的特性可知,while里面的hc.collect总可以在常量时间内完成,循环次数又是<=常量,该算法的时间复杂度只和BooleanQuery的复杂程度相关,和索引文件大小以及命中的Document在索引文件内的分布密度没有关系,因为BooleanQuery的复杂程度决定了countingSumScorer.next()需要经过多少次判断、多少次读取索引文件,countingSumScorer.next()正是整个算法中耗时不定的部分。

 

现在这个视频搜索的索引文件接近3G,热门关键词可以在0.0x秒返回结果,隐士相信即使以后索引文件上到10G,依然可以在0.0x秒返回结果。

 

(注:这个视频搜索实际使用效果会打折扣,因为后台索引也在这台机器上,以后会分服务器,现在暂时在一起。)

这篇关于Lucene Hack之通过缩小搜索结果集来提升性能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/704571

相关文章

基于Python Playwright进行前端性能测试的脚本实现

《基于PythonPlaywright进行前端性能测试的脚本实现》在当今Web应用开发中,性能优化是提升用户体验的关键因素之一,本文将介绍如何使用Playwright构建一个自动化性能测试工具,希望... 目录引言工具概述整体架构核心实现解析1. 浏览器初始化2. 性能数据收集3. 资源分析4. 关键性能指

Zabbix在MySQL性能监控方面的运用及最佳实践记录

《Zabbix在MySQL性能监控方面的运用及最佳实践记录》Zabbix通过自定义脚本和内置模板监控MySQL核心指标(连接、查询、资源、复制),支持自动发现多实例及告警通知,结合可视化仪表盘,可有效... 目录一、核心监控指标及配置1. 关键监控指标示例2. 配置方法二、自动发现与多实例管理1. 实践步骤

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

PowerShell中15个提升运维效率关键命令实战指南

《PowerShell中15个提升运维效率关键命令实战指南》作为网络安全专业人员的必备技能,PowerShell在系统管理、日志分析、威胁检测和自动化响应方面展现出强大能力,下面我们就来看看15个提升... 目录一、PowerShell在网络安全中的战略价值二、网络安全关键场景命令实战1. 系统安全基线核查

HTML5 搜索框Search Box详解

《HTML5搜索框SearchBox详解》HTML5的搜索框是一个强大的工具,能够有效提升用户体验,通过结合自动补全功能和适当的样式,可以创建出既美观又实用的搜索界面,这篇文章给大家介绍HTML5... html5 搜索框(Search Box)详解搜索框是一个用于输入查询内容的控件,通常用于网站或应用程

JVisualVM之Java性能监控与调优利器详解

《JVisualVM之Java性能监控与调优利器详解》本文将详细介绍JVisualVM的使用方法,并结合实际案例展示如何利用它进行性能调优,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录1. JVisualVM简介2. JVisualVM的安装与启动2.1 启动JVisualVM2

Java使用MethodHandle来替代反射,提高性能问题

《Java使用MethodHandle来替代反射,提高性能问题》:本文主要介绍Java使用MethodHandle来替代反射,提高性能问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录一、认识MethodHandle1、简介2、使用方式3、与反射的区别二、示例1、基本使用2、(重要)

PyTorch高级特性与性能优化方式

《PyTorch高级特性与性能优化方式》:本文主要介绍PyTorch高级特性与性能优化方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、自动化机制1.自动微分机制2.动态计算图二、性能优化1.内存管理2.GPU加速3.多GPU训练三、分布式训练1.分布式数据