Luence filter 缓存分析

来源:互联网 发布:香蕉免费网络电视 编辑:程序博客网 时间:2024/06/06 00:19

出处:http://ronxin999.blog.163.com/blog/static/4221792020121331529431/


luence 有两种缓存,分别是查询缓存和排序缓存,查询缓存就是通过filter来实现,排序缓存是用FieldCache来实现。
这里主要分析查询缓存Filter的实现。
先说下Filter实现缓存的机制,我们看下Filter类,源码如下:

public abstract class Filter implements java.io.Serializable {
   //所有的缓存Filter实现都将实现这个方法。返回的是DocIdSet
  public abstract DocIdSet getDocIdSet(IndexReader reader) throws IOException;

}

这里有必要讲下DocIdSet,DocIdSet是一个存储document ID 的集合,提供了一个迭代器iterator,可以随机访问DocIdSet里的ID。

Filter有了要搜索文档ID 的集合DocIdSet,我们在搜索文档时,根据搜索条件生成Score,score也是一个DocIdSetIterator实例,可以迭代这个score的文档ID,有了这两个文档ID的集合,就可以比较了。只有即存在在Filter生成DocIdSet也存在根据条件查找到的score中。这个ID才会被collector收集。这样如果当前查找到的文档ID不在Filter里面,则相当于被过滤掉了。但是这样存在一个问题,由于Filter返回的DocIdSet 没有被缓存,即每次查找都要对reader的文档进行检索一次。而正常搜索的时候也检索一次,相当于做了两次检索。在高并发下性能肯定不靠谱。那怎么解决这样问题呢。luence 已经为我们提供了CachingWrapperFilter。CachingWrapperFilter也是继承Filter。它缓存了DocIdSet 的。

下面分析CachingWrapperFilter的实现原理。

CachingWrapperFilter有一个实例变量Filter。FilterCache<DocIdSet> cache这两个主要变量。CachingWrapperFilter的逻辑为首先从cache中根据当前reader去取DocIdSet,如果没有,则通过实例变量filter为当前reader生成一个DocIdSet,如果不为空,则添加到实例变量cache中。这样就缓存了DocIdSet,这里cache的实现是CachingWrapperFilter的一个内部类FilterCache是实现的。FilterCache有一个  transient Map<Object,T> cache;实例变量。实际的DocIdSet都是存在这个transient 的MAP中,
这个Map为什么是transient 类型的呢,FilterCache是可以序列化的,如果我们把缓存网络传输或者保存的磁盘,那干这个缓存DocIdSet的Map cache肯定是序列化不了的,就要重新初始化。


原创粉丝点击