lucene中的filter其实并不起眼,大家对其对性能的影响也不是很关注,但实际上filter是除了单纯搜索以外,其他搜索附加功能的必选组件,其性能很大程度上会直接影响搜索的性能,之前我一直认为filter的性能比query高,但事实说明并不完全如此(这里所说的负荷是指io消耗并不是cpu),实际上在lucene中充满着各种io流,也就是说很多东西都无法从根本上保存,这也给缓存带来了很大难度(这个问题看似简单,但是在超复杂的组合查询下,缓存可能会几乎无用,原因就是key怎么把握)
首先来看看filter的接口定义:
public abstract class Filter implements java.io.Serializable {
public abstract BitSet bits(IndexReader reader) throws IOException;
}
简单明了从reader中知道哪些记录是可以读出来的用true false放在bitsets中,然后再用这去和总集合做and操作得到剩余记录数,然后再通过query查询.原理知道了,下面来考虑下它的缓存:
缓存filter本身,由于他是序列化对象,那么已经具备了缓存的条件,但是这是一个错误,因为你缓存了这个类,而当你把参数reader拿出来依然会和机器产生io,因此这是极其不恰当的方法,应该缓存它的结果.
在lucene中有这么几个和filter有关的类:
CachingWrapperFilter
CachingSpanFilter
RemoteCachingWrapperFilter
FilterManager
其实我想质疑前两个,为什么呢,请看他的源码:
protected transient Map cache;
他放置缓存的map居然是transient的,这意味着即使你把它实例在static中这个变量依然会每次要new的,这样的缓存有意义吗?我看不出他怎么缓存的
/**
* A transient Filter cache. To cache Filters even when using
{@link org.apache.lucene.search.RemoteSearchable} use
*
{@link org.apache.lucene.search.RemoteCachingWrapperFilter} instead.
*/
上面这句注释总算明了了,呵呵.
那么其实RemoteCachingWrapperFilter才是真正的cache类,他的实现借助于filterManager,这个类是我们平时能理解的那种cache结构
public BitSet bits(IndexReader reader) throws IOException {
Filter cachedFilter = FilterManager.getInstance().getFilter(filter);
return cachedFilter.bits(reader);
}
但这个还不够,第一他的性能我心里没谱,遇到上万的访问怎么办?所以还是要用第三方的缓存,我使用的是memcached,这个东西不介绍了,只有一个问题,就是必须要求对象是可序列化的,这个不难理解,要想网络传输只能治么搞.
我的缓存策略:把最细胞的filter用memached缓存他的结果集,而他的组合fliter用自带的filtermanager管理就好了.filter怎么合在一起上次写过一个,看这里:
http://www.edwardpro.com/post/572/而我这样的道理也是基于filtermanager的key是reader的hashcode,因此他是对应不同的索引的.那么肯定有朋友问怎么刷新呢?太简单了啊,你的key只要有reader或者search的hashcode就可以了,你一旦更新的源hashcode就变化了.(如果你的search和reader的hash不是固定的那么你肯定承受不了100以上的并行访问,io会高得惊人.)
另外一个技巧,是关于rangefilter的,这个东西不错,但是有一点难,在哪里呢?因为他的查询似乎效率不高,因此一定要缓存! 但是key呢?比如我常用的key是timestamp,但是实际中就会发现如果用毫秒的timestamp那么key几乎无用,因为很少相同的,经过改进,我把时间可以用月做单位,查询也是如此,如果你的要求高我觉得做到天就ok了,如果你数据再多用到小时肯定也够了吧,这样filter的缓存会带来极大的性能提升.
那么实际效果呢,在原来使用时候2台集群机(nginx作为前端代理,后部用resin作为应用服务器)io平均1.xx 现在加了缓存之后常年保持在0.2左右!性能得到了几乎5~6倍的提升.而一般查询一个十万当量的+ 5个关键字 + 3个filter 时间大约是<10ms 非命中时大约是 70~80ms 这个速度如果得到同样结果的数据库至少要放大1000倍的时间.
由于我memcached没有做集群是独立的(事实也应该如此,因为你两台机器的reader的hashcode肯定是不一样的,放一起也是这样的结果,这样也没有不好,当一台机器出现问题或者需要更新代码可以用时间差来保证负荷平稳过渡,不像以前一台机器每次重启都是有点怕怕的,只能找空闲时间才敢这么做.
最后要讲的query,其实前面我说了半天没有提到query,query的缓存呢? 其实在lucene中有这么个类:
QueryFilter
这个类简单说就是把query变成filter,那干什么呢?很简单啊,这样任何查询都会变成filter的,所以所有的缓存都是filter!那么从缓存中取出来的filterquery怎么用?
MatchAllDocsQuery matchAll = new MatchAllDocsQuery();
result = isearch.search(matchAll, filter, sort);
filter是用我的合成filter组合的,这样消耗就更低了,当然不建议无限制增加系统负荷,因为那样就几乎无法重启了,呵呵.好了基本说到这里,其实最后我想说我的核心思想: 任何query都是filter,lucene就是filter查询,事实是如此的,当然这点可能还可以讨论下,因为我用filter比较依赖.
大家有什么其他方案也可以讨论和交流一下,呵呵.
相关推荐
2. **配置与初始化**:根据项目需求,配置分词器的参数,如自定义词典、分词模式等,然后在Lucene的Analyzer中实例化该分词器。 3. **索引建立**:在创建索引时,使用配置好的分词器对中文文本进行分词,生成分词后...
其中,Filter过滤器是Lucene中的一个重要组件,用于对索引进行精炼筛选,以满足特定的查询需求。本文将深入探讨Lucene5中的Filter机制,以及其在实际应用中的价值。 首先,我们来理解一下什么是Filter。在Lucene中...
来自“猎图网 www.richmap.cn”基于IKAnalyzer分词算法的准商业化Lucene中文分词器。 1. 正向全切分算法,42万汉字字符/每秒的处理能力(IBM ThinkPad 酷睿I 1.6G 1G内存 WinXP) 2. 对数量词、地名、路名的...
在这个项目中,我们看到开发者利用Lucene结合jdbcTemplate来封装API,并引入缓存机制,以实现索引的精确刷新。这是一项高级的技术实践,旨在提高系统的响应速度和数据一致性。 首先,让我们详细了解一下Lucene。...
在Lucene.NET中,为了支持中文分词,通常需要结合第三方分词器,如IK Analyzer、HanLP、jieba.NET等。这些分词器具备丰富的词汇库和优秀的分词算法,能有效地对中文文本进行拆分。 - **IK Analyzer**:是一个开源的...
为了高效地处理和检索存储的词项(term),Lucene使用了FST(有限状态转换器,Finite State Transducer)这一核心算法构建内存索引。FST算法不仅可以用于快速检索term信息存储的位置,而且还支持判断一个term是否...
lucene3.0 中文分词器, 庖丁解牛
**Lucene索引器实例详解** Lucene是一个高性能、全文本搜索库,由Apache软件基金会开发,被广泛应用于各种搜索引擎的构建。它提供了一个高级的、灵活的、可扩展的接口,使得开发者能够轻松地在应用程序中实现全文...
《深入剖析:Lucene3与庖丁解牛中文分词器》 在信息技术飞速发展的今天,全文检索和...在实际操作中,结合标签“lucene 中文分词器 庖丁解牛 全文索引”,我们可以深入学习和实践,不断优化分词效果,提高用户体验。
在开始之前,确保已安装Java开发环境,并在项目中引入Lucene和IK分词器的相关依赖。对于Lucene 3.5,可能需要导入如下的Maven依赖: ```xml <groupId>org.apache.lucene <artifactId>lucene-core <version>...
通过这个压缩包,我们可以学习如何在C#环境中配置和使用Lucene进行中文分词,包括如何创建索引、查询处理、优化分词器的性能等。此外,通过阅读和分析源代码,还可以深入理解Lucene的工作原理,这对于提升自己的NLP...
在信息技术领域,中文分词是文本处理的一个关键步骤,尤其是在搜索引擎和自然语言处理应用中。Lucene是一个高性能、全文检索库,而“lucene中文分词工具包”则为Lucene提供了一个专门针对中文分词的解决方案。这个...
以《lucene-2.0.CHM》为例,这是一个Lucene 2.0版本的帮助文档,我们可以用这些工具对文档中的中文文本进行分词,观察不同分词器的效果,并根据结果调整分词策略。 七、总结 理解并熟练掌握Lucene中的中文分词技术...
在Lucene中,分词器通常与索引构建过程相结合,通过预处理和并行化处理来减少在线查询时的负担。 总的来说,支持Lucene的词典机械中文分词方法结合了反向分词策略和特定的数字、英文处理机制,能够有效地处理中文...
lucene 3.0 API中文帮助,学习的人懂得的
1. **Analyzer**: 分析器是Lucene中的核心组件之一,负责将输入的文本分解成可搜索的词项(tokens)。在3.0版本中,Lucene提供了多种预定义的Analyzer,如StandardAnalyzer,它们可以处理不同语言的文本。 2. **...
5. **内存缓存与过滤器**:Lucene提供`Filter`类来处理如文档过滤、高亮显示等功能。同时,`BitSet`类用于在内存中高效地存储和操作文档集。 6. **倒排索引的优化**:在`MergePolicy`和`MergeScheduler`中,你可以...
《中文分词及其在基于Lucene的全文检索中的应用》这篇论文主要探讨了中文分词在全文检索系统,特别是基于Lucene平台的应用。全文检索技术是现代信息检索领域的重要组成部分,而Lucene作为一款开源的全文检索引擎框架...
**Lucene索引管理器(基于Luke修改而来)** Lucene是Apache软件基金会的一个开源全文检索库,它提供了强大的文本搜索功能。而Luke是Lucene的可视化工具,它允许开发者查看和操作Lucene索引,包括文档内容、字段、分词...
赠送jar包:lucene-core-7.2.1.jar; 赠送原API文档:lucene-core-7.2.1-javadoc.jar; 赠送源代码:lucene-core-7.2.1-sources.jar; 赠送Maven依赖信息文件:lucene-core-7.2.1.pom; 包含翻译后的API文档:lucene...