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

[经验分享] solr查询优化(实践了一下效果比较明显)

[复制链接]

尚未签到

发表于 2015-7-19 10:10:39 | 显示全部楼层 |阅读模式
什么是filtercache?
  solr应用中为了提高查询速度有可以利用几种cache来优化查询速度,分别是fieldValueCache,queryResultCache,documentCache,filtercache,在日常使用中最为立竿见影,最有效的应属filtercache,何谓filtercache?这个需要从一段solr的查询日志开始说起,下面是我截取的solr运行中打印的一段查询日志:

[search4alive-0] Request_is ==> q=status%3A0++AND+biz_type%3A2+AND+class_id%3A1&sort=index_sort_order+desc&start=0&rows=5,queryTime_is ==> 2                                      
[search4alive-0] Request_is ==> q=status%3A0++AND+biz_type%3A1+AND+class_id%3A1+AND+%28group_id%3A411%29&sort=gmt_create+desc&start=0&rows=20,queryTime_is ==> 2                  
[search4alive-0] Request_is ==> q=status%3A0++AND+biz_type%3A2+AND+class_id%3A1&sort=index_sort_order+desc&start=0&rows=5,queryTime_is ==> 2                                      
[search4alive-0] Request_is ==> q=status%3A0++AND+biz_type%3A1+AND+class_id%3A1+AND+%28group_id%3A8059%29&sort=gmt_create+desc&start=0&rows=20,queryTime_is ==> 0                 
[search4alive-0] Request_is ==> debugQuery=on&group=true&group.field=group_id&group.ngroups=true&group.sort=gmt_create+desc&q=status%3A0++AND+biz_type%3A1+AND+class_id%3A1+AND+ha
[search4alive-0] Request_is ==> q=status%3A0++AND+biz_type%3A2+AND+class_id%3A1&sort=index_sort_order+desc&start=30&rows=30,queryTime_is ==> 4                                    
[search4alive-0] Request_is ==> q=status%3A0++AND+biz_type%3A2+AND+class_id%3A1&sort=index_sort_order+desc&start=0&rows=5,queryTime_is ==> 1                                      
[search4alive-0] Request_is ==> q=status%3A0++AND+biz_type%3A1+AND+class_id%3A1+AND+%28group_id%3A375%29&sort=gmt_create+desc&start=0&rows=20,queryTime_is ==> 3                  
[search4alive-0] Request_is ==> q=status%3A0++AND+biz_type%3A2+AND+class_id%3A1&sort=index_sort_order+desc&start=0&rows=5,queryTime_is ==> 1                                      
[search4alive-0] Request_is ==> q=status%3A0++AND+biz_type%3A2+AND+class_id%3A1&sort=index_sort_order+desc&start=0&rows=30,queryTime_is ==> 4                                    
[search4alive-0] Request_is ==> q=status%3A0++AND+biz_type%3A2+AND+class_id%3A1&sort=index_sort_order+desc&start=0&rows=5,queryTime_is ==> 1                                      
[search4alive-0] Request_is ==> q=status%3A0++AND+biz_type%3A2+AND+class_id%3A1&sort=index_sort_order+desc&start=0&rows=30,queryTime_is ==> 4                                    
[search4alive-0] Request_is ==> q=status%3A0++AND+biz_type%3A2+AND+class_id%3A1&sort=index_sort_order+desc&start=0&rows=30,queryTime_is ==> 3                                    

  看到这段查询日志之后,我们开始考虑如何提升查询的rt(查询速度),因为在参数q中的查询是要有磁盘IO开销的,很自然的思路是将整个查询的参数q作为key,对应的结果作为value,这样做是可以的,但是查询的命中率会很低,会占用大量内存空间。
  查询参数q上基本上每次都会出现status,biz_type,class_id 对于这样的字查询,所以可以把整个查询条件分成两部分一部分是以status,biz_type,class_id 这几个条件组成的子查询条件,另外一部分是除这三个条件之外的子查询。在进程查询的时候,先将status,biz_type,class_id 条件组成的条件作为key,对应的结果作为value进行缓存,然后再和另外一部分查询的结果进行求交运算。
  

DSC0000.png
  
  通过上面这幅图明白了filtercache的意义是,将原先一个普通查询分割成两个组合查询的与运算,两个子查询至少有一个使用缓存,这样既减少了查询过程的IO操作,又控制了缓存的容量不会消耗过多的内存。

如何使用?
  首先要配置solrconfig.xml 要开启fltercache:
  






Xml代码   DSC0001.png

  •   
  •          
  •   
  这里使用的是solr实现的基于LRU算法的缓实现,以上配置是使用solr.LRUCache ,使用这个cache在插入多,查询少的情况比较使用,如果是查询多,插入少的情况,可以使用solr.FastLRUCache缓存模块。
  
  
  客户端API调用:
  下面是原先的客户端端查询代码:
  






Java代码  

  • SolrQuery query = new SolrQuery();  
  •   
  • query.setQuery("status:0 AND biz_type:1 AND class_id:1 AND xxx:123");  
  •   
  • QueryResponse response = qyeryServer.query(query);  
  
  
  使用filterQuery之后的查询代码:
  






Java代码  

  • 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调用方法如下所示:
  






Java代码  

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






Java代码  

  • 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方法来完成。
  



下文摘自solr中国
  
  
What it is used for?
  
先从内部机制开始。FilterCache存储了一些无序的文档标识号(ID)。这些ID并不是我们在schema.xml里配置的unique key,而是solr内部的一个文档标识。请记住这个。
  
FilterCache的任务是保持与用户过滤的结果关联。另外,cache可以辅助facet机制(在使用TermEnum时),在solrconfig.xml中的参数设为true时,还可以进行排序。
  
Definition

FilterCache的标准定义如下:





Xml代码



  
有以下的配置可供选择:

class:实现类。建议使用solr.FastLRUCache,它能在大量的GET、PUT操作下,提供更好的性能。

size:cache的最大值。

initialSize:cache的初始化值。

autowarmCount:从旧的cache到新的cache时,需要被复制的数量。

minSize:在full restoraton的情况下,将cache减小后的值

acceptableSize:如果minSize没有设置,则该值会替代之

cleanupThread:默认false,如果设为true则会使用一个分离的topic来清理cache。
  
大部分情况下,设置initialSize和autowarmCount就已经足够了。
  
How to configure?

cache的大小,需要根据基本的查询语句而定;maximum大小应该至少等于我们使用的过滤字段的大小。举个例子说明:如果在某个时间内,你的应用程序使用了2000个查询参数,则minimum的大小应该最小设为2000。
  
Efficient use

然而,光有配置是不够的,我们还需要让查询能够使用它。请看下面的例子:







  • q=name:solr+AND+category:ksiazka+AND+section:ksiazki
  
初看起来,查询语句是正确的。但是有个问题:它并没有用到filterCache。所有的请求将会绑定到queryResultCache中并创建一个单独的条目。我们来作一下修改:







  • q=name:solr&fq=category:ksiazka&fq=section:ksiazki

  • 对应java代码:

  •     SolrQuery query = new SolrQuery();  
        query.addFilterQuery("category:ksiazka");
    query.addFilterQuery("section:ksiazki");  
    query.setQuery("name:solr");  
    QueryResponse response = qyeryServer.query(query);
  
有什么变化呢?在这个例子中,一个条目会写入到queryResultCache中;另外,还会有两个条目会写入到filterCache中。现在看一下下面的语句:







  • q=name:lucene&fq=category:ksiazka&fq=section:ksiazki
  
这个查询会创建一个条目到queryResultCache中,但是会使用filterCache中两个已经存在的条目。这样查询的执行时间会降低,IO的使用也会节省。
  
然而,对于下面的查询:







  • q=name:lucene+AND+category:ksiazka+AND+section:ksiazki
  
solr不能使用任何cache并且需要从lucene索引中收集所有的信息。
  
Last few words

就像你所看到的,配置cache 的正确方法不是如何保证solr能够使用它,而是如何构建查询语句来提升性能。当考虑查询的时候,请考虑这一点。

运维网声明 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-88179-1-1.html 上篇帖子: hbase、mongodb、redis、lucene、 solr研究 下篇帖子: Solr入门教程
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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