内存控制篇

elasticsearch除了提供检索功能之外,还能做更多的事情,比如近实时的数据分析。对此elasticsearch提供了聚合aggregation模块,这比之前的facet模块更加强大。具体提供的聚合类型本文不再介绍,而是重点关注aggr模块中关于内存控制的一些事情。

  • Fielddata

aggr大量使用fielddata,fielddata也是es中的内存大户。众所周知,倒排索引建立了term到doc之间的映射,因此适合快速查询匹配term的doc。而aggr的应用场景恰恰是相反的,因此需要建立doc到term之间的映射关系,这就是fielddata。

(1) analyzed vs not_analyzed:

如果是分词字段,则该字段的值被拆解成为多个term,如果是针对term的聚合操作就会出现意向不到的结果,所以要根据应用场景来决定是对分词字段进行聚合还是对不分词字段进行聚合操作,当然这种错误是比较容易发现的,在multifield的前提下可以及时作出调整。

对于基数很高的string类型的分词字段,如果进行聚合操作,fielddata会非常大,加载到内存中会有隐患。分词进程通常会产生大量term,并且很多term都是唯一的,这就增加了这个field的总体基数,也就增加了更多的内存压力。考虑n-gram分词的场景,比如new york将会产生ne,ew,w_,_y,yo,or,rk多个,这无疑增加了内存的消耗。

(2) 控制fielddata的内存使用量

为了aggr操作的速度考虑,fielddata需要load到内存中以提高访问效率。但这并不是没有代价的。过多的fielddata会造成jvm的垃圾回收变慢,甚至会造成oom。jvm的内存空间也会有限资源,如果fielddata的内存使用控制不好,会对节点稳定性造成影响。es进程可以使用的内存大小可以通过ES_HEAP_SIZE来进行设置。注意:可以调高这个参数来获取更多的内存使用量,但是建议不超过总体内存的50%,但是不要超过32G.(这是jvm的机制决定的,在小于32G的情况下会开启指针压缩,8字节变4字节,无疑将会节约大量内存,大于32G的情况下,则不启用指针压缩,空间虽然大了,但是垃圾回收将会消耗更大,导致不稳定性)。下边来看一下es对fielddata内存使用量的控制机制:

indices.fielddata.cache.size:控制fielddata可以使用多大内存。如果超过这个设置,则lru(这会导致大量的磁盘IO,在内存中也会出现大量的垃圾)而es对这个设置的默认取值是无限制的(鉴于几个考量:1:fielddata并不是只用一次的cache 2:fielddata建立过程是昂贵的操作,如果每次请求再去加载,显然是无法接受的。),因此在默认设置下,是不会有数据淘汰的。

这里有一个关键点:对于size的衡量是否超过限制,是先加载再衡量的,因此就会有一个问题:如果需要加载的fielddata超过已经超过了目前的限制,会怎么样呢?很遗憾,会导致oom。鉴于这个考量,有了另外一个机制:circuit breaker。该机制会预估将要加载的fielddata的数量来决定是否加载,如果容量充足则加载,如果容量不足则会放弃这次请求,抛出一个异常(如果抛出了这个异常,应用就需要考虑下为什么你的请求需要那么多的fielddata呢?是否要优化一下。)。因为是预估,所以是在加载之前,因此也就不会造成oom的问题。针对fielddata的配置项为:indices.breaker.fielddata.limit。默认60%。另外还有indices.breaker.request.limit,默认40%

indices.break.total.limit,默认70%。

建议将circuit breaker配置为一个相对保守的数字,默认60%是相对合理的。我们应该注意到,jvm的heap是共享的,也就是说fielddata.limit, request.limit,以及index buffer,filter cache等等都是共享heap的。因此如果过度设置circuit breaker会引起潜在oom,可能让node挂掉。

注意:indices.fielddata.cache.size < indices.breaker.fielddata.limit.limit的值一定要大于size值。否则将永远不会有lru发生,也就失去了设置的意义。

其实circuit breaker机制也不是没有缺陷的。首先,是一种预估,并不是准确的,因此会存在偏差。其次,比较的对象是total heap而不是free heap,因此强烈建议配置的值要是相对保守的。

另外fielddata支持filter,可以决定加载哪些不加载哪些,比如tf小于0.01的不加载等等。根据具体的业务场景来进行分析。

  • doc values

理想情况下我们希望fielddata是全部常驻内存的,但是内存毕竟是有限的,因此需要增加节点来尽量多的保存fielddata数据。但是这样也造成了资源的浪费,在内存被充分利用的情况下,cpu等其他资源则可能是闲置的。如果采用了上述的配置,内存是限制住了,但是缺陷也是显而易见的。有没有一种访问速度快还不占用内存的fielddata的方案呢?有,doc values。

目前doc values的访问速度还是略慢于fielddata,大约10%-25%左右的样子。但是优势也是显而易见的:首先,磁盘存储而不是内存,这就不再多说了。其次,doc value是在index的时候创建的,fielddata需要在查询的时候加载(反转倒排索引),而doc value由于是index的时候创建完成了,因此在初始化过程要明显快于fielddata。

当然没有什么事情是完美的,doc values的优势自然也带来了不足,比如索引会变大,访问速度略慢于fielddata。但是我们真的会在乎访问速度的细微差别么?不尽然。doc values已经足够的高效,所以应用也许并不关注这点细微的差距。况且由此来会带来较快的垃圾回收等优势。

doc values目前还不能应用与analyzed string field。

doc value的启用也非常简单,只需要在mapping中对应的doc_values属性设置为true即可。

在可以遇见的将来doc value format将会成为es默认设置。

  • aggr的collect_mode

默认是depth_first,大多情况下都能很好的工作,但在一些特殊场景下breadth_first则更适合。比如

我们有一份电影的数据,记录了每一部电影的参演演员信息。我们想得到参演最多的10个演员,并且得到与这10个演员合作做多的演员的前5个助演。

显然,只需要对actors进行terms aggr,size=10,并且内嵌一个同样类型的terms aggr,size=5。

但是,我们只是想得到top10 和 top5,总计50个对象,而默认的执行过程是depth_first,假设一部电影平均n个演员,那这个数量级显然是平方级别的,其实大部分对我们并没有用处。在这种应用场景下,我们只需要第一层聚合的10个对象,然后再进一步拓展,因此需要把第一层其余bucket去除,也就是breadth_first要做的事情。根据名称也可以知道,类似于多叉树的深度优先和广度优先。

elsaticsearch聚合内存控制相关推荐

  1. 【读书笔记】《深入浅出nodejs》第五章 内存控制

    海量请求+长时间运行 -> 内存控制 -> 一切资源高效循环利用 1. V8的垃圾回收机制与内存限制 在Node中通过JavaScript使用内存时,只能使用部分内存(64位系统下约1.4 ...

  2. Unity移动端游戏性能优化简谱之 常见游戏内存控制

    <Unity移动端游戏性能优化简谱>从Unity移动端游戏优化的一些基础讨论出发,例举和分析了近几年基于Unity开发的移动端游戏项目中最为常见的部分性能问题,并展示了如何使用UWA的性能 ...

  3. 白话Elasticsearch52-深入聚合数据分析之fielddata内存控制、circuit breaker短路器、fielddata filter、预加载机制以及序号标记预加载

    文章目录 概述 官网 fielddata核心原理 fielddata内存限制 监控fielddata内存使用 circuit breaker fielddata filter的细粒度内存加载控制 fi ...

  4. field data-es控制聚合内存使用-elasticsearch权威指南翻译

    #(主要是聚合使用,索引会从这里面获取term数据) 聚合通常通过一个叫fielddata的结构进行工作,fielddata经常会吃集群大量的内存,所以理解它咋工作的是非常重要的. fileddata ...

  5. Android内存控制小技巧-使用矢量图来节省你的内存并简化你的开发。

    先上一个 位图和矢量图的 说明.http://zhidao.baidu.com/link?url=xwvs5CBzWeh15O3Ee4bICwCqg4PCQWwg5oZ0a6CVydbVZzufqrI ...

  6. JVM堆内存控制/分代垃圾回收

    JVM的堆的内存, 是通过下面面两个参数控制的 -Xms 最小堆的大小, 也就是当你的虚拟机启动后, 就会分配这么大的堆内存给你  -Xmx 是最大堆的大小 当最小堆占满后,会尝试进行GC,如果GC之 ...

  7. 内存地址重映射的选项_内存控制设置请教

    匿名用户 1级 2016-02-08 回答 Bank Interleaving:Bank交错存取.内存bank 交错存取可以让系统对内存的不同bank同时存取,可以提升内存速度及稳定性.设置值有Aut ...

  8. openlayers6【二十六】业务交互:Cluster 聚合标注控制,显示隐藏聚合标注

    文章目录 1. 聚合标注常见业务需求交互 2. 实现效果 3. 核心代码 4. 完整代码 1. 聚合标注常见业务需求交互 业务需求:在地图场景中,通常是多种业务场景(点位图标,边界图层,热力图层等)在 ...

  9. 对象与内存控制1---实例变量和类变量

    一.实例变量和类变量的定义 Java程序的变量可分为成员变量和局部变量. 局部变量(作用时间短,存储在方法的栈中) 形参:由方法签名中定义,由方法调用者为其赋值,随方法的结束消亡. 方法内的局部变量: ...

最新文章

  1. 嵌入式linux硬件成本,嵌入式Linux驱动和固件有何区别?供应商是如何用固件压缩成本的?...
  2. 如何设计一门语言(一)——什么是坑(a)
  3. mysql约束深入了解_MySQL 的约束
  4. iview表单验证不生效问题注意点
  5. 【python】*与** 参数问题
  6. 【仿某公司前台】 asp安全查询系统
  7. MATLAB中SVM(支持向量机)的用法
  8. ModuleNotFoundError: No module named ‘models‘
  9. php环境用什么服务器好些_PHP环境部署,Linux真的比Windows好吗?
  10. 超星阅读器pdz文件打印转pdf文件
  11. Tuxedo服务中间件
  12. 一招win7 c盘瘦身
  13. can not connect to mysql server翻译_Message:Can not connect to MySQL server的解决办法
  14. oracle用户新建和授权,oracle创建用户及受权
  15. 使用 Envoy 和 AdGuard Home 阻挡烦人的广告
  16. MacOS Big Sur 如何安装创新SBX-Fi Surround 5.1Pro(USB外置)声卡?
  17. 计算机图形学应用题,计算机图形学教学大纲
  18. Fortran中输出Tecplot格式
  19. i7 10700和10700f 10700k这三个CPU有什么区别
  20. 响应时代号召 中烜速充走进新能源充电桩新时代

热门文章

  1. 维沃手机有没有智能机器人_【vivoiQOOPro评测】jovi人工智能评测:智商250的我竟有点慌(全文)_vivo iQOO Pro_手机评测-中关村在线...
  2. php closure 类,PHP中Closure类详解
  3. 金融,财务,融资相关知识(二)
  4. 2022年执业兽医考试测试题及答案
  5. 【UNITY】记录——导入透明视频
  6. 基于密度的聚类算法(1)——DBSCAN详解
  7. 解决Tensorflow显存溢出的问题
  8. 有没有python搜题_免费搜题公众号python
  9. 2021-05-10 打造自己的vim c/c++开发工具
  10. bat文件启动jar包