设为首页 收藏本站
查看: 914|回复: 0

[经验分享] Solr缓存介绍

[复制链接]
累计签到:2 天
连续签到:1 天
发表于 2016-12-15 07:30:43 | 显示全部楼层 |阅读模式
  转自:http://www.blogjava.net/conans/articles/380684.html
  本文将介绍Solr查询中涉及到的Cache使用及相关的实现。Solr查询的核心类就是SolrIndexSearcher,
  每个core通常在 同一时刻只由当前的SolrIndexSearcher供上层的handler使用
  (当切换SolrIndexSearcher时可能会有两个同时提供服务),而Solr的各种Cache是依附于SolrIndexSearcher的,SolrIndexSearcher在则Cache 生,SolrIndexSearcher亡则Cache被清空close掉。
  Solr中的应用Cache有filterCache、 queryResultCache、documentCache等,这些Cache都是SolrCache的实现类,
  并且是 SolrIndexSearcher的成员变量,各自有着不同的逻辑和使命,下面分别予以介绍和分析。

1、SolrCache接口实现类
  Solr提供了两种SolrCache接口实现类:solr.search.LRUCache和solr.search.FastLRUCache。
  FastLRUCache是1.4版本中引入的,其速度在普遍意义上要比LRUCache更fast些。

1.1、solr.search.LRUCache

LRUCache可配置参数如下:
  1)size:cache中可保存的最大的项数,默认是1024
2)initialSize:cache初始化时的大小,默认是1024。
3)autowarmCount:
当切换SolrIndexSearcher时,可以对新生成的SolrIndexSearcher做autowarm(预热)处理。
autowarmCount表示从旧的SolrIndexSearcher中取多少项来在新的SolrIndexSearcher中被重新生成,
  如何重新生成由CacheRegenerator实现。在当前的1.4版本的Solr中,这个autowarmCount只能取预热的项数,
  将来的4.0版本可以指定为已有cache项数的百分比,以便能更好的平衡autowarm的开销及效果。
  如果不指定该参数,则表示不做autowarm处理。实现上,LRUCache直接使用LinkedHashMap来缓存数据,
  由initialSize来限定cache的大小,淘汰策略也是使用LinkedHashMap的内置的LRU方式,

读写操作都是对map的全局锁,所以并发性效果方面稍差。
1.2、solr.search.FastLRUCache

在配置方面,FastLRUCache除了需要LRUCache的参数,还可有选择性的指定下面的参数:
  1)minSize:当cache达到它的最大数,淘汰策略使其降到minSize大小,默认是0.9*size。
2)acceptableSize:当淘汰数据时,期望能降到minSize,但可能会做不到,则可勉为其难的降到acceptableSize,
  默认是0.95*size。
  3)cleanupThread:相比LRUCache是在put操作中同步进行淘汰工作,FastLRUCache可选择由独立的线程来做,
  也就是配置cleanupThread的时候。当cache大小很大时,每一次的淘汰数据就可能会花费较长时间,
  这对于提供查询请求的线程来说就不太合适,由独立的后台线程来做就很有必要。实现上,
  FastLRUCache内部使用了ConcurrentLRUCache来缓存数据,它是个加了LRU淘汰策略的ConcurrentHashMap,
  所以其并发性要好很多,这也是多数Java版Cache的极典型实现。

2、filterCache

filterCache存储了无序的lucene document id集合,该cache有3种用途:
  1)filterCache
存储了filter queries(“fq”参数)得到的document id集合结果。Solr中的query参数有两种,即q和fq。如果fq存在,
  Solr是先查询fq(因为fq可以多个,所以多个fq查询是个取结果交集 的过程),之后将fq结果和q结果取并。
  在这一过程中,filterCache就是key为单个fq(类型为Query),value为documentid集合(类型为DocSet)的cache。
  对于fq为range query来说,filterCache表现出其有价值的一面。
2)filterCache
还可用于facet查询(http://wiki.apache.org/solr/SolrFacetingOverview),facet查询中各
facet的计数是通过对满足query条件的document
id集合(可涉及到filterCache)的处理得到的。因为统计各facet计数可能会涉及到所有的doc
id,所以filterCache的大小需要能容下索引的文档数。
3)如果solfconfig.xml中配置了<useFilterForSortedQuery/>,
  那么如果查询有filter(此filter是一需要过滤的DocSet,而不是fq,我未见得它有什么用),

则使用filterCache。
  对于是否使用filterCache及如何配置filterCache大小,需要根据应用特点、统计、效果、经验等各方面来评估。
  对于使用fq、facet的应用,对filterCache的调优是很有必要的。
  4)客户端使用
  使用filterQuery之后的查询代码:

SolrQuery query = new SolrQuery();
query.addFilterQuery("status:0 AND biz_type:1 AND class_id:1");  
query.setQuery("xxx:123");  
QueryResponse response = qyeryServer.query(query);  
 


  经过测试这样优化之后,查询的RT会明显减小,QPS会有明显提升。
  使用filterquery过程中需要注意点:
  ●不能在filterQuery 上重复出现query中的查询参数,如果上面的filterquery调用方法如下所示:


  • query.addFilterQuery("status:0 AND biz_type:1 AND class_id:1 AND xxx:123");  
  • query.setQuery("xxx:123");  

  如上,条件xxx:123 在filterQuery和query上都出现了,这样的写法非但起不到查询优化的目的,而且还会增加查询的性能开销。
  ●尽量减少调用addFilterQuery方法的次数

query.addFilterQuery("status:0 ");  
query.addFilterQuery("biz_type:1 ");  
query.addFilterQuery("class_id:1 ");  
query.setQuery("xxx:123");  
  如上,将status:0 AND biz_type:1 AND class_id:1 这个组合查询条件,分三次调用filterQuery方法来完成,这样的调用方法虽然是正确的,并且能起到性能优化的效果,优化性能没有调用一次addFilterQuery方法来得高,原因是多调用了两次addFilterQuery,就意味着最后需要多进行两次结果集的求交运算,虽然结果集求交运算速度很快,但毕竟是有性能损耗的。
  不过从内存开销的角度来说,调用三次addfilterQuery方法这样可以有效降低内存的使用量,这个是肯定的。所以在是否调用多次addFilterQuery方法的原则是,在内存开销允许的前提下,将量将所有filterQuery条件,通过调用有限次数的addFilterQuery方法来完成。



3、queryResultCache

顾名思义,queryResultCache是对查询结果的缓存(SolrIndexSearcher中的cache缓存的都是document id set),
这个结果就是针对查询条件的完全有序的结果。 
因为查询参数是有start和rows的,所以某个QueryResultKey可能命中了cache,但start和rows却不在cache的
document id set范围内。当然,document id
set是越大命中的概率越大,但这也会很浪费内存,这就需要个参数:queryResultWindowSize来指定document id set的大小。

<queryResultWindowSize>50</queryResultWindowSize>

相比filterCache来说,queryResultCache内存使用上要更少一些,但它的效果如何就很难说。

就索引数据来说,通常我们只是在索引上存储应用主键id,再从数据库等数据源获取其他需要的字段。

这使得查询过程变成,首先通过solr得到document id set,再由Solr得到应用id集合,

最后从外部数据源得到完成的查询结果。如果对查询结果正确性没有苛刻的要求,可以在Solr之外独立的缓存完整的

 

查询结果(定时作废),这时queryResultCache就不是很有必要,否则可以考虑使用queryResultCache。当然,如果发现在

queryResultCache生命周期内,query重合度很低,也不是很有必要开着它。 



4、documentCache
  又顾名思义,documentCache用来保存<doc_id,document>对的。如果使用documentCache,就尽可能开大
  些,至少要大过<max_results> *<max_concurrent_queries>,否则因为cache的淘汰,
  一次请求期间还需要重新获取document一次。也要注意document中存储的字段的多少,避免大量的内存消耗。

5、User/Generic Caches 
  Solr支持自定义Cache,只需要实现自定义的regenerator即可

6、The Lucene FieldCache 
  lucene中有相对低级别的FieldCache,Solr并不对它做管理,所以,lucene的FieldCache还是由lucene的IndexSearcher来搞。 

7、autowarm
  上面有提到autowarm,autowarm触发的时机有两个,一个是创建第一个Searcher时(firstSearcher),一个是创建个新
  Searcher(newSearcher)来代替当前的Searcher。在Searcher提供请求服务前,Searcher中的各个Cache可以
  做warm处理,处理的地方通常是SolrCache的init方法,而不同cache的warm策略也不一样。
  1)filterCache:filterCache注册了下面的CacheRegenerator,就是由旧的key查询索引得到新值put到新cache中。
  2)queryResultCache:queryResultCache的autowarm不在SolrCache的init(也就是说,不是去遍历已
  有的queryResultCache中的query key执行查询),而是通过SolrEventListener接口的void
  newSearcher(SolrIndexSearcher newSearcher, SolrIndexSearcher
  currentSearcher)方法,来执行配置中特定的query查询,达到显示的预热lucene FieldCache的效果。
  3)documentCache:因为新索引的document id和索引文档的对应关系发生变化,所以documentCache没有warm的过程,
  落得白茫茫一片真干净。尽管autowarm很好,也要注意autowarm带来的开销,这需要在实际中检验其warm的开销,
  也要注意Searcher的切换频率,避免因为warm和切换影响Searcher提供正常的查询服务。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-314348-1-1.html 上篇帖子: 配置solr (windows) 并配中文分词 IKAnalyzer 下篇帖子: Solr+Tomcat在Windows下的搭建
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表