Elasticsearch的filter的caching(缓存)机制详解

编程界的小学生 2017-12-27 07:50:54

直接举例说明

1.假设现在要在倒排索引中去搜索字符串(xxx)

比如如下有个倒排索引列表:

Elasticsearch的filter的caching(缓存)机制详解

我现在要搜索:2017-02-02

去倒排索引中找,发现对应的document list是doc2和doc3

2.为每个在倒排索引中搜索到的结果,构建一个bitset

使我们找到的doc list构建一个bitset,就是一个二进制数组,数组每个元素都是0或1。用来标识一个doc对一个filter条件是否匹配,如果匹配就是1,不匹配就是0

[0,1,1]

doc1:不匹配这个filter的

doc2和doc3:匹配这个filter的

尽可能用简单的数据结构去实现复杂的功能,可以节省内存空间,提升性能

3.遍历每个过滤条件对应的bitset,优先从最稀疏的开始搜索,查找满足所有条件的document

一次性其实可以在一个search请求中,发出多个filter条件,每个filter条件都会对应一个bitsite,遍历每个filter条件对应的bitset,先从最稀疏的开始遍历

[0, 0, 0, 1, 0, 0]:比较稀疏

[0, 1, 0, 1, 0, 1]

先遍历比较稀疏的bitset,就可以先过滤掉尽可能多的数据

遍历所有的bitset,找到匹配所有filter条件的doc

请求:filter,postDate=2017-01-01,userID=1

postDate: [0, 0, 1, 1, 0, 0]

userID: [0, 1, 0, 1, 0, 1]

遍历完两个bitset之后,找到的匹配所有条件的doc。就是doc4,就可以将doc4作为结果返回给client了

4.caching bitset

跟踪query,在最近256个query中超过一定次数的过滤条件,缓存其bitset。对于小segment(<1000,或<3%),不缓存bitset。

比如postDate=2017-01-01, [0,0,1,1,0,0],可以缓存在内存中,这样下次如果再有这个条件过来的时候,就不用重新扫描倒排索引,不用反复生成bitset,可以大幅度提升性能。

在最近的256个filter中,有某个filter超过了一定的次数,次数不固定,就会自动缓存这个filter对应的bitset

lter针对小segment获取到的结果,可以不缓存,segment记录数<1000,或者segment大小<index总大小的3%

segment数据量很小,此时哪怕是扫描也很快;segment会在后台自动合并,小segment很快就会跟其他小segment合并成大segment,此时就缓存也没有什么意义,segment很快就消失了

针对一个小segment的bitset,[0, 0, 1, 0]

filter比query的好处就在于会caching,但是之前不知道caching的是什么东西,实际上并不是一个filter返回的完整的doc list数据结果。而是filter bitset缓存起来。下次不用扫描倒排索引了。

5. filter大部分情况下来说,在query之前执行,先尽量过滤掉尽可能多的数据

query:是会计算doc对搜索条件的relevance score,还会根据这个score去排序

filter:只是简单过滤出想要的数据,不计算relevance score,也不排序

6. 如果document有新增或修改,那么cached bitset会被自动更新

postDate=2017-01-01,[0, 0, 1, 0]

document,id=5,postDate=2017-01-01,会自动更新到postDate=2017-01-01这个filter的bitset中,全自动,缓存会自动更新。postDate=2017-01-01的bitset,[0, 0, 1, 0, 1]

document,id=1,postDate=2016-12-30,修改为postDate-2017-01-01,此时也会自动更新bitset,[1, 0, 1, 0, 1]

7. 以后只要是有相同的filter条件的,会直接来使用这个过滤条件对应的cached bitset

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java将前端的json数组字符串转换为列表

记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang