solr查询优化(实践了一下效果比较明显)

摘要:
为了提高查询速度,solr应用程序可以使用多个缓存来优化查询速度,它们是fieldValueCache、queryResultCache、documentCache和filtercache。它们在日常使用中是最直接有效的。什么是filtercache?查询流程时,首先设置status、biz_ type、class_由id条件组成的条件作为关键字,相应的结果作为值缓存,然后与查询结果的另一部分相交。
什么是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进行缓存,然后再和另外一部分查询的结果进行求交运算。

solr查询优化(实践了一下效果比较明显)第1张

  

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

如何使用?

首先要配置solrconfig.xml 要开启fltercache:

Xml代码  收藏代码
  1. <query>  
  2.         <filterCache    class="solr.LRUCache"     size="50000"      initialSize="512"      autowarmCount="0"/>  
  3. </query>  

 这里使用的是solr实现的基于LRU算法的缓实现,以上配置是使用solr.LRUCache ,使用这个cache在插入多,查询少的情况比较使用,如果是查询多,插入少的情况,可以使用solr.FastLRUCache缓存模块。

客户端API调用:

下面是原先的客户端端查询代码:

Java代码  收藏代码
  1. SolrQuery query = new SolrQuery();  
  2.   
  3. query.setQuery("status:0 AND biz_type:1 AND class_id:1 AND xxx:123");  
  4.   
  5. QueryResponse response = qyeryServer.query(query);  

使用filterQuery之后的查询代码:

Java代码  收藏代码
  1. SolrQuery query = new SolrQuery();  
  2.   
  3. query.addFilterQuery("status:0 AND biz_type:1 AND class_id:1");  
  4. query.setQuery("xxx:123");  
  5.   
  6. QueryResponse response = qyeryServer.query(query);  

经过测试这样优化之后,查询的RT(查询速度)会明显减小,QPS(每秒查询率)会有明显提升。

使用filterquery过程中需要注意点:

●不能在filterQuery 上重复出现query中的查询参数,如果上面的filterquery调用方法如下所示:

Java代码  收藏代码
  1. query.addFilterQuery("status:0 AND biz_type:1 AND class_id:1 AND xxx:123");  
  2. query.setQuery("xxx:123");  

 如上,条件xxx:123 在filterQuery和query上都出现了,这样的写法非但起不到查询优化的目的,而且还会增加查询的性能开销。

●尽量减少调用addFilterQuery方法的次数

Java代码  收藏代码
  1. query.addFilterQuery("status:0 ");  
  2. query.addFilterQuery("biz_type:1 ");  
  3. query.addFilterQuery("class_id:1 ");  
  4. 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中的<useFilterForSortedQuery/>参数设为true时,还可以进行排序。

Definition
FilterCache的标准定义如下:

Xml代码
  1. <filterCache
  2.     class=”solr.FastLRUCache”
  3.     size=”16384″
  4.     initialSize=”4096″
  5.     autowarmCount=”4096″ />

有以下的配置可供选择:
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
然而,光有配置是不够的,我们还需要让查询能够使用它。请看下面的例子:

  1. q=name:solr+AND+category:ksiazka+AND+section:ksiazki

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

  1. q=name:solr&fq=category:ksiazka&fq=section:ksiazki
  2. 对应java代码:
  3.     SolrQuery query = new SolrQuery();  
        
        query.addFilterQuery("category:ksiazka");
        query.addFilterQuery("section:ksiazki");  
        query.setQuery("name:solr");  
          
        QueryResponse response = qyeryServer.query(query);  


有什么变化呢?在这个例子中,一个条目会写入到queryResultCache中;另外,还会有两个条目会写入到filterCache中。现在看一下下面的语句:

  1. q=name:lucene&fq=category:ksiazka&fq=section:ksiazki

这个查询会创建一个条目到queryResultCache中,但是会使用filterCache中两个已经存在的条目。这样查询的执行时间会降低,IO的使用也会节省。

然而,对于下面的查询:

  1. q=name:lucene+AND+category:ksiazka+AND+section:ksiazki

solr不能使用任何cache并且需要从lucene索引中收集所有的信息。

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


免责声明:文章转载自《solr查询优化(实践了一下效果比较明显)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇企业认证抖音的好处和引流策略HTML标记之a标签下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

solr搜索之搜索精度问题我已经尽力了!!!

solr搞了好久了,没啥进展,没啥大的突破,但是我真的尽力了! solr7可能是把默认搜索方式去掉了,如下: 在solr7里找了半天以及各种查资料也没发现这个默认搜索方式,后来想,可能是被edismax里的mm取代了吧,都是控制搜索精度的,如下: 这个mm还是挺解决问题的,但是对于我们公司来说就差那么一点,就一点。就这一点我没有解决。正常情况下这个参数...

du -sh

本文来自依云's Blog,转载请注明。 du命令的输出结果要么是不人性化的全部以千字节为单位,要么加上-h参数,显示为1K 234M 2G这样易读的数据。可是,我通常想查看那些大文件/目录,或者那些小文件/目录。单单只用sort命令的话,就不得不在脑海转换那些千字节单位的数据了。做为一个Linux用户,电脑能做的我可不想让人脑来做。Google了一下,...

Solr单机版的安装与部署(使用Tomcat)

一、硬件环境 假设有1台机,IP及主机名如下: 192.168.100.105 c1 二、软件环境 操作系统:Ubuntu Server 18.04 JDK:1.8.0 1.安装JDK https://www.cnblogs.com/live41/p/14235891.html 2.安装Tomcat https://www.cnblogs.com/live...

solr的配置文件及其含义

solr与.net系列课程(二)solr的配置文件及其含义        solr与.net系列课程(二)solr的配置文件及其含义        本节内容还是不会涉及到.net与数据库的内容,但是不要着急,这都是学时solr必学要掌握的东西,solr可不是像其他的dll文件一样,只需要引用就能调出方法与数据的,你不配置好是无法使用,前两节主要是起铺垫...

c#操作MangoDB 之MangoDB CSharp Driver驱动详解

序言MangoDB CSharp Driver是c#操作mongodb的官方驱动。 官方Api文档:http://api.mongodb.org/csharp/2.2/html/R_Project_CSharpDriverDocs.htm#! 驱动的具体介绍:https://docs.mongodb.org/ecosystem/drivers/csharp...

搭建第一个web项目:实现用户的增删改查(四)

前台采用了easyUI框架。 这里浪费时间比较多的就是对easyUI中的一些插件的扩展。因为自己一开始jQuery基础确实不是太好,有些问题不能及时发现。 下面是easyUI一个增删改的列表实现: 在图中,可以看到列表底部有总记录,页码,还有reload按钮和添加按钮。所以在项目中建立了一个工具类,用于包装这些数据。EasyGridAction.java...