lucene 分布式索引方案

一、lucene介绍

Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。

二、Hadoop介绍

一个分布式系统基础架构,由Apache基金会开发。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力高速运算和存储。Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有着高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上。而且它提供高传输率(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求(requirements)这样可以流的形式访问(streaming access)文件系统中的数据。

三、测试环境

1、系统windows xp

2、jdk1.6

3、cgywin

4、hadoop0.20

5、lucene2.9.4

四、测试内容

1、第一种测试形式及结果

wps_clip_image-8670[3][1]

此种形式比较简单,测试成功。

2、第二种测试形式及结果

wps_clip_image-13115[3][1]

此种形式分布式抓取数据,最终合并成一个索引,上传到hadoop,执行搜索后合并成功

3、第三种测试形式及结果

wps_clip_image-12030[3][1]

此种形式比第二种形式减少了合并索引,这样搜索必须支持多索引目录联合查询,测试成功

4、第四种测试形式及结果

wps_clip_image-17875[3][1]

此种形式是直接将索引写入内存,从内存写入hadoop目录,执行联合搜索测试成功

5、第五种测试形式及结果

wps_clip_image-21988[3][1]

此种形式接入两套hadoop集群,把抓取数据与创建索引分开,测试成功

五、与solr比较

1、solr简介

Solr是一个高性能,采用Java5开发,基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。

文档通过Http利用XML 加到一个搜索集合中。查询该集合也是通过http收到一个XML/JSON响应来实现。它的主要特性包括:高效、灵活的缓存功能,垂直搜索功能,高亮显示搜索结果,通过索引复制来提高可用性,提供一套强大Data Schema来定义字段,类型和设置文本分析,提供基于Web的管理界面等。

wps_clip_image-3888[3][1]

Solr

wps_clip_image-12605[3][1]

Solr

2、solrCloud(集群)

SolrCloud是基于Solr和Zookeeper的分布式搜索方案,是正在开发中的Solr4.0的核心组件之一,它的主要思想是使用Zookeeper作为集群的配置信息中心。

它有几个特色功能:

1)集中式的配置信息

2)自动容错

3)近实时搜索

4)查询时自动负载均衡

wps_clip_image-503[3][1]

3、solr\lucene的优缺点

(1)优点

低成本、快速上手、开源社区发达,有问题基本上有现成的解决方法。
但是,也正因为如此,熟悉了solr、lucene并不能说一定可以应对任何搜索需求。因为实际场景中,有许多千奇百怪的需求、问题,往往需要面对的是用最小的改动、最方便的形式满足需求,而不是,是否满足以及多久满足的问题,要的是简单、可靠、可控、快速接入、快速处理故障。

最后汇聚成为“检索质量”,而这个标准是很难形成和取得相应口碑的。经验成为了搜索中的重要财富,而solr、lucene原理、源码只是一种最为基础和最为不可缺失的工具。理解了这些,是可以复制一个solr、lucene的,但是无法复制solr、lucene已经形成的开源经验、应用经验、讨论氛围等。

(2)缺点

短板越多,反应solr、lucene已经支持的场景非常多,提供服务的功能非常强大。所谓的短板,完全可以成为solr、lucene在生成环境中的应用特殊性所在、亮点所在。

1) http 请求做了cache,有时候会出现新数据不可见,cache滞后的问题。—cache优化下也不是问题

2) admin 后台页面,支持中文、复杂查询语法上,欠友好。—自己稍加扩展也不是问题

3) swap core的时候,单结点多core,并且core对应的索引比较大的时候,切换过程出现内存2倍化现象,甚至超时现象。—如果分前后排切换这些都不是问题了。

4) index build和index search往往在一起,导致全量过程,磁盘峰值3倍化。一份原来的、一份新建的、一份优化的时候。—-当然,build和search分离是可以解决这个问题的,也是常规做法。

5) build 和search在一起,也使得build和search的一些参数设置不能区别对待,尤其是build和search合体的时候,预留磁盘、内存等加速build,反而影响search。—-当然可以
build search分离搞定

6) 分布式查询,如果有merge,性能有些问题。—-当然可以将数据分区,避免merge

7) 得分因子是可以调整的,但是得分因子的增加、得分公式的扩展,无法直接从solr配置插入。—-但是,可以扩展lucene的代码或者参数spanquery,重新一个query,插入solr,这样工作量稍大.另外,社区提供了bm25、pagerank等排序batch,对lucene有所以了解后,就可以直接引用了。

8) solr分布式索引全量、增量控制粒度,尚不够友好。指定结点、任何时刻全量,指定条件下增量都不够顺利。尽管solr提供了自定义扩展实现方法。这些也不是很大问题。

9) solr build和search和在一起,数据和业务其实绑定在一起了,没有彻底隔离。使得在上100个core的时候,数据源管理维护变得非常消耗资源。直接引入hadoop或者其他nosql存储时目前最流行的用来隔离数据和业务耦合性了。开源的分布式lucene方案非常多.

10) ABTest 共享相同索引目录,而不同排序或者不同分词 solr不能直接支持

11) ABTest 独立索引目录,不同排序或者不同分词,solr也不能直接支持

12) 一个core对应多个子目录,查询既可以查指定子目录也可以全部子目录查,以及更新某个子目录索引或者全部子目录索引,solr也不能直接支持,而这些在大数据量的时候是需要支持这些功能的。

13)solr或者lucene目前不支持快速的“局部”更新。这里是指对document的某个字段的快速更新,目前是需要传入完整的document,然后add进去。如果document的不变字段来源多个源的话,IO、计算资源有些浪费,如果更新量不大还好。—当然可以对更新的单独开辟内存来处理,而更大的那个基本索引不去动他。

14)solr不支持第三方条件过滤。例如从倒排中过滤处理一批doc,而这些doc需要与外部源进行doc域值过滤。问题主要是第三方信息动态性太强,不利于直接写索引中去。

15)solr 在支持中文分词的时候,有很多第三方包可以引入,但需要扩展queryparse有时候,总体看有优势也有劣势。优势是引入方便,劣势是词库、算法体系和lucene的不完全兼容,扩展、完善不是那么容易。

16)在排序上,对与去重或者对应基于时间动态性上,还没有现成的支持。去重是指排序的前几条结果,可能某个域值完全相同了,或者某几个域值完全相同,导致看起来,靠前的结果带有一些关联字段的“聚集性”,对有些应用来说,并不是最好的。
在时间因素上动态性,也没有直接支持,也只能靠间接的按时间排序来实现。
这个问题其实不是lucene、solr要关注的吧,应该是应用的特殊性导致的吧。

17) solr、lucene输出的日志,尚没有一个通用的分析工具,包括高频词、查询query聚合性等。只能自行去解析。

18) 在支持推荐上,还不能将log信息直接关联起来,推荐也基本上靠离线计算好,导入倒排索引,查询再关联起来。

19) 当内存30个G 以上,单节点索引数据量比较大的时候,jvm环境下FGC和内存管理显得非常辣手。调优需要仔细的测试

20) lucene很少面向接口,solr很多面向接口,插件化、可扩展使得solr很灵活

21)对于垂直型的平台化搜索,支持N个不同应用、不同schema、不同数据源、不同更新频率、不同查询逻辑、不同访问请求量、不同性能指标要求、不同机器配置、垂直扩容、水平扩容,solr显得不够胜任,尽管solrcloud中已经有非常多的宝贵设计经验。

22)流控和数控,solr也不能直接支持。访问请求不支持定时和定量控制,索引垂直扩容(增加索引副本,支撑更多访问请求)、索引水平扩容(增加索引分区数,支撑更多数据量,平衡性能和空间压力)

23) solr自容错还不够强大。例如schema变更导致的不合理检测以及配置错误的回滚、solrconfig的一些参数不能动态获取,必须事先配置好。oom之后不能自动reload!请求量大的时候也不能抛弃一些请求。

24) 基于位操作的高级应用还不够灵活,例如boolean 存储和facet、byte[]存储和facet、group等,支撑仍然不够友好。

25) query parse基本没有预测功能,不能调整query顺序和自动收缩条件。当然一般情况下是不需要这么复杂的优化。

26)一些比较变态的查询需求不是特别高效。例如查询某个域不空。当然可以将空域采取默认值代替,查询默认值再过滤。

27)对于唯一值域,没有优化,导致唯一值域的term数据膨胀。最常见的就是更新时间、上传时间等,占了非常大的term比例。

28)multivalue 字段,实质是建立多个相同域名的字段,并不是一个域。对于域值很多内容的话,只好和在一起保存。同时,long int short float double 等数组不能直接作为一个类型保存,全部得转为字符存储。空间和效率有些低。

29)有些词出现的频率特别高,导致该词的倒排连非常长,solr、lucene也没有干涉。任务交给应用自己斟酌,实际上solr单节点对于命中超过100w的,并多字段排序的时候,cache失效时性能非常糟糕的。

30)solr\lucene 对千万级别应用非常擅长,亿级别应用需要慎重对待。

发表评论