zoukankan      html  css  js  c++  java
  • solr查询优化(实践了一下效果比较明显)

    什么是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进行缓存,然后再和另外一部分查询的结果进行求交运算。

      

           通过上面这幅图明白了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();  
          
      1.  
        query.addFilterQuery("category:ksiazka");
      2.  
        query.addFilterQuery("section:ksiazki");
      3.  
        query.setQuery("name:solr");
      4.  
         
      5.  
        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能够使用它,而是如何构建查询语句来提升性能。当考虑查询的时候,请考虑这一点。

  • 相关阅读:
    Atitti 图像处理 图像混合 图像叠加 blend 原理与实现
    Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途
    Atitit 图像处理 灰度图片 灰度化的原理与实现
    Atitit (Sketch Filter)素描滤镜的实现  图像处理  attilax总结
    Atitit 实现java的linq 以及与stream api的比较
    Atitit attilax在自然语言处理领域的成果
    Atitit 图像处理 常用8大滤镜效果 Jhlabs 图像处理类库 java常用图像处理类库
    Atitit 图像处理--图像分类 模式识别 肤色检测识别原理 与attilax的实践总结
    Atitit apache 和guava的反射工具
    atitit。企业的价值观 员工第一 vs 客户第一.docx
  • 原文地址:https://www.cnblogs.com/cuihongyu3503319/p/9329120.html
Copyright © 2011-2022 走看看