文/曾彪
华中科技大学图书馆累积的各种元数据总量接近1亿条。学校结合S o l r开发了学术搜索系统,从而能够充分利用这些元数据。
华中科技大学图书馆在资源整合方面做了大量的元数据收集工作,累积的各种元数据总量接近1亿条,为了充分利用这些元数据,我们结合S o l r开发了学术搜索系统(当前在http://www.libsou.com 上运行)。
Solr是一款非常优秀的全文搜索引擎组件,对千万级别的数据搜索速度能达到毫秒级别,Solr在2010 年7 月发布了1.41版。
Solr可以在Tomcat、Jetty、Resin等平台下运行,学术搜索的运行环境为:Windows2008 R2 x64位、Solr 1.41版、Java 1.6 x64位、Tomcat 6.0.24 x64位(考虑到对32G内存的充分利用,在配置环境时选择了64位的运行环境)。
我们通过以下步骤配置S o l r的运行环境:
1.安装配置Tomcat和Java运行环境,并调整了Tomcat 的最大和最小的内存值。-Xmx30524M -Xms25524M,在Tomcat 中配置solr.home,设置为Java 的系统参数-Dsolr.solr.home=d:solr。
2.解压缩Solr,将Solr发布包中的examplesolr目录复制到其他目录(d:solr),修改$SOLR_HOME/conf/solrconfig.xml,找到dataDir设置:修改为索引存放的目录,默认为,修改为:
r.data.dir:./solr}修改为:
。
3.将apache-solr-1.4.1.war部署到Tomca t 之下,并且可以将这个w a r 复制到tomcatwebapps的目录下。
4.修改Tomcat的server.xml文件(防止出现乱码),设置URIEncoding为UTF-8: redirectPort="8443" URIEncoding="UTF-8" /> 增加tomcatconfCatalinalocalhostsolr.xml文件,其内容为: Solr 主要是通过schema. xml 和solrConfig.xml 这两个XML 文件来完成配置,solrconfig.xml文件包含了大部分的参数,用来配置Solr的缓存、索引路径、查询参数、查询相关的事件监听器、更新处理等,与Solr运行相关的参数都可以通过这个文件来配置。schema.xml相当于数据表配置文件,它定义了加入索引的数据的数据类型,主要包括types、fields和其他的一些缺省设置。该文件中配置的字段与索引字段的名称与属性一致,例: 在中文搜索中,中文分词的加入可以提高搜索的准确性。中文不同于西文,词汇之间没有明显的分界,但是计算机自然语言处理是按词汇来进行分析的,因此中文分词的效果好坏直接影响中文检索和自然语言处理的准确性。当前开源的分词组件有: 1.ICTCLAS3.0分词速度单机是996KB/s,分词精度为98.45%,API 不超过200KB,各种词典数据压缩后不到3M。ICTCLAS 全部采用C/C++编写,支持Linux、FreeBSD及Windows系列操作系统,支持C/C++、C#、Delphi、Java等主流的开发语言。 2.IKAnalyzer是一个开源的分词项目,它是基于Java 语言开发的轻量级的中文分词工具包。结合词典分词和文法分析算法的中文分词组件。最新版本IKAnalyzer3.2.3 ,独立于Lucene 项目,同时提供了对Lucene、Solr的默认优化实现。。 3.Paoding提供Lucene和Solr 接口,具有极高的效率和高扩展性, 引入隐喻,采用完全的面向对象的设计。 4.MMSeg 提供Lucene 和Solr 接口,MMSeg 算法实现中文分词器,并实现Lucene的 analyzer和Solr的TokenizerFactory。中文分词器可以在在Lucene 和Solr 中使用。MMSeg 算法有两种分词方法:Simple 和Complex,它们都是基于正向最大匹配。Complex 增加了4 个规则过滤。 5.imdict-chinese-analyzer:算法基于隐马尔科夫模型(Hidden Markov Model,H M M ) ,是中国科学院计算技术研究所的ictclas 中文分词程序的重新实现(基于Java),可以直接为Lucene搜索引擎提供简体中文分词支持。 Solr在建立索引进行搜索时都用到了中文分词组件,我们选择IKAna lyzer作为学术搜索的分词工具。 在设计好数据库和检索字段后,可以通过S o l r提供的导入功能,将我们需要进行搜索的数据导入到S o l r中,S o l r会生成索引文件。这种方式虽然方便,但是不灵活。在学术搜索的排序中,要将最相关的、最值得阅读的、最新的、引用频次高的学术文献排到最前面,而S o l r在建立索引的过程中对文献的评分不能有效地控制,我们选择了在L u c e n e的基础上开发索引程序,从而生成索引以供S o l r使用。 在完成上面的工作后,调用S o l r搜索就很容易了,通过h t t p发送指定的搜索参数,S o l r就能返回X M L或者j o s n的结果。 搜索语法 Solr查询的格式如下: http://localhost:8983/solr/select/?facet.limit=10&rows=10&start=0&facet=true&q=content:java&mlt.count=15&mlt=true&mlt.fl=title&mlt.mintf=1&hl.fl=title,content&facet.field=type,year&mlt.mindf=1&hl=true 以上参数表示:在content中查询关键词为java的记录,返回前面10条记录,并且按照type和year进行查询结果的分组。 Solr 常用的查询参数如下: q:查询字符串; fl:指定返回哪些字段内容,用逗号或空格分隔多个内容; start:返回第一条记录在完整找到结果中的偏移位置,从0开始,一般用于分页; rows:指定返回记录条数的上限,配合start来实现分页; sort:对指定字段的排序,格式是year desc, year asc,默认是相关性降序; fq(filter query): 过滤查询; qt(query type): 指定某个类型,用来处理查询请求,默认是standard; indent:返回的结果是否缩进,默认关闭,用indent=true|on 开启,一般调用json,php,phps,ruby输出才有必要用这个参数; version:查询语法的版本,建议不使用它,由服务器指定默认值。 分组 按照指定的字段分组检索是Solr的一项特性,目前有很多搜索引擎提供这项功能。在设计好分组字段后,建立索引时必须将需要分组的字段设置为Field.Index.NOT_ANALYZED。人们可以同时按照多个字段进行分组。在提交给Solr的参数中,facet.field用来确定需要分组的字段,facet.limit用来确定返回前分组数据的条数。 排序 学术搜索除了有海量的数据和高效的搜索引擎外,优秀的排序算法也非常重要,在互联网搜索引擎中,人们大多采用Pagerank来排序。Lucene中组合使用了信息检索的向量空间模型和布尔模型。下面是Lucene的评分公式: score(q,d) = coord·queNorm(q)… ∑(tf(t in d) ·idf(t)2t.getBoost() ·norm(t,d)) t inq其中: tf(t in d):词条t在文档d中出现的词频; idf( t ):词条t在文档中的倒排词频; boost(t.field in d):在索引过程中设置的字段参数; lengthNorm(t.field in d):字段的标准化值,表明在字段中存储了多少词条,这个数值是在索引过程中计算出来的,并且也存储在索引中; coord(q, d):协调因子,它的计算是基于文档d中所包含的所有可供查询的词条数量; queryNorm(q) :在给出每个查询条目的方差和后,计算某查询的标准化值。 学术搜索在设计排序时结合了3个方面的内容: 1.L u c e n e本身的评分机制,学术搜索综合时间、类型、引用次数、是否核心期刊、是否基金项目等因素,通过d o c.S e t B o o s t(f)来给记录评分。 2.在搜索时,对标题、关键词、文摘分别给不同的权重t i t l e^2 k e y w o r d^ c o n t e n t。 3.分析检索词的词性及分类属性,对应的分类文献给予较高的权重。 我们有多种方式来提高Solr搜索效率与并发数,比如用更快的C P U、采取S S D硬盘或者S A S 1 5 K r a i d 0 的方式能大幅提高硬盘的读取效率、使用大内存虚拟硬盘来存放索引文件。 我们除了从硬件方面改善Solr性能之外,还可以采用其他方式来改善其性能。 多级缓存策略 在建立索引完成之后,我们很难对索引结构作出较大改动,而缓存能大幅度提高搜索服务的性能,所以我们可以采用多级缓存的策略来提高Solr的并发性能和搜索性能。 Solr中有如下几种类型的缓存: 1.SolrCache缓存 Solr提供了两种SolrCache接口实现类:solr.search.LRUCache(LRU = 最近最少使用内存中)和solr.search.FastLRUCache(FastLRUCache在1.4版本中引入的),后者速度在普遍意义上要比LRUCache更快。LRUCache和FastLRUCache都使用了现成的Map来维护数据,不同点是如何来淘汰数据。 2.过滤器缓存(filterCache) filterCache存储了无序的文档编号列表(lucene document id集合)。filterCache主要用在查询过滤、查询结果分组、进行排序,在查询参数使用fq、facet的应用中,对filterCache的调优使得性能的改善效果明显。通过监控搜索服务器的缓存命中率来调整参数,从而获取更好的效果。 3.查询结果缓存(queryResultCache) queryResultCache是对查询结果的缓存(SolrIndexSearcher中的Cache缓存的都是document id set),这里的结果就是完全有序的结果。 4.对象缓存(documentCache) 在Lucene中,Documen是一个需要进行索引的“单元”,一个Document由多个字段组成,类似数据库中的一条记录。documentCache用来保存 5.自定义缓存(User/Generic Caches) Solr支持自定义Cache,只需要实现自定义的regenerator即可,下面是配置示例: warmCount="4096"regenerator="myrRege nerator"/>-也可以使用memcached来替代Solr提供的缓存方式,这样能获得分布式缓存支持。 分布式搜索与索引 当索引越来越大,单台服务器无法满足搜索需求时,可以采取分布式搜索与索引来提高搜索效率:将原来大的索引文件,分隔为多个小索引文件,分发到多台S o l r搜索服务器上面,客户端通过一次搜索多台服务器,S o l r将从多台服务器返回的结果合并,然后返回给客户端。分布式搜索可以大幅度提高S o l r的并发处理能力。 需要注意的是要增大容器http处理线程数来防止阻塞,分布式搜索会加大http的请求数目,如果http容器没有多余的线程处理请求,servlet容器就会阻塞刚来的请求,这种情况一直持续到正在处理的请求被处理完毕。 与分布式搜索相同,当需要索引的数据量非常大或者对数据的实时性要求比较高时,可以通过分布式索引来提供索引速度。在实施分布式索引中,索引的文档必须有一个唯一键,至于如何建立小索引,这点随用户的喜好而定。关于如何决定哪条记录放在哪个索引上,我们可以使用类似这样的公式:uniqueId.hashCode() % numServers。 监控性能 LucidGaze for Solr 是由 Lucid 开发的开源 Solr 监测工具,该工具提供了快照、存储、交互视图、比较各种Solr 性能指标等功能,用5个不同的监视器来搜集统计数据,具体如下: 1.分析统计数据:Analyzer、TokenFilter、TokenStream和Tokenizer相关数据,以及哪一个Analyzer被用来为特定域产生TokenStream。 2.文档统计数据:已建索引文档的总数,索引的各个域。 3.索引统计数据: IndexReader和IndexWriter的活动和行为,比如查看每个实例、跟踪每个相关方法的调用、查看缓存及内存使用情况和索引增加和提交的平均时间。 4.搜索统计数据:查询操作、搜索器性能和处理时间、方法调用统计以及对大多常用执行的查询。 5.存储统计数据: Lucene存储架构的目录实例(directory instance)。中文分词提高搜索准确性
调用Solr搜索
改进效率软硬兼施