Lucene的一种分布式检索方案的研究报告
chester60
2008-07-10
这几天实现了个Lucene分布式检索的模块,采用的分布式方案是将数据分块,分别生成N个索引文件,放到N个节点上运行。检索时,对每一个节点发出查询请求,将N个节点返回的结果归并,然后生成一个新的结果。如果没看明白,可以看看我的帖子 http://www.iteye.com/topic/212046 ,这个方案同帖子中的思想是一致的。
用这样的方案,遇到的问题是归并过后的结果,同没有归并结果是有一定区别的。在实现这个方案前我也分析过,Lucene使用TF/IDF算法来计算相关度,所以会产生这样的问题: 100万条数据,分别索引成2个50万数据的索引文件A,B和100万条数据的索引文件C。这样,A、B、C3个文件的IDF都不相同,所以搜索出来的结果将会不同。但是如果是海量数据,IDF值从统计学角度上来说应该是非常相似的,所以搜索出的结果大体上来说是一样的。 今天专门做了一个实验,取100万条数据做测试,每个节点50万数据,进行几个关键词的检索,同包含100万条同样数据的索引文件比较,取前100项统计有多少项不同。数据是类似www.net114.com这样的类型的数据,下面是结果(同位置是指在100条数据中,位置相同的数据。非交集指那些分布式检索返回的结果,不在集中式检索的结果之中的数据): 关键字:公司 同位置:0条 非交集:12条 “公司”这个关键字返回的结果非常多,基本返回整个数据集中的数据。这个测试针对的是目的非常模糊的查询。 关键字:永恒 公司 同位置:4条 非交集:0条 返回的结果中等,针对有一定目的的查询。 关键字:中国石油 同位置:1条 非交集:0条 针对比较精确的查询,返回的结果最前面基本都是中国石油开头的数据。 可以看到,同之前的分析结果类似,进行这样的分布式检索,基本上同集中式检索获取到的数据是相同的,但是排序不同。我已经截图下来了,但是这里貌似没法发……总体上来说,我这些精度损失在我的项目中还是可以接受的,对“公司”这种返回结果很多,搜索目的非常模糊的检索,头10项相差得比较大。但是这种搜索本身要求的精度就不是很高。而对于比较精确的搜索,头10项相差得很小,要是有兴趣的话我找个地方上传图片给大家看看。 至于性能,经过100万数据的测试,大体上能提升至少30%的检索时间,偶尔有超过单个节点查询的情况,一般是由于在网络传输层中有一些延时造成的,有的也是我系统的BUG……。进行分布式的好处在于能够处理一些无法分割的数据,保证在海量数据下也能保持足够的响应速度。 最近准备学习Java(我是用.Net的),不知道大家对这个分布式检索的方案有没有兴趣,如果有兴趣的话我就用Java实现它,希望到时候大家多多指点~~~ |
|
titanfoot
2008-07-11
玩具而已!
|
|
amigobot
2008-07-15
检索的精度会取决于文档是否是均等的分布于不同的index里面, 如果是一个1w, 另一个100w, 结果就会差很多了。
可以用remotesearcher, 如果节点不再用一个JVM, 如果是同一个里面, 用multisercher就行了, 里面回计算全局TF/IDF。 remotesearcher基本不能用于企业级应用。 |
|
dogstar
2008-07-16
个人认为->这种分布式索引的方法是处理大索引的好办法.我们公司目前就是这么处理的.比如要索引一张表,那么根据id进行hash到不同的机器上,做索引,然后分别查询后归并.
|
|
chester60
2008-07-16
amigobot 写道 检索的精度会取决于文档是否是均等的分布于不同的index里面, 如果是一个1w, 另一个100w, 结果就会差很多了。
可以用remotesearcher, 如果节点不再用一个JVM, 如果是同一个里面, 用multisercher就行了, 里面回计算全局TF/IDF。 remotesearcher基本不能用于企业级应用。 精度问题,其实有办法解决,从我的应用来看,TF/IDF应该自己作为一个文件保存。查询时去读取保存有所有数据的TF/IDF的表,就能保证每个节点的评分都是一致的。而且,还可以做出一些扩展的东西,比如我要搜索某个行业中的数据,可以专门做一个TF/IDF表,对该行业中的某些关键字加权,这样搜出来的结果会更加符合。但是这样就要修改Lucene的源码了,这个目前我还没做,因为感觉现在这样搜出来的结果也不错。 不过为什么说remotesearcher基本不能用于企业级应用呢?我也没有在大规模的集群上测试过,目前几台计算机来看效果还可以。方便的话不妨说下,谢谢。 |
|
grantbb
2008-07-16
dogstar 写道 个人认为->这种分布式索引的方法是处理大索引的好办法.我们公司目前就是这么处理的.比如要索引一张表,那么根据id进行hash到不同的机器上,做索引,然后分别查询后归并.
hash到不同的机器上,那么如果要加机器的时候,就要完全重新索引了。 |
|
amigobot
2008-07-20
chester60 写道 amigobot 写道 检索的精度会取决于文档是否是均等的分布于不同的index里面, 如果是一个1w, 另一个100w, 结果就会差很多了。
可以用remotesearcher, 如果节点不再用一个JVM, 如果是同一个里面, 用multisercher就行了, 里面回计算全局TF/IDF。 remotesearcher基本不能用于企业级应用。 精度问题,其实有办法解决,从我的应用来看,TF/IDF应该自己作为一个文件保存。查询时去读取保存有所有数据的TF/IDF的表,就能保证每个节点的评分都是一致的。而且,还可以做出一些扩展的东西,比如我要搜索某个行业中的数据,可以专门做一个TF/IDF表,对该行业中的某些关键字加权,这样搜出来的结果会更加符合。但是这样就要修改Lucene的源码了,这个目前我还没做,因为感觉现在这样搜出来的结果也不错。 不过为什么说remotesearcher基本不能用于企业级应用呢?我也没有在大规模的集群上测试过,目前几台计算机来看效果还可以。方便的话不妨说下,谢谢。 看过remotesearcher的代码,很简单的基于RMI的实现。 几个机器的简单应用应该没问题, 但在几十台机器上的话, 扩展性, 效率, 配置性都有很大的局限性。 我在去年用JMS做了一个demo, 后来也考虑过用Javaspace, 后来用了自己个的协议。 |
|
chester60
2008-07-21
amigobot 写道 看过remotesearcher的代码,很简单的基于RMI的实现。 几个机器的简单应用应该没问题, 但在几十台机器上的话, 扩展性, 效率, 配置性都有很大的局限性。
我在去年用JMS做了一个demo, 后来也考虑过用Javaspace, 后来用了自己个的协议。 噢,我是担心这样的查询方式有什么硬伤,导致无法应用于大型的系统中。如果是这个原因还是可以解决的,我的项目中也是用自己的通信框架和协议作为底层的通信方式。 |
相关讨论
相关资源推荐
- java源码包---java 源码 大量 实例
- java程序读取共享文件_在Java程序中读写windows共享文件夹
- 超详细:Java 读取 Windows 共享文件夹中的文件,并下载到本地电脑中
- 在java程序中访问windows有用户名和密码保护的共享目录
- java 获取系统用户名和密码_java 如何实现开机自动运行程序 --如何获得系统用户名 怎么获得当前系统在哪个盘上...
- java 获取系统用户名和密码_Java – 从配置文件加密/解密用户名和密码
- java读取桌面文件_用java读取桌面上的文档"abc.txt",程序怎么写?
- java如何给用户密码_如何使用提供的用户名和密码来读取Java中的文件
- Windows搭建FTP服务器,JAVA实现读写功能
- 【Windows共享文件】Java读取Windows环境共享文件夹