




下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、new web life lucene 的缓存机制分析lucene 的缓存可分为两类:filter cache 和 field cache。filter cache的实现类为CachingWrapperFilter ,用来缓存其他 Filter 的查询结果。field cache的实现类是FieldCache,缓存用于排 序的 field 的值。简单来说, filter Cache 用于查询缓存, field cache用于排序。这两种缓存的生存周期都是在一个 IndexReader 实例内,因此提高 Lucene 查询性能的关键在于 如何维护和使用同一个lndexReader(即IndexS
2、earcher)。1、Filter Cache 从严格意义上来说, lucene 没有查询类似数据库 服务器的数据高速缓存。lucene的Filter缓存实现类是 CachingWrapperFilter,它缓存了查出来的bits。另夕卜 lucene还提供了 FilterManager ,一个单例对象,用来缓存 Filter 本 身。下面是 CachingWrapperFilter 的具体实现: public class CachingWrapperFilter extends Filter protected Filter filter;protected transient Map ca
3、che;/ 这是作为缓存使用的 mappublic CachingWrapperFilter(Filter filter) this.filter = filter;public BitSet bits(IndexReader reader) throws IOException if (cache = null) cache = newWeakHashMap();/ 采用 WeakHashMap 实现,由 JVM 回收内 存synchronized (cache) / check cacheBitSet cached = (BitSet) cache.get(reader);/key 为 I
4、ndexReader,value 为 BitSet,所以该缓存生存周期在一个 IndexReader 内 if (cached != null) return cached;/ 若没有找到缓存,则重新读取 final BitSet bits = filter.bits(reader);synchronized (cache) / update cachecache.put(reader, bits);return bits; 在 FilterManager 里, 采用 Filter.hashCode() 作为 key 的,所以使用的时候应该在自 定义的Filter类中重载hashCode()方
5、法。例子:Filter filter=FilterManager.getInstance().getFilter(new CachingWrapperFilter(new MyFilter(); 如果该 filter 已经存 在,在 FilterManager 返回该 Filter 的缓存(带有 bit 缓存), 否则返回本身(不带 bit 缓存的)。 FilterManager 里有个定时 线程,会定期清理缓存,以防造成内存溢出错误。2、field缓存field缓存是用来排序用的。lucene会将需要排序的字段 都读到内存来进行排序,所占内存大小和文档数目相关。经 常有人用lucene做排序
6、出现内存溢出的问题,一般是因为每次查询都启动新的searcher实例进行查询,当并发大的时候, 造成多个Searcher实例同时装载排序字段,引起内存溢出。 Field 缓存的实现类是 FieldCacheImpl ,下面我们看看排序时 怎么用到Field缓存的:在IndexSearcher类里的方法,有关 排序的查询都回调用到此方法: public TopFieldDocs search(Weight weight, Filter filter, final int nDocs,Sort sort)throws IOException TopFieldDocCollector collect
7、or =new TopFieldDocCollector(reader, sort, nDocs);/ 排序操作由TopFieldDocCollector 实现 search(weight, filter, collector);/ 开 始查询 ,查询结果回调 Collector.collect() 方法时实现排序 return (TopFieldDocs)collector.topDocs();/ 返回 TopFieldDocs 对象,这个对象和 TopDocs 的差异在于 TopFieldDocs 里包含 排序字段的信息,包括字段名和字段值。其中 TopFieldDocs 中 ScoreD
8、oc 的实例是 FieldDoc 下面看看 TopFieldDocCollector.collect() 是怎么实现的: public void collect(int doc, float score) if (score 0.0f) totalHits+;if (reusableFD = null)reusableFD = new FieldDoc(doc, score);else reusableFD.score = score;reusableFD.doc = doc;reusableFD = (FieldDoc) hq.insertWithOverflow(reusableFD);/
9、hq 是 FieldSortedHitQueue 对象,一个 PriorityQueue 的子类, insertWithOverflow() 实现一个固定大小的排序队列,排序靠 后的对象被挤出队列 FieldSortedHitQueue 是通过重载 lessThan()方法来实现排序功能的:*/protected booleanlessThan (final Object a, final Object b) final ScoreDoc docA = (ScoreDoc) a;final ScoreDoc docB = (ScoreDoc) b;/ run comparatorsfinal
10、int n = comparators.length;int c = 0;for (int i=0; i docB.doc;return c 0;comparators 实在 FieldSortedHitQueue 的构造函数里创建的: public FieldSortedHitQueue (IndexReader reader, SortField fields, int size)throws IOException final int n = fields.length;comparators = new ScoreDocComparatorn;this.fields = new Sor
11、tFieldn;for (int i=0; in; +i) String fieldname = fieldsi.getField();comparatorsi = getCachedComparator (reader, fieldname, fieldsi.getType(), fieldsi.getLocale(), fieldsi.getFactory();/ 调用 getCachedComparator 方法获得缓 存的 comparators,comparator 是 ScoreDocComparator 的实例 if (comparatorsi.sortType() = Sort
12、Field.STRING) this.fieldsi = new SortField (fieldname, fieldsi.getLocale(), fieldsi.getReverse(); else this.fieldsi = new SortField (fieldname, comparatorsi.sortType(), fieldsi.getReverse();initialize (size); 下面看看 getCachedComparator ()的实现: static final FieldCacheImpl.Cache Comparators = new FieldCa
13、cheImpl.Cache() 。 static ScoreDocComparator getCachedComparator (IndexReader reader, String field, int type,Locale locale, SortComparatorSource factory)throws IOException / 以下两种不需要读取字段 if (type = SortField.DOC) return ScoreDocComparator.INDEXORDER;/ 按索引顺序排序 if (type = SortField.SCORE) return ScoreDo
14、cComparator.RELEV ANCE;/ 按相关度排序 FieldCacheImpl.Entry entry = (factory != null) new FieldCacheImpl.Entry (field, factory): new FieldCacheImpl.Entry (field, type, locale);/ 其他类型的排序需 要读取字段到缓存中 return (ScoreDocComparator)Comparators.get(reader, entry);/Comparators 是一个 FieldCache 的实例 呵呵,好多代 码阿,幸好马上就到终点了。
15、Comparators.get()方法根据排序字段类型的不同, 返回 ScoreDocComparator 的不同实现, 下 面我们看看 String 类型的实现,就可以知道什么时候调用 fieldCache 了: static ScoreDocComparator comparatorstring (final IndexReader reader, final String fieldname)throws IOException final String field = ern();/ 下面代码 读取缓存, 得到字段值和文档 id 的对应关系, 如果缓存不存 在
16、,则读取索引文件。缓存的生命周期是和 IndexReader 一 样,所以不同查询使用同一个Searcher,可以保证排序缓存只有一个,不会出现内存溢出的问题 finalFieldCache.StringIndex index =FieldCache.DEFAULT.getStringIndex (reader, field);return new ScoreDocComparator () public final int compare (final ScoreDoc i, final ScoreDoc j) final int fi = index.orderi.doc;/index.order 的值是按自定义字段的排序, 数组的索引是 lucene docid ;可以看看 getStringIndex 的具体 实现来看看这些值是怎么读进来的,这里就不详细说明了 final int fj = index.orde
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 采购合同模板:乳胶漆
- 股权投资协议课件
- 2016疟疾培训课件
- 资阳环境科技职业学院《液压与气压传动1》2023-2024学年第二学期期末试卷
- 湖北省稳派教育2024-2025学年高三下学期第二次诊断性考试生物试题含解析
- 人教PEP版英语五年级下册教学课件Unit 5 Part A 第二课时
- 内蒙古经贸外语职业学院《营销效果评估与分析》2023-2024学年第二学期期末试卷
- 湖南冶金职业技术学院《软件学基础》2023-2024学年第二学期期末试卷
- 安阳幼儿师范高等专科学校《文艺学学科前沿》2023-2024学年第二学期期末试卷
- 中央财经大学《食品加工与制造》2023-2024学年第二学期期末试卷
- 2024年韶关学院辅导员考试真题
- 物理-北京市朝阳区2025年高三年级第二学期质量检测一(朝阳一模)试题和答案
- 小学生金融知识进校园
- 【课件】高二下学期《清明祭英烈 共筑中华魂》主题班会课件
- 2024年宁夏电力投资集团招聘笔试真题
- 飞利浦超声基础培训
- 大学生创新创业演讲稿
- 医院物业保洁保安投标服务方案(技术方案)
- 陶瓷行业安全生产培训
- 学校感恩教育课件
- 新兴技术交流及应用方案推进工作指引
评论
0/150
提交评论