女主宣言

在Elasticsearch的运维过程中,我们经常会遇到节点不可用、OOM和垃圾回收时间过长等问题,如果每次都等出问题了才发现,极端情况下会影响业务访问。在日常运维中,我们需要提前预测这些问题,及时处理,防止影响业务。那么问题来了!我们要怎么监测呢?快跟随小编一起来看看吧!

本文是Emily Chang的分享《How to monitor Elasticsearch performance》中文译文的第一部分。这篇文章的原文可以在GitHub(阅读原文)上可以找到。

PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!

Elasticsearch

关于ES,大家可以查看之前的几篇文章来了解它。

《360私有云平台Elasticsearch服务初探》

《谨慎前行-浅谈Elasticsearch安全策略》

《Elasticsearch认证及安全》

《浅析ElasticSearch原理》

《AIOps时代下的利器:ELK》

Elasticsearch本身提供了大量的指标,可以帮助我们进行故障预检,并在遇到诸如节点不可用、JVM OutOfMemoryError和垃圾回收时间过长等问题时采取必要措施。 通常需要监测的几个关键领域是:

1.   查询和索引(indexing)性能

2.   内存分配和垃圾回收

3.   主机级别的系统和网络指标

4.   集群健康状态和节点可用性

5.   资源饱和度和相关错误

这些指标都是可以通过Elasticsearch’s RESTful API获取,也可以使用像Marvel这样的专用监控工具或者像Datadog这样的通用监控服务来监测。

查询(search)和索引(indexing)是Elasticsearch最主要的两种访问请求类型,他们有点类似于传统数据库系统中的读和写请求。

查询性能指标

对于查询(search)请求,Elasticsearch提供了与查询过程的两个主要阶段(Query和Fetch)相对应的指标。

下面的图示展示了一个查询请求的完整过程:

1.客户端发送请求给Node2(Node2 通常被称为“协调节点”,原则上,Elasticsearch的任意节点都可以成为协调节点)

2.   协调节点将请求转发至该索引的每一个分片的任意副本,既可以是主分片也可以是副本分片。

3.   每个接收请求的分片执行检索并将检索结果返回给协调节点,协调节点将接收到的检索结果排序并存储在一个全局优先级队列里。这里返回的并不是整个文档,通常是需要聚合和排序的字段以及全局唯一ID。

4. 协调节点找出哪些文档需要被获取(Fetch),然后发送一个Multi GET请求到相关的分片。

5.每一个接收请求的分片获取对应数据然后返回给协调节点。

6.协调节点发送数据给客户端。

如果您主要使用Elasticsearch进行查询,那么您应该关注查询延迟并在超出阈值时采取措施。监控Query和Fetch的相关指标可以帮助您跟踪查询在一段时间内的执行情况。例如,您可能需要跟踪查询曲线的峰值以及长期的查询请求增长趋势,以便可以优化配置来获得更好的性能和可靠性。

下图是需要关注的查询性能指标:

 

查询(Query)负载

监控当前查询并发数可以让您大致了解集群在某个时刻处理的请求数量。对不寻常的峰值峰谷的关注,也许能发现一些潜在的风险。您可能还需要监控查询线程池队列的使用情况,关于这一点我们将在稍后的文章中详细解释。

 

查询(Query)延迟

虽然Elasticsearch并没有直接提供这个指标,但是我们可以通过定期采样查询请求总数除以所耗费的时长来简单计算平均查询延迟时间。如果超过我们设定的某个阀值,就需要排查潜在的资源瓶颈或者优化查询语句。

 

获取(Fetch)延迟:

查询(search)过程的第二阶段,即获取阶段,通常比查询(query)阶段花费更少的时间。如果您注意到此度量指标持续增加,则可能表示磁盘速度慢、富文档化(比如文档高亮处理等)或请求的结果太多等问题。

索引性能指标

索引(Indexing)请求类似于传统数据库里面的写操作。如果您的Elasticsearch集群是写负载类型的,那么监控和分析索引(indices)更新的性能和效率就变得很重要。在讨论这些指标之前,我们先看一下Elasticsearch更新索引的过程。如果索引发生了变化(比如新增了数据、或者现有数据需要更新或者删除),索引的每一个相关分片都要经历如下两个过程来实现更新操作:refresh和flush

 

Refresh

首先我们要明确的是,新写入的文档在被refresh之前,并不能被检索到。新的文档首先会被写入内存的buffer里,并等待下一次索引的refresh操作。如果没有单独配置,refresh操作默认是每秒执行一次。每次refresh操作会把当前buffer里的数据写入一个内存段(segment,只有segment里的数据才能被检索到),然后清空对应的buffer。如下图所示:

这里关于segment的概念,我们稍微展开一点。大家知道,索引的每个分片都是由若干个segment组成。每一个segement都是一个完整的倒排索引(Inverted Index),用于保存词项(terms)和文档的对应关系,查询的时候会依次检索对应分片的所有segment。每次索引执行refresh的时候,都会生成一个新的segement,因此segment实际上记录了索引的一组变化值。但是由于每个segement的存储和扫描都需要占用一定资源(文件描述符、CPU、内存等),因此需要后台进程不断的进行段合并来减少segement的数量,从而提升效率降低资源消耗。但是段合并本身也是一个比较消耗性能的操作。

由于segment一旦生成就不能更新,因此文档的更新(Update)实际上意味着:

  1. 通过refresh将新的数据写入新的segment。

  2. 然后将旧的数据标记为deleted

这些被标记删除的数据在后续的段合并过程中才会最终被删除。

 

Flush

在新的文档被添加到索引内存缓冲区的同时,它们也被追加到分片的translog。translog是一个持久化的,记录所有更改操作( index, delete, update, or bulk)的write-ahead日志,可以防止数据丢失,并且可以用于分片的数据恢复。

每次flush操作,内存缓冲区中的所有文档都被refreshed(存储在新的segment中),所有内存中的segment都将落盘,并且清除translog。

有三种条件可以触发flush操作:

  1. translog日志达到限制大小(index.translog.flush_threshold_size,默认为512MB);

  2. 如果设置了index.translog.durability=request,则每次更新操作( index, delete, update, or bulk)之后都执行flush(这是Elasticsearch的默认行为)

  3. 如果index.translog.durability= async,则采用异步sync机制,每index.translog.sync_interval执行一次flush操作,默认是5秒,但是这种情况可能导致未落盘的数据丢失。

flush的过程如下图所示:

Elasticsearch提供了许多指标,您可以使用这些指标评估索引性能并优化更新索引的方式。

 

索引(Indexing)延迟:

Elasticsearch并未直接提供这个指标,但是可以通过计算index_total 和 index_time_in_millis来获取平均索引延迟。如果您发现这个指标不断攀升,可能是因为一次性bulk了太多的文档。Elasticsearch推荐的单个bulk的文档大小在5-15MB之间,如果资源允许,可以从这个值慢慢加大到合适的值。

如果您想要索引大量数据,并且不需要立即查询索引的数据,可以通过临时降低指定索引的refresh间隔,来提升索引的效率。如下API可以关闭索引的refresh操作:

但是请记得索引完数据,最好将这个参数改回默认值1s。

 

Flush延迟:

由于Elasticsearch是通过flush操作来将数据持久化到磁盘的,因此关注这个指标非常有用,可以在必要的时候采取一些措施。比如如果发现这个指标持续稳定增长,则可能说明磁盘IO能力已经不足,如果持续下去最终将导致无法继续索引数据。此时您可以尝试适当调低index.translog.flush_threshold_size的值,来减小触发flush操作的translog大小。与此同时,如果你的集群是一个典型的write-heavy系统,您应该利用iostat这样的工具持续监控磁盘的IO,必要的时候可以考虑升级磁盘类型。

内存分配和垃圾回收

在Elasticsearch运行过程中,内存是需要密切关注的关键资源之一。

Elasticsearch和Lucene以两种方式利用节点上的所有可用RAM:JVM堆和文件系统缓存。 Elasticsearch运行在Java虚拟机(JVM)上,这意味着JVM垃圾回收的持续时间和频率将是其他重要的监控领域。

 

JVM堆栈:金发女孩效应

Elasticsearch使用“恰到好处”来强调JVM 堆栈大小的设置原则,既不能太大,也不能太小。一般来说,Elasticsearch的经验法则是将少于50%的可用内存分配给JVM堆,并且永远不要超过32GB。分配给Elasticsearch的堆栈内存越少,留给Lucene的内存就越多,而Lucene在很大程度上依赖于文件系统缓存来快速检索数据。但是也不应该将堆大小设置得过于小,因为您可能会遇到OutOfMemoryError,或者是因为频繁的垃圾回收过程中的短暂暂停导致的吞吐量降低。可以参阅下面的指南来确定堆栈的大小,这是由Elasticsearch的核心工程师之一编写的。

https://www.elastic.co/blog/a-heap-of-trouble

 

垃圾回收

Elasticsearch依靠垃圾回收来释放堆栈内存。如果您想了解更多关于JVM垃圾回收的信息,请查看Java官方指南。由于垃圾回收本身需要消耗资源(为了释放资源!),您应该留意它的频率和持续时间,看看是否需要调整堆栈大小。将堆栈设置得太大可能导致垃圾回收时间过长,这些过多的暂停是非常危险的,因为它们可能会导致您的群集错误地认为您的节点已经掉线。

下图是需要关注的JVM相关指标:

 

JVM堆栈使用率

Elasticsearch默认当JVM堆栈使用率达到75%的时候启动垃圾回收。因此监控节点堆栈使用情况并设置告警阀值来定位哪些节点的堆栈使用率持续维持在85%变得非常有用,这表明垃圾回收的速度已经赶不上垃圾产生的速度了。要解决这个问题,您可以增加堆栈大小,或者通过添加更多的节点来扩展群集。

和JVM堆栈分配了多少内存(committed)相比,监控JVM使用了多少内存(used)会更加有用。使用中的堆栈内存的曲线通常会呈锯齿状,在垃圾累积时逐渐上升在垃圾回收时又会下降。 如果这个趋势随着时间的推移开始向上倾斜,这意味着垃圾回收的速度跟不上创建对象的速度,这可能导致垃圾回收时间变慢,最终导致OutOfMemoryError。

 

垃圾回收的时长和频率:

为了收集无用的对象信息,JVM会暂停执行所有任务,通常这种状态被称为“Stop the world”,不管是young还是old 垃圾回收器都会经历这个阶段。由于Master节点每隔30s检测一下其他节点的存活状态,如果某个节点的垃圾回收时长超过这个时间,就极可能被Master认为该节点已经失联。

 

内存使用

正如上面所述,Elasticsearch可以很好地使用任何尚未分配给JVM堆的RAM。 和Kafka一样,Elasticsearch被设计为依靠操作系统的文件系统缓存来快速可靠地处理请求。如果某个segment最近由Elasticsearch写入磁盘,那么它已经在缓存中。 但是,如果一个节点已被关闭并重启,则在第一次查询一个segment的时候,必须先从磁盘读取数据。所以这是确保群集保持稳定并且节点不会崩溃的重要原因之一。通常,监视节点上的内存使用情况非常重要,并尽可能为Elasticsearch提供更多的RAM,以便在不溢出的情况下最大化利用文件系统缓存。

总结

本文讲解了三个领域的监测指标:

1.   查询和索引(indexing)性能

2.   内存分配和垃圾回收

3.   主机级别的系统和网络指标

下篇文章,我们将继续讲解剩下的两类指标:

1.   集群健康状态和节点可用性

2.   资源饱和度和相关错误

敬请期待~

扫描下方
二维码
了解更多内容

Elasticsearch性能监控(一)相关推荐

  1. Elasticsearch性能监控(二)

    女主宣言 上一期我们分享了<Elasticsearch性能监控(一)>,介绍了两个领域的ES监测指标:查询和索引(indexing)性能和内存分配和垃圾回收:本期我们将继续讲解另外三类监测 ...

  2. Elasticsearch 性能监控2(五种常见问题的解决办法)

    前言:本文为es性能监控基础的扩展,大家可以先看下性能监控基础,熟悉下es的基本原理.为翻译性质文档,感谢原作者.原始文档 类似于汽车的运行方式,Elasticsearch旨在让用户快速上手和运行,而 ...

  3. 【全观测系列】Elasticsearch应用性能监控实践

    简介:本文介绍了应用性能监控的应用价值以及解决方案等. 1.什么是全观测? 要了解全观测,我们先看看传统运维存在哪些问题. 数据孤岛,分散在不同部门,分析排查故障困难: 多个厂商的多种工具,无法自动化 ...

  4. 最牛逼的性能监控系统!集强大功能于一身

    点击关注公众号,Java干货及时送达 SkyWalking 是一个应用性能监控系统,特别为微服务.云原生和基于容器(Docker, Kubernetes, Mesos)体系结构而设计.除了应用指标监控 ...

  5. ElasticSearch性能优化策略【转】

    ElasticSearch性能优化主要分为4个方面的优化. 一.服务器部署 二.服务器配置 三.数据结构优化 四.运行期优化 一.服务器部署 1.增加1-2台服务器,用于负载均衡节点 elasticS ...

  6. .NetCore使用skywalking实现实时性能监控

    一.简介 很久之前写了一篇 <.Net Core 2.0+ InfluxDB+Grafana+App Metrics 实现跨平台的实时性能监控>关于NetCore性能监控的文章,使用Inf ...

  7. AspNet Core下利用 app-metrics+Grafana + InfluxDB实现高大上的性能监控界面

    在日常系统工作中,我们为了洞察系统的问题和运作情况通常会记录日志的方式来进行分析,但是在很多情况下都是被动的在出问题后才会去查日志.在很多时候,我们可能更需要相对实时的了解整个系统或者某一时段的运行的 ...

  8. Apache SkyWalking 为.NET Core带来开箱即用的分布式追踪和应用性能监控

    在大型网站系统设计中,随着分布式架构,特别是微服务架构的流行,我们将系统解耦成更小的单元,通过不断的添加新的.小的模块或者重用已经有的模块来构建复杂的系统.随着模块的不断增多,一次请求可能会涉及到十几 ...

  9. 开源java性能分析工具_Java性能监控:您应该知道的5个开源工具

    开源java性能分析工具 鲜为人知但有用:开源应用程序性能监视的状态 对于任何应用程序来说,最重要的事情之一就是性能. 我们要确保用户获得他们能获得的最佳体验,并想知道我们的应用已启动并正在运行. 这 ...

最新文章

  1. Android Studio第三十四期 - git企业级应用命令
  2. 如何降低在 npm 模块中发布敏感信息的可能性
  3. CWDM/DWDM是城域网最好的选择吗?
  4. 在ubuntu 中如何保存及播放DVD
  5. 电脑编程python老是出现错误_python常见的编程错误
  6. 平面海报设计素材|几何风格极简流行风,继续
  7. 背景固定,内容滑动效果 - 仿QQ下载首页
  8. KindleDrip:从邮件地址到信用卡盗刷的严重漏洞,值$1.8万奖金
  9. 集成产品开发团队的组成
  10. FPGA笔试数电部分(一)
  11. Android 学习 Android应用的两种架构
  12. ACCESS数据库注入解析
  13. 空号检测(电话号码状态实时分析)freeswitch模块
  14. jquery api中文手册
  15. Please either set ERLANG_HOME to point to your Erlang installation or place
  16. k8s集群安装traefik 2.x (保证成功版)
  17. react-redux多reducer完整实例
  18. Docker基础笔记
  19. sprintf() 用法
  20. 在腾讯实习的五个月的一些思考与收获

热门文章

  1. 工作站的windows server 2008 终于安装好了
  2. Android学习之调用系统相机实现拍照功能
  3. Linux crontab
  4. idea卸载删除旧版重新安装新版后,新版本idea程序打不开闪退的解决方案
  5. 解决Ubuntu18.04 No wifi adapter found
  6. ES5(三)——数组新增函数every()、some()、map()、foreach()、filter()和reduce()汇总
  7. enspar启动失败40_法式长棍面包,在家自己做,简单零失败,低糖无油不担心长胖...
  8. OSChina 周日乱弹 —— 七哥的北漂日记
  9. 越努力越幸运--动态数组vector
  10. Battle Encoder Shirase一款能限制进程CPU占有率的小东西