Elasticsearch 性能监控(二)

阅读数:47 2019 年 11 月 27 日 22:58

Elasticsearch性能监控(二)

上一期我们分享了《Elasticsearch 性能监控(一)》,介绍了两个领域的 ES 监测指标:查询和索引(indexing)性能和内存分配和垃圾回收;本期我们将继续讲解另外三类监测指标:主机级别的系统和网络指标、指标集群健康状态和节点可用性、资源饱和度和相关错误。

本文是 Emily Chang 的分享《How to monitor Elasticsearch performance》中文译文的第一部分。

前期回顾

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

  1. 查询和索引(indexing)性能
  2. 内存分配和垃圾回收
  3. 主机级别的系统和网络指标
  4. 集群健康状态和节点可用性
  5. 资源饱和度和相关错误

上期我们分享了前两个领域的检测指标,本期我们将继续分享后三个领域的监测指标。

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

尽管 Elasticsearch 提供了很多程序定制的参数指标,但您也应该从各个节点收集和监控主机级别的指标。

Elasticsearch性能监控(二)

磁盘空间

如果您的 Elasticsearch 集群是写负载型的,那么这个指标将变得更加重要。因为一旦空间不足,您将不能进行任何插入和更新操作,节点也会下线,这应该是您不想看到的。如果节点的可用空间小于 20%,您应该利用类似 Curator 这样的工具,删除一些占用空间较大的索引来释放部分空间。

如果业务逻辑上不允许删除索引,那么另一种方案就是扩容更多的节点,让 Master 在新节点间重新分配分片(尽管这样会增加 Master 节点的负载)。

另外需要记住一点,包含需要分析(analyzed)的字段的文档占用的磁盘空间比那些不需要分析(non-analyzed)的字段(精确值)的文档要多得多。

I / O 利用率

当 segment 被创建、查询和合并时,Elasticsearch 会进行大量的磁盘读写操作。 对于具有不断经历大量 I/O 活动的节点的写负载集群,Elasticsearch 建议使用 SSD 来提高性能。

CPU 利用率

利用图示来展示不同节点类型的 CPU 使用情况会很有帮助。例如,可以创建三个不同的图来表示群集中的不同节点类型(例如 Data 节点,Master 节点和 Client 节点)的 CPU 使用情况,通过对比图示来发现是否某一种类型的节点过载了。如果您看到 CPU 使用率增加,这通常是由于大量的搜索或索引工作造成的负载。设置一个通知,以确定您的节点的 CPU 使用率是否持续增长,并根据需要添加更多的节点来重新分配负载。

网络吞吐量

节点之间的通信是衡量群集是否平衡的关键组成部分。 您需要监视网络以确保网络正常运行,并且能够跟上群集的需求(例如,在节点间复制或分片的重新分配)。 Elasticsearch 提供有关集群节点间通信的传输指标,但是您也可以通过发送和接收的字节速率,来查看您的网络正在接收多少流量。

打开的文件描述符

文件描述符用于节点间的通信、客户端连接和文件操作。

如果打开的文件描述符达到你的系统的限制,那么新的连接和文件操作将不可用,直到有旧的被关闭。 如果超过 80%的可用文件描述符正在使用中,则可能需要增加系统的最大文件描述符计数。 大多数 Linux 系统限制每个进程中只允许有 1024 个文件描述符。 在生产中使用 Elasticsearch 时,应该将操作系统文件描述符数量设置为更大的值,例如 64,000。

HTTP 连接

Elasticsearch性能监控(二)

除了 Java Client 以外的任何语言发送的请求都将使用基于 HTTP 的 RESTful API 与 Elasticsearch 进行通信。 如果打开的 HTTP 连接总数不断增加,则可能表明您的 HTTP 客户端没有正确建立持久化连接。 重新建立连接会在请求响应时间内增加额外的时间开销。 因此务必确保您的客户端配置正确,以避免对性能造成影响,或者使用已正确配置 HTTP 连接的官方 Elasticsearch 客户端之一。

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

Elasticsearch性能监控(二)

集群健康状态

如果集群状态为 YELLOW,说明至少有一个副本分片未分配或者丢失。尽管这个时候搜索结果仍然是完整的,但是如果更多的分片消失的话,有可能造成整个索引的数据丢失。

如果集群状态为 RED,则表示至少有一个主分片丢失,索引缺少数据,这意味着搜索将返回部分结果,而且新的文档数据也无法索引到该分片。您可以考虑设置一个告警,如果状态为黄色超过 5 分钟,或者上次检测状态为红色,则触发警报。

初始化(initializing)和未分配(unassigned)状态的分片

当索引首次创建或者节点重新启动时,由于 Master 节点试图将分片分配给 Data 节点,所以在转换为“started”或“unassigned”状态之前,该分片将暂时处于“initializing”状态。 如果您看到分片处于初始化状态或未分配状态的时间过长,则可能是群集不稳定的信号。

资源饱和度和相关错误

Elasticsearch 节点使用线程池来管理线程对内存和 CPU 使用。

由于线程池是根据处理器的核数自动配置的,因此调整它们通常是没有意义的。 但是通过请求队列和请求被拒绝的情况,来确定你的节点是否够用是一个不错的主意。如果出现了状况,您可能需要添加更多的节点来处理所有的并发请求。

fielddata 和 filter cache 的使用是另一个需要监控的领域,因为 cache 的置换可能预示了效率低下的查询或内存压力的迹象。

线程池的请求队列(queues)和拒绝情况(rejections)

每个 Elasticsearch 节点都维护着很多类型的线程池。具体应该监控哪些线程池,需要根据 Elasticsearch 的使用场景而定。一般来讲,最重要的几个线程池是搜索(search),索引(index),合并(merger)和批处理(bulk)。

每个线程池队列的大小代表着当前节点有多少请求正在等待服务。 队列的作用是允许节点追踪并最终处理这些请求,而不是直接丢弃它们。但是线程池队列不是无限扩展的(队列越大占用的内存越多),一旦线程池达到最大队列大小(不同类型的线程池的默认值不一样),后面的请求都会被线程池拒绝。

如下图是需要关注的线程池指标

Elasticsearch性能监控(二)

线程池队列

线程池队列并不是越大越好,因为线程池越大占用的资源越多,并且增大了节点宕机时请求丢失的风险。 如果您看到排队和拒绝的线程数量持续增加,则需要尝试减慢请求速率、增加节点上的处理器数量或增加集群中的节点数量。

如下图所示,查询访问尖峰与搜索线程池队列大小中的尖峰是吻合的。

Elasticsearch性能监控(二)

批处理(bulk)的请求队列和请求拒绝

批处理是同时发送多个请求的更有效方式。 通常如果要执行许多操作(创建索引,或者添加,更新或删除文档),则应尝试将请求作为批处理发送,而不是多个单独的请求。批处理请求被拒绝通常与试图在一个批处理请求中索引太多文档有关。虽然据 Elasticsearch 的文档所说,出现批处理请求被拒绝的情况,不一定是必须要担心的事情,但是您应该尝试实施一些退避策略,以有效处理这种情况。

缓存使用相关指标

在 Elasticsearch 中,每个查询请求都被发送到索引中的每个分片,然后分别扫描这些分片中的每个段(segment)。 Elasticsearch 以每个段为基础缓存查询,以加快响应时间。

在 Elasticsearch 中,文档中的每个字段可以以两种形式存储:精确值或全文。 精确值(如时间戳或年份)的存储与其索引的方式完全相同,因为您不希望收到查询 1/1/16 为“2016 年 1 月 1 日”。如果字段以全文形式存储 ,这意味着它将被分析 - 基本上,它被分解成分词,根据分析器的类型,标点符号和停用词如“是”或“the”可能被删除。 分析器将字段转换为规范化的格式,使其能够匹配更广泛的查询。

看这样一个例子,假设您有一个类型(type)名为 location 的索引, location 的每个文档都包含一个字段 city,它被存储为经过分析(analyzed)的字符串。 你索引两个文档:一个在 city 字段包含“St. Louis”,另一个包含“St. Paul”。 每个字符串将被转成小写,并去掉标点符号,变成词项。 这些词项(terms)被存储在一个倒排索引里,看起来像这样:

Elasticsearch性能监控(二)

分析(analysis)的好处就是当你检索“st.”的时候,所有包含这个词项的文档都会被检索出来。如果您将 city 这个字段存储为精确值,只有检索“St. Louis”或者“St. Paul”这样的精确值,才能匹配到结果。

Elasticsearch 使用两种主要类型的缓存来更快地提供搜索请求:Fielddata 和 Filter。

Fielddata cache

Fielddata cache 主要用于字段(field)的排序和聚合,这是一个“转置”(uninvert)倒排索引并按照文档的索引顺序为每一个字段创建一个包含所有值的数组的过程。例如,如果我们想从上面的例子中找到任何包含“st”的文档中的唯一的词项列表,我们将

1. 扫描倒排索引以查看哪些文档包含该词项(在本例中为 Doc1 和 Doc2);
2. 对于步骤 1 中找到的每个文档,遍历索引中的每个词项来收集分词,从而创建如下图的结构;
3. 这个时候倒排索引就已经被“转置”了,并且从每个文档中提取出了唯一的分词(st,louis 和 paul)。 像这样编译字段数据会消耗大量的堆栈内存,特别是有大量的文档和词项需要处理的时候,因为所有的字段值都会被加载到内存中。

Elasticsearch性能监控(二)

对于 1.3 版本之前的 Elasticsearch,fielddata cache 大小是没有限制的。 从 1.3 版本开始,Elasticsearch 添加了一个 fielddata 断路器,如果查询试图加载需要占用 60%以上堆栈内存的 fielddata,则会触发该断路器。

Filter cache

Filter cache 也使用 JVM 堆栈,在 2.0 版本之前,Elasticsearch 自动缓存不超过堆栈内存 10% 容量的 filtered queries,并驱逐最近最少使用的数据。从 2.0 版本开始,Elasticsearch 根据 segment 大小(比如只缓存小于 10000 条文档的 segment)和检索频率(比如只缓存文档数小于索引总文档数 3% 的 segment)来自动优化 Filter cache 的使用。综上,filter cache 相关的指标只有在 Elasticsearch 2.0 版本之前可以使用。

举个例子,有一个过滤查询(filter query)要返回字段 year 的值落在 2000-2005 范围内的文档。在第一次执行过滤查询的过程中,Elasticsearch 将创建一个文档过滤规则是否匹配的数据结构(Bitset)(如果文档匹配则为 1,否则为 0)。之后使用相同过滤规则的查询将复用这些信息来辅助执行。无论何时添加或更新新文档,这个 Bitset 也都会被更新。如果您使用 2.0 之前的 Elasticsearch 版本,则应该注意 Filter 缓存以及驱逐指标。

下图是需要关注的缓存相关指标

Elasticsearch性能监控(二)

Fielddata cache 驱逐

理想情况下,您可能想限制 Fielddata 被驱逐的数量,因为它们是 I/O 密集型的。如果您看到大量的驱逐,并且目前无法增加内存,Elasticsearch 建议将 fielddata 缓存限制为堆栈内存的 20%(可以在 elasticsearch.yml 文件中配置)。当 fielddata 达到堆栈内存的 20%时,它将驱逐最近最少使用的 fielddata,然后允许您将新的 fielddata 加载到缓存中。

Elasticsearch 也建议尽可能使用 Doc Values,因为它们的用途与 fielddata 相同。但是,因为它们存储在磁盘上,所以不依赖于 JVM 堆栈。尽管 doc values 不能用于分析字符串字段,但是在其他类型的字段上进行聚合或排序时,它们确实节省了 fielddata 的使用。在版本 2.0 之后的版本中,doc values 在文档索引时自动创建,这大量减少了堆栈的占用。

Filter cache 驱逐

如前所述,Filter 缓存逐出指标只有在使用 2.0 之前的 Elasticsearch 版本时才可用。 每个 segment 都维护着自己的独立的 filter cache。 由于在大的 segement 上比小的 segment 驱逐数据成本要高很多,因此没有明确的方法来评估每一次驱逐影响的严重程度。 但是如果您发现驱逐出现得更频繁,这可能表示您没有有效的利用 filter——您可能只是频繁的创建新的 filter 并驱逐旧的 filter,以至于完全无法使用缓存。 您可能想要调整您的查询(例如,使用布尔查询而不是 and/or/not filter)。

挂起的任务(Pending tasks)

挂起的任务只能由 master 节点处理。这些任务包括创建索引并将分片分配给节点。挂起的任务按照优先级顺序处理——紧急优先,然后是高优先级的。当挂起的任务数量的变化值大于 master 节点处理速度时,他们便开始积累。如果这个指标持续增长的话,最好持续关注。 挂起的任务数量很好地反映了集群的运行情况。如果 master 节点已经非常繁忙,而挂起的任务还在持续增加,则可能导致群集不稳定。

Elasticsearch性能监控(二)

失败的 GET 请求

GET 请求比普通的搜索请求更直接——它根据 ID 检索文档。失败的 get-by-id 请求意味着没有找到对应的文档。您通常不会遇到这种类型的请求报错,但是在发生 GET 请求失败时关注一下还是有好处的。

Elasticsearch性能监控(二)

结论

通过两期文章,我们介绍了 Elasticsearch 的一些最重要的方面,以便在集群增长和扩展您的集群时进行监控:

  1. 查询和索引(indexing)性能
  2. 内存分配和垃圾回收
  3. 主机级别的系统和网络指标
  4. 集群健康状态和节点可用性
  5. 资源饱和度和相关错误

随着您监控 Elasticsearch 以及节点级别的系统指标,您将会发现哪些领域对于您的特定场景最有意义。

本文转载自公众号 360 云计算(ID:hulktalk)。

原文链接:

https://mp.weixin.qq.com/s/m1z-BBO1TZHJEJSiv8X_9A

评论

发布