什么是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:

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

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

客户端API调用:

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

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

使用filterQuery之后的查询代码:

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

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

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

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

  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方法的次数

  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能够使用它,而是如何构建查询语句来提升性能。当考虑查询的时候,请考虑这一点。

solr查询优化(实践了一下效果比较明显)的更多相关文章

  1. solr查询优化【转】filtercache

    solr查询优化(实践了一下效果比较明显) 什么是filtercache? solr应用中为了提高查询速度有可以利用几种cache来优化查询速度,分别是fieldValueCache,queryRes ...

  2. 后端技术杂谈4:Elasticsearch与solr入门实践

    阮一峰:全文搜索引擎 Elasticsearch 入门教程 作者:阮一峰 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://g ...

  3. 二、JavaScript语言--JS实践--信息滚动效果制作

    运用JavaScript技术,掌握无缝滚动和歇间性滚动的制作方法. 一.marquee标签实现信息滚动 1 behavior滚动的方式 alternate:表示在两端之间来回滚动 scroll:表示由 ...

  4. solr最佳实践

    管理页面 页面地址:http://{ip}:{port}/solr/#/ 管理页面的data-import页可以手动重建索引,configuration指定了数据源,重建索引也可以通过http请求触发 ...

  5. solr 最佳实践

    管理页面 页面地址:http://{ip}:{port}/solr/#/ 管理页面的data-import页可以手动重建索引,configuration指定了数据源,重建索引也可以通过http请求触发 ...

  6. SQL查询优化实践

    为什么要优化 系统的吞吐量瓶颈往往出现在数据库的访问速度上,即随着应用程序的运行,数据库的中的数据会越来越多,处理时间会相应变慢,且数据是存放在磁盘上的,读写速度无法和内存相比 如何优化 设计数据库时 ...

  7. mysql 千万级数据查询效率实践,分析 mysql查询优化实践--本文只做了一部分,仅供参考

    数据量, 1300万的表加上112万的表 注意: 本文只做了部分优化,并不全面,仅供参考, 欢迎指点.   请移步tim查看,因为写的时候在tim写的,粘贴过来截图有问题,就直接上链接了. https ...

  8. solr特点八:Spatial(空间搜索)

    前言 在美团CRM系统中,搜索商家的效率与公司的销售额息息相关,为了让BD们更便捷又直观地去搜索商家,美团CRM技术团队基于Solr提供了空间搜索功能,其中移动端周边商家搜索和PC端的地图模式搜索功能 ...

  9. Git之VS2010实践

    对于我们经常在VS2010下编程的开发人员来说,强大的SCM工具Git貌似对我们很陌生.对于Git,我在我的另一篇博客<Git学习笔记>中已做过介绍,下面我再简单介绍一下Git在VS201 ...

随机推荐

  1. hdu4965矩阵快速幂

    这题不能直接按常规做啊,因为数组根本就开不下,转换思维A(B*A)^(n*n-1)B 这样的话数组B*A就是10*10了,然后快速幂就行了 刚开始数组都开小了,tle,还找了半天bug...还有就是定 ...

  2. Linux CentOS7.0下JAVA安装和配置环境变量

    一.前言: CentOS7.0虽然自带JDK1.7和1.8,运行“java -version”命令也可以看到版本信息,但是jdk的安装环境不全,比如缺少tool.jar和dt.jar等,这就导致“ja ...

  3. 自定义jQuery的animate动画

    //擦除效果 jQuery.extend(jQuery.easing, { easeOutBack : function(x, t, b, c, d, s) { s = s || 1.3; retur ...

  4. 关于poi操作excel我使用的一些修饰操作

    被这情况恶心了.我的excel默认为常规,然后写入数字就成类似number类型,获取值得到的是double类型,2变成2.0.号码变成科学计数法. 做功能找了一段时间,保存下来防止忘记下次浪费时间. ...

  5. 浅谈ES6的let和const的异同点

    1.let和const的相同点: ① 只在声明所在的块级作用域内有效. ② 不提升,同时存在暂时性死区,只能在声明的位置后面使用. ③ 不可重复声明. 2.let和const的不同点: ① let声明 ...

  6. Unix网络编程第三版源码编译

    配置: $ cd Unix-Network-Programming/ $ chmod 755 configure $ ./configure 主要的工作是检查系统是否有源码编译所依赖的各种资源(系统版 ...

  7. 第3课 进化后的const分析

    C语言中的const const修饰的变量是只读的,本质还是变量 const修饰的局部变量在栈上分配空间(改变这个空间的值,这个变量就会改变) const修饰的全局变量在只读存储区分配空间 const ...

  8. Buildroot 打包文件系统流程跟踪

    /********************************************************************************* * Buildroot 打包文件系 ...

  9. POJ3696 The Luckiest number

    题意 Language:Default The Luckiest number Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7 ...

  10. mongodb下cpu高的查询方式(慢查询)

    1.查看mongodb进程 ps-ef | grep mongo 获取进程id为3267 2.查看进程的线程 top -p 3267 按shift+h 查看cpu高的线程,发现有线程点用cpu高且cp ...