即使是不成熟的尝试,也胜于胎死腹中的策略。

关于es缓存

Elasticsearch | 作者 mhl | 发布于2017年11月01日 | 阅读数:8754

看了下es文档,大概总结了几种缓存,不知道理解对不对。
1.node query cache 同样的请求在node级别进行缓存,包括缓存结果
2.shard request cache shard级别的缓存,主要缓存size=0的请求,缓存hits total,以及aggs等信息
3.fielddatacache node级别缓存,缓存aggs,排序等信息
4.bitset shard级别,位运算,匹配 同样的条件,比如 term , range等,只缓存该shard中满足条件的docId。 es5去除了term cache,同样的term请求,还必须走bitset 然后 feach

同样有个问题,因为还没看代码,猜测比如node级别的缓存,同样的请求缓存了结果,同时也缓存了命中的段列表。 新数据进来,生成新段,缓存结果做merge?

请问我理解对么?
已邀请:
理解基本正确, 只是你说的1和4其实是一个东西。
  1. Node Query Cache,早期版本也叫做filter cache。 Node级别,被所有shard共享。 主要用于缓存在filter上下文里执行的Query,比如Range Query。 缓存的是压缩过的bitset,对应满足Query条件的docID列表。 这个缓存有一些智能的地方: 比如不是所有的Query都会被缓存,而是记录最近256个Query,只有重用过的,才会被挑选出来放到缓存; 对于小的segment会跳过不缓存; 5.1 以后对于term query完全不缓存; 新写入的文档会增量加入到bitset,而无需反复重建整个bitset。 
  2. Shard request cache, shard级别的缓存。 主要用于缓存size=0的聚合信息,和你理解的一样。
  3. Fielddata Cache。  不是用于缓存Aggs,而是缓存所谓的field data。 早期版本,ES没有doc values这样的数据结构,只有倒排索引。 做数据聚合和排序的时候,需要将倒排索引的数据读取出来,重新组织成一个根据指定字段,按照文档序排列的值列表。 之后才能够高效的做排序和聚合计算。由于这个转换工作很耗资源,转换好的列表就会被缓存到fielddata cache,提升速度。 但是因为这个cache是在heap内部的,海量数据聚合的时候,生成的这些fielddata可能heap都放不下,很容易引起性能问题,甚至JVM OOM。 从ES 2.0开始,提供了doc values特性,将field data的构建放在了index time,并且这些数据直接放到磁盘上,通过memory mapped file的方式来访问。 使得海量数据的聚合可以有效利用堆外内存,性能和稳定性都有提高。 因此支持doc values特性的字段类型,比如keyword, 数值型等等,不会再用到fielddata cache。 由于text字段没有doc values支持,所以对text类型字段做排序和聚合的时候,依然会构造field data,填充到cache里。
  4. 文件系统缓存,也就是Linux OS page cache。 ES对于索引的访问是通过memory mapped file来访问的,经常访问的segment,只要没有合并,再次访问时可以直接从page cache里读取。 所以索引里被经常访问的热数据片段,等同于内存读取。
  5. 另外还有一个数据结构,叫做Global Ordinals,用于加速排序和Terms aggregation。这个数据的构建类似field data比较繁重,因此也会被缓存起来。 其没有专门的cache空间,而是放在Fielddata Cache。  

 
 
PS.  ES随着版本的快速更迭,缓存的机制也在不断改进,以上解释只针对目前5.x版本。
 
 

要回复问题请先登录注册