第一部分 如何监测elasticsearch的性能?

本文翻译自网站https://www.datadoghq.com/blog/monitor-elasticsearch-performance-metrics/

一、什么是Elasticsearch?

    Elasticsearch是一个开源的分布式文档存储和搜索引擎,可以近实时的存储和检索数据结构。由Shay Banon 在2010年开发和编译,严重依赖由Java编写的全文搜索引擎Apache Lucene
    Elasticsearch用JSON文档的结构来描述数据,并通过RESTfull API和PHP、Python、Ruby等语言的web 客户端来进行全文搜索。Elasticsearch可以很简单的进行横向扩展–通过增加更多的节点来分配负载。目前,很多公司,包括Wikipedia, eBay, GitHub, and Datadog,均使用Elasticsearch来进行大量的动态数据分析。

Elasticsearch的元素

    在我们开始研究性能指标之前,让我们先解释一下Elasticsearch的工作原理。在Elasticsearch中,一个集群由1个或者多个节点组成,如下图所示:
在这里插入图片描述
    每个节点是一个独立运行的Elasticsearch实例,由elasticsearch.yml配置文件决定节点属于哪个集群(cluster.name)、节点是什么类型的节点(master主节点或者data数据节点,或者即是master节点也是data节点)。在这个配置文件中的任何属性也可以通过命令行参数指定。上图所示的集群由1个专用的主节点和5个数据节点。

    在Elasticsearch中最常见的三种节点如下:

Master-eligible nodes 候选主节点

    除非有其他的指定,默认每个节点均是候选主节点。每个集群自动从所有的候选主节点中选举出一个主节点。在当前主节点挂了(如断电、硬件故障、内存溢出错误等)之后,集群会从候选主节点中选举出一个新的主节点。主节点负责协调集群任务,如跨节点分配分片、创建和删除索引。任何候选主节点同时也可以充当数据节点。尽管如此,在大部分集群中,为了提高集群的可靠性,用户可能会启动一个不存储数据的专用主节点(通过在配置文件中添加配置项node.data: false)。在高可用的环境中,将主节点角色从数据节点中分离开可以帮助保证集群中总是有足够的资源分配给只能由主节点处理的任务。

Data nodes 数据节点

    默认的,每个节点都是数据节点,数据节点以分片的形式存储数据(关于分片的更多信息见下一章节),执行与索引、搜索和聚合数据相关的操作。在大部分集群中,可以选择通过在配置文件中添加配置项node.master: false来创建一个专用的数据节点,没有与集群相关的管理任务的额外工作负载,可以保证这些节点具有足够的资源来处理数据相关的请求。

Client nodes 客户端节点

    如果设置node.master 和 node.data为false,就可以启动为一个客户端节点。客户端节点设计用于充当负载均衡器,帮助路由索引和搜索请求。客户端节点帮助分担检索压力,这样数据节点和候选主节点就可以专注于它们的核心任务中。根据使用场景,客户端节点可能不是必须的,因为数据节点也可以自己处理请求路由。尽管如此,当搜索/索引的负载很严重的时候在集群中增加客户端节点来帮助路由请求是非常有意义的

Elasticsearch是如何组织数据的?

    在Elasticsearch中,相关的数据经常放在同一个索引(index)中,索引可以被看作是配置的逻辑包装器。每个索引包含一组JSON格式的相关文档。Elasticsearch全文索引的秘诀是Lucene的倒排索引。当一个文档被索引,Elasticsearch自动为每个字段创建倒排索引,倒排索引将关键字映射到包含这些关键字的文档中。
    每个索引存储在1个或者多个主分片,0个或者多个副本分片上。每个分片都是Lucene的一个完整实例,就像一个迷你搜索引擎。
在这里插入图片描述

    当我们创建一个索引的时候,我们可以指定主分片数和副本数。每个索引的主分片数默认是5,副本数默认是1.索引创建完成之后,主分片数不能更改,所以在创建索引的时候要谨慎选择主分片数。副本数在索引创建之后可以根据需要进行更改。为保护数据不丢失,主节点会保证每个副本分片不会和主分片分配在同一个节点上。

二、 Elasticsearch关键性能监测指标

在这里插入图片描述

    Elasticsearch提供了大量可以帮助你发现故障迹象的指标,当你遇到节点不可用、内存溢出错误、长时间GC的问题时,可以采取相应措施。需要监测的几个关键点如下:

  • 搜索(查询数据)/索引(插入更新数据)性能
  • 内存和gc
  • 服务器和网络指标
  • 集群健康状态和节点可用性
  • 资源饱和情况和错误

    所有这些指标均可以通过Elasticsearch的API、单一用途的监测工具如Elastic’s Marvel或者通用监控服务Datadog来获取。更多的关于怎么收集这些指标的方法,详见第二部分

2.1 搜索性能指标Search performance metrics

搜索请求是Elasticsearch中两个主要请求之一,另一个是索引请求。这两个请求分别有点类似于传统数据库系统的读请求和写请求。Elasticsearch提供的指标与搜索过程的两个主要阶段相对应(query和fetch)。如下图展示了搜索请求从开始到结束的过程。
在这里插入图片描述

1、客户端发送一个搜索请求到节点2
在这里插入图片描述

2、节点2(协调节点)将查询发送到索引中的每个分片的副本(副本或主分片)上。

例如,索引a分片数为3,副本数为1,相当于3个分片分别有1个副本,其中一个主分片,一个是副本,那么一共有3+3=6个分片,请求只会发给每个分片的主分片或者副本中的一个,就是发出的是3个请求,而不是6个请求。

如上图所示,对于分片0来说,存有两份数据P0和R0,如果请求发给了R0,就不会再发送给P0。

在这里插入图片描述

3、每个分片在本地执行查询并将结果交付给节点2。节点2将它们排序并编译成全局优先队列。
在这里插入图片描述

4、节点2发现需要获取哪些文档,并向相关分片发送多GET请求。
在这里插入图片描述

5、每个分片下载文档并将其返回给节点2
在这里插入图片描述

6、节点2向客户端交付搜索结果。

    如果你是用Elasticsearch主要是用于搜索,或者搜索是对你的公司很关键的面向客户特色,你应该监视查询延迟,并在超过阈值时采取行动。监测有关查询(query)和获取(fetch)的相关指标非常重要,这些指标可以帮助确定搜索在一段时间内的执行情况。例如,你可能希望跟踪查询请求的峰值和长期增长请客,以便可以调整配置以优化性能和可靠性。

指标描述 名称 指标类型
Total number of queries indices.search.query_total Work: Throughput
Total time spent on queries indices.search.query_time_in_millis Work: Performance
Number of queries currently in progress 当前正在进行的查询数量 indices.search.query_current Work: Throughput
Total number of fetches indices.search.fetch_total Work: Throughput
Total time spent on fetches indices.search.fetch_time_in_millis Work: Performance
Number of fetches currently in progress indices.search.fetch_current Work: Throughput

搜索要观察的性能指标

查询负载
    监视“当前正在进行的查询数量”可以让您大致了解集群在任何特定时刻正在处理多少请求。考虑在出现不寻常的尖峰或尖峰可能指向潜在的问题时发出警报。你可能还希望监视搜索线程池队列的大小,我们将在本文后面详细解释这一点。

查询延迟
    尽管Elasticsearch没有明确地提供这个指标,但是监视工具可以帮助你使用可用的指标,通过定期采样查询总数和总运行时间来计算平均查询延迟。如果延迟超过阈值,则设置警报,如果触发警报,则查找潜在的资源瓶颈,或调查是否需要优化查询。

获取延迟
    搜索过程的第二部分,即获取阶段,通常比查询阶段花费的时间要少得多。如果你注意到这个指标持续增加,这可能表明磁盘速度缓慢、文档内容丰富(在搜索结果中突出显示相关文本等)或请求太多文档。

2.2 索引的性能指标

    索引请求类似于传统数据库系统中的写请求,如果你的Elasticsearch工作负载很大,那么重要的是要监视和分析你如何有效地使用新信息更新索引。在讨论指标之前,我们先来看看Elasticsearch更新索引的过程。当向索引中添加新信息或更新或删除现有信息时,通过两个过程更新索引中的每个分片:refresh和fresh。

索引refresh

    新索引的文档不能立即用于搜索。首先,它们被写入内存缓冲区,等待下一次索引refresh,默认情况下每秒refresh一次。refresh进程从内存缓冲区的内容中创建一个新的内存段(使新索引的文档可搜索),然后清空缓冲区,如下所示:
在这里插入图片描述
索引refresh的过程
    索引的分片由多个段组成。段是Lucene的核心数据结构,一个段本质上是索引的变更集。这些段在每次refresh时创建,然后在后台随着时间的推移合并在一起,以确保资源的有效使用(每个段使用文件句柄、内存和CPU)。
    段是将关键字映射到包含这些关键字的文档的迷你倒排索引。每次搜索索引时,每个分片的主版本或副本版本都必须依次搜索该分片中的每个段。
    段是不可变的,所以更新文档意味着:

  • 在刷新过程中将信息写入新段
  • 将旧信息标记为已删除

当过时的段与另一个段合并时,旧的信息最终会被删除。

索引flush

    在新索引的文档被添加到内存缓冲区中的同时,它们也被添加到分片的translog中:一个持久的、预写的操作事务日志。每30分钟,或者当translog达到最大大小(默认值为512MB)时,就会触发flush。在flush期间,内存缓冲区中的所有文档都被刷新(存储在新段上),所有在内存缓冲区中的段都被提交到磁盘,translog被清除。
    translog有助于防止节点失败时的数据丢失。它的设计目的是帮助分片恢复可能在刷新之间丢失的操作。日志每5秒钟提交一次到磁盘,或者在每次成功的索引、删除、更新或批量请求(无论哪个先出现)时提交。
    flush过程如下图所示:
在这里插入图片描述
索引flush的过程
    Elasticsearch提供了许多指标,你可以使用这些指标来评估索引性能并优化更新索引的方式。

指标描述 名称 指标类型
Total number of documents indexed indices.indexing.index_total Work: Throughput
Total time spent indexing documents indices.indexing.index_time_in_millis Work: Performance
Number of documents currently being indexed indices.indexing.index_current Work: Throughput
Total number of index refreshes indices.refresh.total Work: Throughput
Total time spent refreshing indices indices.refresh.total_time_in_millis Work: Performance
Total number of index flushes to disk indices.flush.total Work: Throughput
Total time spent on flushing indices to disk indices.flush.total_time_in_millis Work: Performance

索引要监视的性能指标

索引延迟
    Elasticsearch并不直接提供这个特定的指标,但是监视工具可以帮助我们从可用的index_total和index_time_in_millis指标计算平均索引延迟。如果你注意到延迟的增加,那么你可能一次索引了太多的文档(Elasticsearch的文档建议从5到15 mb的批量索引大小开始,然后慢慢增加)。
    如果你计划对许多文档进行索引,并且不需要立即获得新的信息来进行搜索,那么可以通过减少刷新频率来优化索引性能而不是搜索性能,直到完成索引为止。索引设置API允许您临时禁用刷新间隔:

curl -XPUT <nameofhost>:9200/<name_of_index>/_settings -d '{ "index" : { "refresh_interval" : "-1" } }'

    索引完成后,可以恢复到“1”的默认值。本系列的第4部分将更详细地介绍这个和其他索引性能技巧。
Flush延迟
    因为在刷新成功完成之前,数据不会持久化到磁盘中,所以如果性能开始下降,跟踪刷新延迟并采取行动是很有用的。如果你看到这个指标稳步增长,它可能表明磁盘速度慢的问题;这个问题可能会升级,最终会阻止您向索引中添加新信息。您可以尝试在索引的刷新设置中降低index.translog.flush_threshold_size。这个设置决定触发flush之前的translog大小。但是,如果你是写操作密集的Elasticsearch用户,你应该使用iostat或Datadog代理之类的工具来长期监视磁盘IO指标,并在需要时考虑升级磁盘。

2.3 内存使用和GC垃圾回收

    运行Elasticsearch时,内存是我们最想密切监测的主要资源之一。Elasticsearch和Lucene以两种方式利用节点上所有可用的RAM:JVM堆和文件系统缓存。Elasticsearch在Java虚拟机(JVM)中运行,这意味着JVM垃圾收集的持续时间和频率将是另一个需要监视的重要领域。

JVM堆:一个金发女孩的故事

        Elasticsearch强调JVM堆大小“刚刚好”的重要性,不希望将它设置得太大或太小。一般来说,Elasticsearch的经验法则是分配给JVM堆内存要不能大于可用RAM的50%,并且永远不会超过32gb。
        为Elasticsearch分配的堆内存越少,Lucene就可以使用越多的RAM,它严重依赖于文件系统缓存来快速服务请求。但是,你也不希望将堆大小设置得太小,因为你可能会遇到内存不足的错误或吞吐量降低的问题,因为应用程序会面临频繁的垃圾回收(GC)造成的持续的短时间停顿。请参考Elasticsearch的一位核心工程师编写的指南,以找到确定正确堆大小的提示。
        Elasticsearch的默认安装设置的JVM堆大小为1g,对于大多数用例来说太小了。可以export想要的堆大小作为环境变量,并重新启动Elasticsearch:

  $ export ES_HEAP_SIZE=10g

        另一个选项是在每次启动Elasticsearch时在命令行中设置JVM堆大小(大小相等,以防止堆大小调整):

$ ES_HEAP_SIZE="10g" ./bin/elasticsearch 

        在两个示例中,我们都将堆大小设置为10gb。要验证更新成功,运行:

 $ curl -XGET http://<nameofhost>:9200/_cat/nodes?h=heap.max

输出应该显示正确更新的最大堆值。

GC

        Elasticsearch依赖于垃圾回收进程来释放堆内存。如果您想了解更多关于JVM垃圾收集的知识,请参阅本指南
        因为垃圾回收使用资源(为了释放资源!),所以你应该关注它的频率和持续时间,看看是否需要调整堆大小。设置堆太大会导致垃圾收集时间过长;这些过多的停顿是危险的,因为它们可能导致集群错误地将节点注册为已从网格中删除的节点,就是认为节点已经挂了。

指标描述 名称 指标类型
Total count of young-generation garbage collections jvm.gc.collectors.young.collection_count (jvm.gc.collectors.ParNew.collection_count prior to vers. 0.90.10) Other
Total time spent on young-generation garbage collections jvm.gc.collectors.young.collection_time_in_millis (jvm.gc.collectors.ParNew.collection_time_in_millis prior to vers. 0.90.10) Other
Total count of old-generation garbage collections jvm.gc.collectors.old.collection_count (jvm.gc.collectors.ConcurrentMarkSweep.collection_count prior to vers. 0.90.10) Other
Total time spent on old-generation garbage collections jvm.gc.collectors.old.collection_time_in_millis (jvm.gc.collectors.ConcurrentMarkSweep.collection_time_in_millis prior to vers. 0.90.10) Other
Percent of JVM heap currently in use jvm.mem.heap_used_percent Resource: Utilization
Amount of JVM heap committed jvm.mem.heap_committed_in_bytes Resource: Utilization

要观察的JVM指标

在这里插入图片描述

使用中的JVM堆:
        当JVM堆使用率达到75%时,Elasticsearch将启动垃圾回收。如上所示,监视哪个节点显示了较高的堆使用率,并设置一个警报,以查明任何节点是否一直地使用了超过85%的堆内存,这可能是有用的;这表明垃圾回收的速度赶不上垃圾创建的速度。要解决这个问题,您可以增加堆大小(只要它仍然低于上面所述的推荐准则),或者通过添加更多节点来扩展集群。
使用的JVM堆与提交的JVM堆:
        与提交的内存(保证可用的内存)相比,了解JVM堆当前使用了多少内存是很有帮助的。在使用中的堆内存数量通常会呈现锯齿状,当垃圾累积时,这种情况会上升,当垃圾回收时,这种情况会下降。如果曲线随着时间的推移开始向上倾斜,这意味着垃圾回收的速度赶不上对象创建的速度,这会导致垃圾收集时间变慢,最终导致OutOfMemoryErrors。
垃圾收集的持续时间和频率:
        新生代和年老代的垃圾回收器都会经历“停止所有”的阶段,因为JVM会暂停程序的执行,以收集死对象。在此期间,节点无法完成任何任务。因为主节点每隔30秒检查其他节点的状态,如果任何节点的垃圾收集时间超过30秒,主节点就会认为节点挂了。

内存使用

        如上所述,Elasticsearch很好地利用了任何没有分配给JVM堆的RAM。与Kafka一样,Elasticsearch的设计依赖于操作系统的文件系统缓存来快速可靠地服务请求。
        许多变量决定Elasticsearch是否能从文件系统缓存中成功读取。如果段文件是最近通过Elasticsearch写入磁盘的,那么它已经在缓存中了。但是,如果节点已被关闭并重启,那么第一次查询段时,很可能必须从磁盘读取信息。这是确保集群保持稳定和节点不会崩溃的重要原因之一。
        通常,监控节点上的内存使用情况非常重要,并尽可能多地提供给Elasticsearch,这样它就可以利用文件系统缓存的速度,而不会耗尽空间。

2.4 主机级网络和系统指标

Name Metric type
Available disk space Resource: Utilization
I/O utilization Resource: Utilization
CPU usage Resource: Utilization
Network bytes sent/received Resource: Utilization
Open file descriptors Resource: Utilization

        当Elasticsearch通过API提供许多特定于应用程序的指标时,您还应该从每个节点收集和监视几个主机级指标。

要警告的主机指标

磁盘空间:
        如果Elasticsearch集群的写操作很频繁,那么这个指标就特别重要。你不希望耗尽磁盘空间,如此将会无法插入或更新任何内容,而且节点将失败。如果一个节点上可用的磁盘少于20%,您可能希望使用Curator之类的工具删除该节点上占用太多宝贵磁盘空间的某些索引。
        如果不能删除索引,另一种选择是添加更多节点,并让主节点自动在新节点之间重新分配分片(尽管您应该注意到这为繁忙的主节点创建了额外的工作)。另外,要记住,带有分析字段(需要文本分析的字段——标记、删除标点符号等)的文档要比包含非分析字段(精确值)的文档占用更多的磁盘空间。

要监视的主机指标

I/O利用率:
        随着段的创建、查询和合并,Elasticsearch对磁盘进行大量的读写操作。对于具有不断经历大量I/O活动的节点的写密集型集群,Elasticsearch建议使用ssd来提高性能。

在这里插入图片描述
节点上的CPU利用率:
        对于每个节点类型,在热图中可视化CPU使用情况(如上面所示)是很有帮助的。例如,您可以创建三个不同的图来表示集群中的每一组节点(例如数据节点、master- qualified节点和客户机节点),以查看一种类型的节点是否在与另一种节点相比的活动中过载。如果您看到CPU使用量增加,这通常是由繁重的搜索或索引工作负载引起的。设置一个通知,以确定节点的CPU使用率是否一直在增加,并添加更多的节点以重新分配负载。
网络字节发送/接收:
        节点间的通信是平衡集群的关键组成部分。你需要监视网络,以确保它是健康的,并且能够满足集群的需求(例如,在节点之间复制或重新平衡分片)。Elasticsearch提供了关于集群通信的传输度量,但是你还可以查看发送和接收的字节数,以查看你的网络正在接收多少流量。
打开的文件描述符:
        文件描述符用于节点到节点通信、客户端连接和文件操作。如果这个数字达到了系统的最大容量,那么新的连接和文件操作在旧的连接关闭之前是不可能的。如果超过80%的可用文件描述符在使用中,您可能需要增加系统的最大文件描述符计数。大多数Linux系统每个进程只允许1024个文件描述符。当在生产环境中使用Elasticsearch时,您应该将OS文件描述符计数重置为更大的数,比如64000。

HTTP连接

指标描述 名称 指标类型
Number of HTTP connections currently open http.current_open Resource: Utilization
Total number of HTTP connections opened over time http.total_opened Resource: Utilization

        除了Java之外,任何语言发送的请求都可以通过HTTP使用RESTful API与Elasticsearch通信。如果打开的HTTP连接的总数不断增加,这可能表明HTTP客户端没有正确地建立持久连接。重新建立连接会增加额外的毫秒甚至秒的请求响应时间。确保正确地配置了客户端以避免对性能产生负面影响,或者使用官方的Elasticsearch客户端,它已经正确地配置了HTTP连接。

2.5 集群健康和节点可用性

指标描述 名称 指标类型
Cluster status (green, yellow, red) cluster.health.status Other
Number of nodes cluster.health.number_of_nodes Resource: Availability
Number of initializing shards cluster.health.initializing_shards Resource: Availability
Number of unassigned shards cluster.health.unassigned_shards Resource: Availability

集群状态:
        如果集群状态为黄色,则至少有一个副本分片未分配或丢失。搜索结果仍然完整,但如果更多的分片消失,可能会丢失数据。
初始化和未分配分片:
        第一次创建索引或重启节点时,其分片将在转换到“已启动”或“未分配”状态之前短暂地处于“初始化”状态,因为主节点试图将分片分配给集群中的节点。如果分片停留在初始化或未分配的状态太长,这可能是集群不稳定的警告信号。

2.6 资源饱和和错误

        Elasticsearch节点使用线程池来管理线程如何消耗内存和CPU。由于线程池设置是根据处理器数量自动配置的,因此调整它们通常没有意义。但是,最好关注线程池队列和拒绝,看看节点是否跟不上;如果是这样,可能需要添加更多节点来处理所有并发请求。字段数据和过滤缓存的使用是另一个需要监视的领域,因为退出可能指向低效的查询或内存压力的迹象。

线程池队列和拒绝

        每个节点维护许多类型的线程池;你想要监视的精确值将取决于你对Elasticsearch的特定使用。通常,要监视的最重要的操作是搜索、索引、合并和批量,这与请求类型(搜索、索引、合并和批量操作)对应。

        每个线程池的队列的大小表示节点当前处于可用状态时等待服务的请求数量。队列允许节点跟踪并最终服务于这些请求,而不是丢弃它们。一旦达到线程池的最大队列大小(根据线程池的类型而变化),就会出现线程池拒绝。

指标描述 名称 指标类型
Number of queued threads in a thread pool thread_pool.bulk.queue thread_pool.index.queue thread_pool.search.queue thread_pool.merge.queue Resource: Saturation
Number of rejected threads a thread pool thread_pool.bulk.rejected thread_pool.index.rejected thread_pool.search.rejected thread_pool.merge.rejected Resource: Error

需要监控的指标

线程池队列:
        大型队列并不理想,因为它们会耗尽资源,而且如果节点宕机,还会增加丢失请求的风险。如果您看到排队的线程和被拒绝的线程的数量在稳步增加,您可能希望尝试减慢请求速度(如果可能的话)、增加节点上的处理器数量或增加集群中的节点数量。如下面的截图所示,查询加载峰值与搜索线程池队列大小的峰值相关,因为节点试图跟上查询请求的速度。
在这里插入图片描述

批量拒绝和批量队列:
        批量操作是一次发送多个请求的更有效方式。通常,如果您想执行许多操作(创建索引,或添加、更新或删除文档),您应该尝试将请求作为批量操作发送,而不是作为多个单独的请求。
        批量拒绝通常与试图在一个批量请求中索引太多文档有关。根据Elasticsearch的文档,批量拒绝并不一定需要担心。但是,你应该尝试执行线性或指数回退策略,以有效地处理批量拒绝。

缓存使用指标

        每个查询请求被发送到索引中的每个分片,然后这些分片命中每个分片的每个段。Elasticsearch以每段为基础缓存查询,以加快响应时间。另一方面,如果缓存占用了太多的堆,它们可能会减慢速度而不是加快速度!
        在Elasticsearch中,文档中的每个字段可以以两种形式之一存储:精确值或全文。精确值,例如时间戳或一年,是按照索引的方式存储的,因为您不希望收到查询1/1/16的查询,比如“2016年1月1日”。如果一个字段存储为全文,这意味着它将被分析—基本上,它将被分解成词组,并且,根据分析器的类型,标点和停止词,如“是”或“the”可能被删除。分析器将字段转换为规范化格式,使其能够匹配更广泛的查询。
        例如,假设有一个索引,其中包含一个名为location的类型;类型location的每个文档都包含一个字段city,它被存储为一个分析字符串。你将索引两个文档:一个在city字段是“St. Louis” 另一个是 “St. Paul”.。每个字符串都将被小写化并转换为词组,且不使用标点符号。这些术语存储在一个倒排索引中,它看起来像这样:

Term Doc1 Doc2
st x x
louis x
paul x

        分析的好处是你可以搜索“st”。结果会显示,这两份文件都包含这个词。如果将city字段存储为精确值,则必须搜索精确的词“St. Louis”或者 “St. Paul”,以查看生成的文档。

        Elasticsearch使用两种主要类型的缓存更快地为搜索请求提供服务:字段数据(Fielddata )和过滤器(filter)。

Fielddata缓存
        Fielddata缓存是在对字段进行排序或聚合时使用的,这个过程基本上需要反转倒排索引,以按照文档顺序创建每个字段的每个字段值的数组。例如,如果我们想从上面的例子中找到任何包含“st”的文档中唯一的术语列表,我们将:
    1、扫描倒排索引以查看哪些文档包含该词(在本例中是Doc1和Doc2)
        2、对于步骤1中找到的每个文档,遍历索引中的每个词,从该文档收集词组,创建如下结构:

Doc Terms
Doc1 st, louis
Doc1 st, paul

    3、现在倒排索引已经“非倒排”,编译来自每个文档(st、louis和paul)的惟一词组。这样编译fielddata会消耗大量堆内存,尤其是使用大量文档和关键词时更是如此。所有字段值都加载到内存中。

    对于1.3之前的版本,字段数据缓存大小是无限制的。从1.3版开始,Elasticsearch添加了一个字段数据断路器,如果查询试图加载需要超过60%堆的字段数据,就会触发该断路器。
过滤器缓存
        过滤器缓存也使用JVM堆。在2.0之前的版本中,Elasticsearch会自动缓存筛选过的查询,其最大值为堆的10%,并清除最近最少使用的数据。从2.0版本开始,Elasticsearch就根据频率和段大小自动开始优化它的过滤缓存(缓存只发生在索引中文档总数少于10,000个或少于3%的段上)。因此,筛选缓存指标只对使用的是2.0版本之前的Elasticsearch用户可用。
        例如,过滤器查询只能返回年份字段中的值在2000-2005范围内的文档。在第一次执行过滤器查询时,Elasticsearch将创建与过滤器匹配的文档的位集(如果文档匹配,为1,如果不匹配,为0)。具有相同过滤器的查询的后续执行将重用此信息。每当添加或更新新文档时,位集也会被更新。如果你使用的是2.0之前版本的Elasticsearch,那么你应该关注过滤器缓存以及回收指标(下面将对此进行详细介绍)。

指标描述 名称 指标类型
Size of the fielddata cache (bytes) indices.fielddata.memory_size_in_bytes Resource: Utilization
Number of evictions from the fielddata cache indices.fielddata.evictions Resource: Saturation
Size of the filter cache (bytes) (only pre-version 2.x) indices.filter_cache.memory_size_in_bytes Resource: Utilization
Number of evictions from the filter cache (only pre-version 2.x) indices.filter_cache.evictions Resource: Saturation

要监视的缓存指标在这里插入图片描述

字段数据缓存收回:
        理想情况下,您希望限制字段数据收回的数量,因为它们是I/O密集型的。如果您看到了大量的收回,而此时又无法增加内存,Elasticsearch建议暂时将字段数据缓存限制在堆的20%;可以在config/elasticsearch.yml文件中这样。当fielddata达到堆的20%时,它将收回最近最少使用的fielddata,从而允许您将新的fielddata加载到缓存中。
        Elasticsearch还建议尽可能使用doc值,因为它们与字段数据的用途相同。但是,因为它们存储在磁盘上,所以它们不依赖于JVM堆。虽然doc值不能用作分析的字符串字段,但是在对其他类型的字段进行聚合或排序时,它们确实节省了字段数据的使用。在2.0或更高版本中,doc值在文档索引时自动构建,这减少了许多用户的字段数据/堆使用。但是,如果您使用的是1.0和2.0之间的版本,那么你也可以从这个特性中获益——只要记住启用它们即可。

过滤器缓存收回:
        如前所述,只有使用2.0之前的Elasticsearch的版本时,过滤器缓存收回指标才可用。每个段维护自己的过滤器缓存。由于大规模的收回行动比小规模的更昂贵,因此没有明确的方法来评估每次收回的严重程度。但是,如果您看到收回发生得更频繁,这可能表明腻并没有将过滤器用好——你可能只是频繁地创建新过滤器并将旧过滤器收回,甚至违背了使用缓存的目的。你可能需要考虑调整你的查询(如使用bool查询,而不是使用and or not 过滤器)

挂起任务

指标描述 名称 指标类型
Number of pending tasks pending_task_total Resource: Saturation
Number of urgent pending tasks pending_tasks_priority_urgent Resource: Saturation
Number of high-priority pending tasks pending_tasks_priority_high Resource: Saturation

        挂起的任务只能由主节点处理。这些任务包括创建索引和向节点分配分片。挂起的任务以优先级顺序处理——先来的,优先级最高。当更改的数量发生得比主程序处理它们的速度快时,它们就开始累积。如果这个指标持续增加,你就需要关注它。挂起任务的数量很好地显示了集群运行的平稳性。如果主节点非常繁忙,挂起的任务数量没有减少,则可能导致不稳定的集群。

不成功的GET请求

指标描述 名称 指标类型
Total number of GET requests where the document was missing indices.get.missing_total Work: Error
Total time spent on GET requests where the document was missing indices.get.missing_time_in_millis Work: Error

        GET请求比普通的搜索请求更直接——它根据文档的ID检索文档。对于这种类型的请求,您通常不会有什么问题,但是在出现未成功的GET请求时,最好注意一下。

结论

        在这篇文章中,我们介绍了对Elasticseach进行监控的一些重要方面:

  • 搜索(查询数据)/索引(插入更新数据)性能
  • 内存和gc
  • 服务器和网络指标
  • 集群健康状态和节点可用性
  • 资源饱和情况和错误

        当您监视Elasticsearch指标和节点级系统指标时,你就会发现哪些区域对您的特定场景最有意义。阅读本系列文章的第2部分,了解如何开始收集和可视化对您最重要的Elasticsearch指标。

猜你喜欢

转载自blog.csdn.net/liaoyanyunde/article/details/83276563