Elasticsearch 基础知识要点与性能监控

本文的来源是我翻译国外的一篇技术博客,感谢原做者Emily Chang,原文地址经过以下的知识,咱们能大体学到关于ES的一些基本知识,进而对elasticsearch的性能进行监控和调优

注意elasticsearch的版本不一样,此处的描述可能会有稍许误差html

1、Elasticsearch 是什么

Elasticsearch是一款用Java编写的开源分布式文档存储和搜索引擎,能够用于near real-time存储和数据检索。node

1. Elasticsearch简要组成

在开始探索性能指标以前,让咱们来看看Elasticsearch的工做原理,在elasticsearch中,集群由一个或者更多的节点组成,以下图:

每一个节点是Elasticsearch的单个运行实例,其“elasticsearch.yml”配置文件指定其所属的集群(“cluster.name”)以及它能够是什么类型的节点。 配置文件中设置的任何属性(包括集群名称)也能够经过命令行参数指定。 上图中的集群由一个专用主节点和五个数据节点组成。 三种最多见的es节点类型有:数据库

  • master备选节点
    默认状况下(不动配置),每一个节点均为master备选节点。每一个集群都会自动从全部master备选节点中选择一个成为master节点。在当前master节点遇到故障(例如停电,硬件故障或内存不足错误)的状况下,从新选举产生新的master节点。master节点负责协调集群任务,好比跨节点的shards分发、建立和删除索引等。
    master节点也能同时做为数据节点,但在比较大的集群中,master节点通常不存储数据(经过设置node.data : false 来设置),以提升可靠性。在高可用环境中,节点任务明确、分离能够保证任务单一可靠。(专人干专事)
  • data节点
    默认状况下(不动配置),每一个节点都是数据节点,以shards的形式存储数据并执行与索引,搜索和聚合数据相关的操做。
    在大集群中,咱们能够经过设置node.master : false来设置该节点为专用数据节点。确保这些节点具备足够的资源来处理与数据相关的请求,而不须要承担与集群相关的管理任务类的工做负载。缓存

  • client 节点
    若是将node.master 和node.data都设置为false。那么该节点就是一个client节点。该client节点被设计为负载均衡器的角色,以帮助路由索引和搜索请求。
    client节点有助于承担部分搜索工做量,以便数据和主节点节点能够专一于其核心任务。client节点并非必须的,由于数据节点可以本身处理请求路由。若是你的search/index workload比较重,能够在集群中配一个client节点。bash

2. Elasticsearch 如何组织数据

在es中,相关联的数据一般存储在相同的索引中,每一个索引包含一组JSON格式的相关联文档。Elasticsearch的全文搜索秘诀是Lucene的倒排索引。在索引(存入)数据的时候,es会自动为每一个字段建立一个倒排索引,倒排索引将索引的词(terms)映射(map)到包含该词的文档(document)中。index被存储在一个或多个主副shard中,每一个shard都是一个完整的Lucenes实例,是一个完整的迷你搜索引擎
网络

建立索引时,能够指定主分片的数量以及每一个主节点的副本数,默认为五个分片和一个副本。索引建立后,分片数不能被修改。若是要修改可能须要reindex。副本数能够在后期被修改。 为了防止数据丢失,主节点的调度机制会确保主副分片不会出如今同一个数据节点上。并发

2、咱们要监控哪些Elasticsearch metric

Elasticsearch提供了大量的Metric,能够帮助您检测到问题的迹象,在遇到节点不可用、out-of-memory、long garbage collection times的时候采起相应措施。 一些关键的检测以下:负载均衡

  • Search and indexing performance(搜索、索引性能)
  • Memory and garbage collection
  • Host-level system and network metrics
  • Cluster health and node availability
  • Resource saturation(饱和) and errors

这里提供了一个metric搜集和监控的框架 Monitoring 101 series ,全部这些指标均可以经过Elasticsearch的API以及Elasticsearch的Marvel和Datadog等通用监控工具访问。框架

1. 搜索性能指标

搜索请求是Elasticsearch中的两个主要请求类型之一,另外一个是索引请求。 这些请求有时相似于传统数据库系统中的读写请求。 Elasticsearch提供与搜索过程的两个主要阶段(查询和获取)相对应的度量。 下图显示了从开始到结束的搜索请求的路径curl

  • step1. 客户端向Node 2 发送搜索请求

  • step2. Node 2(此时客串协调角色)将查询请求发送到索引中的每个分片的副本

  • step3. 每一个分片(Lucene实例,迷你搜素引擎)在本地执行查询,而后将结果交给Node 2。Node 2 sorts and compiles them into a global priority queue.

  • step4. Node 2发现须要获取哪些文档,并向相关的分片发送多个GET请求。

  • step5. 每一个分片loads documents而后将他们返回给Node 2

  • step6. Node 2将搜索结果交付给客户端

节点处理时,由谁分发,就由谁交付

若是您使用Elasticsearch主要用于搜索,或者若是搜索是面向客户的功能。您应该监视查询延迟和设定阈值。 监控关于查询和提取的相关指标很重要,能够帮助您肯定搜索随时间的变化。 例如,您可能但愿跟踪查询请求的尖峰和长期增加,以便您能够作好准备。

搜索性能指标的要点:

  • Query load: 监控当前正在进行的查询数量可让您了解群集在任何特定时刻处理的请求数量。您可能还想监视搜索线程池队列的大小,稍后咱们将在本文中进一步解释连接
  • Query latency: 虽然Elasticsearch没有明确提供此度量标准,但监控工具能够帮助您使用可用的指标来计算平均查询延迟,方法是以按期查询总查询次数和总通过时间。 若是延迟超过阈值,则设置警报,若是触发,请查找潜在的资源瓶颈,或调查是否须要优化查询。
  • Fetch latency:  搜索过程的第二部分,即提取阶段一般比查询阶段要少得多的时间。 若是您注意到这一指标不断增长,多是磁盘性能很差、highlighting影响、requesting too many results的缘由。

2. 索引性能指标

索引请求相似于传统数据库系统中的写入请求,若是es的写入工做量很重,那么监控和分析您可以如何有效地使用新数据更新索引很是重要。在了解指标以前,让咱们来探索Elasticsearch更新索引的过程,在新数据被添加进索引、更新或删除已有数据,索引中的每一个shard都有两个过程:refresh 和 flush Index fresh 新索引的文档不能立马被搜索的。 首先,它们被写入一个内存中的缓冲区(in-memory buffer),等待下一次索引刷新,默认状况下每秒一次。刷新是以in-memory buffer为基础建立in-memory segment的过程(The refresh process creates a new in-memory segment from the contents of the in-memory buffer )。这样索引进的文档才能是可被搜索的,建立完segment后,清空buffer 以下图:

A special segment on segments
索引由shards构成,shard又由不少segments组成,The core data structure from Lucene, a segment is essentially a change set for the index. 这些segments在每次刷新的时候被建立,随后会在后台进行合并,以确保资源的高效利用(每一个segment都要占file handles、memory、CPU) segments 是mini的倒排索引,这些倒排索引映射了terms到documents。每当搜索索引的时候,每一个主副shards都必须被遍历。更深一步说shards上的每一个segment会被依次搜索。 segment是不可变的,所以updating a document 意味着以下:

  • writing the information to a new segment during the refresh process
  • marking the old information as deleted

当多个outdated segment合并后才会被删除。(意思是不单个删除,合并后一块儿删)。

Index flush
在新索引的document添加到in-memory buffer的同时,它们也会被附加到分片的translog(a persistent, write-ahead transaction log of operations)中。 每隔30分钟,或者每当translog达到最大大小(默认状况下为512MB)时,将触发flush 。在flush 期间,在in-memory buffer上的documents会被refreshed(存到新的segments上),全部内存中的segments都提交到磁盘,而且translog被清空。 translog有助于防止节点发生故障时的数据丢失。 It is designed to help a shard recover operations that may otherwise have been lost between flushes. 这个translog每5秒将操做信息(索引,删除,更新或批量请求(以先到者为准))固化到磁盘上。

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

索引性能指标的要点:

  • Indexing latency: Elasticsearch不会直接公开此特定指标,可是监控工具能够帮助您从可用的index_total和index_time_in_millis指标计算平均索引延迟。 若是您注意到延迟增长,您可能会一次尝试索引太多的文档(Elasticsearch的文档建议从5到15兆字节的批量索引大小开始,并缓慢增长)。若是您计划索引大量文档,而且不须要当即可用于搜索。则能够经过减小刷新频率来优化。索引设置API使您可以暂时禁用刷间隔
curl -XPUT <nameofhost>:9200/<name_of_index>/_settings -d '{
 "index" : {
 "refresh_interval" : "-1"
 } 
}'

完成索引后,您能够恢复为默认值“1s”

  • Flush latency: 在flush完成以前,数据不会被固化到磁盘中。所以追踪flush latency颇有用。好比咱们看到这个指标稳步增加,代表磁盘性能很差。这个问题将最终致使没法向索引添加新的数据。 能够尝试下降index.translog.flush_threshold_size。这个设置决定translog的最大值(在flush被触发前)

3. 内存使用和GC指标

在运行Elasticsearch时,内存是您要密切监控的关键资源之一。 Elasticsearch和Lucene以两种方式利用节点上的全部可用RAM:JVM heap和文件系统缓存。 Elasticsearch运行在Java虚拟机(JVM)中,这意味着JVM垃圾回收的持续时间和频率将成为其余重要的监控领域。
JVM heap: A Goldilocks tale
Elasticsearch强调了JVM堆大小的重要性,这是“正确的” - 不要将其设置太大或过小,缘由以下所述。 通常来讲,Elasticsearch的经验法则是将少于50%的可用RAM分配给JVM堆,而不会超过32 GB。 您分配给Elasticsearch的堆内存越少,Lucene就可使用更多的RAM,这很大程度上依赖于文件系统缓存来快速提供请求。 可是,您也不想将堆大小设置得过小,由于应用程序面临来自频繁GC的不间断暂停,可能会遇到内存不足错误或吞吐量下降的问题 Elasticsearch的默认安装设置了1 GB的JVM heap大小,对于大多数用例来讲,过小了。 您能够将所需的heap大小导出为环境变量并从新启动Elasticsearch:

export ES_HEAP_SIZE=10g

如上咱们设置了es heap大小为10G,经过以下命令进行校验:

curl -XGET http://:9200/_cat/nodes?h=heap.max

Garbage collection
Elasticsearch依靠垃圾收集过程来释放heap memory。由于垃圾收集使用资源(为了释放资源!),您应该注意其频率和持续时间,以查看是否须要调整heap大小。设置过大的heap会致使GC时间过长,这些长时间的停顿会让集群错误的认为该节点已经脱离。

JVM指标的要点:

  • JVM heap in use: 当JVM heap 使用率达到75%时,es启动GC。如上图所示,能够监控node的JVM heap,而且设置一个警报,确认哪一个节点是否一直超过%85。若是一直超过,则代表垃圾的收集已经跟不上垃圾的产生。此时能够经过增长heap(须要知足建议法则不超过32G),或者经过增长节点来扩展集群,分散压力。
  • JVM heap used vs. JVM heap committed: 与commit的内存(保证可用的数量)相比,了解当前正在使用多少JVM heap的状况可能会有所帮助。heap memory的图通常是个锯齿图,在垃圾收集的时候heap上升,当收集完成后heap降低。若是这个锯齿图向上偏移,说明垃圾的收集速度低于rate of object creation,这可能会致使GC时间放缓,最终OutOfMemoryErrors。
  • Garbage collection duration and frequency: Both young- and old-generation garbage collectors undergo “stop the world” phases, as the JVM halts execution of the program to collect dead objects。在此期间节点cannot complete any task。主节点每30秒会去检查其余节点的状态,若是任何节点的垃圾回收时间超过30秒,则会致使主节点任务该节点脱离集群。
  • Memory usage: 如上所述,es很是会利用除了分配给JVM heap的任何RAM。像Kafka同样,es被设计为依赖操做系统的文件系统缓存来快速可靠地提供请求。 许多变量决定了Elasticsearch是否成功读取文件系统缓存,若是segment file最近由es写入到磁盘,它已经in the cache。然而若是节点被关闭并从新启动,首次查询某个segment的时候,数据极可能是必须从磁盘中读取,这是确保您的群集保持稳定而且节点不会崩溃的重要缘由之一。 总的来讲,监控节点上的内存使用状况很是重要,而且尽量多给es分配RAM,so it can leverage the speed of the file system cache without running out of space。

4. es主机的网络和系统

虽然Elasticsearch经过API提供了许多特定于应用程序的指标,但您也应该从每一个节点收集和监视几个主机级别的指标。 Host指标要点:

  • Disk space: 若是数据不少,这个指标很关键。若是disk space 太小,讲不能插入或更新任何内容,而且节点会挂掉。可使用Curator这样的工具来删除特定的索引以保持disk的可用性。 若是不让删除索引,另外的办法是添加磁盘、添加节点。请记住analyzed field占用磁盘的空间远远高于non-analyzed fields。
  • I/O utilization: 因为建立,查询和合并segment,Elasticsearch会对磁盘进行大量写入和读取,于具备不断遇到大量I / O活动的节点的写入繁重的集群,Elasticsearch建议使用SSD来提高性能。

  • CPU utilization: 在每一个节点类型的热图(如上所示)中可视化CPU使用状况可能会有所帮助。 例如,您能够建立三个不一样的图表来表示集群中的每组节点(例如,数据节点,主节点,客户端节点), 若是看到CPU使用率的增长,这一般是因为搜索量大或索引工做负载引发的。 若是须要,能够添加更多节点来从新分配负载。
  • Network bytes sent/received: 节点之间的通信是集群平衡的关键。所以须要监控network来确保集群的health以及对集群的需求(例如,segment在节点之间进行复制或从新平衡)。 Elasticsearch提供有关集群通讯的指标,但也能够查看发送和接收的字节数,以查看network接收的流量。
  • Open file descriptors: 文件描述符用于节点到节点的通讯,客户端链接和文件操做。若是这个number达到了系统的最大值,则只有在旧的链接和文件操做关闭以后才能进行新的链接和文件操做。 若是超过80%的可用文件描述符被使用,您可能须要增长系统的最大文件描述符数量。大多数Linux系统每一个进程只容许1024个文件描述符。 在生产中使用Elasticsearch时,您应该将操做系统文件描述符计数从新设置为更大,如64,000。
  • HTTP connections:

能够用任何语言发送请求,但Java将使用RESTful API经过HTTP与Elasticsearch进行通讯。 若是打开的HTTP链接总数不断增长,可能表示您的HTTP客户端没有正确创建持久链接。 从新创建链接会在您的请求响应时间内添加额外的毫秒甚至秒。 确保您的客户端配置正确,以免对性能形成负面影响,或使用已正确配置HTTP链接的官方Elasticsearch客户端。

5. 集群健康和节点可用性

指标要点:

  • Cluster status: 若是集群状态为黄色,则至少有一个副本分片未分配或丢失。 搜索结果仍将完成,但若是更多的分片消失,您可能会丢失数据。 红色的群集状态表示至少有一个主分片丢失,而且您缺乏数据,这意味着搜索将返回部分结果。 您也将被阻止索引到该分片。 Consider setting up an alert to trigger if status has been yellow for more than 5 min or if the status has been red for the past minute.
  • Initializing and unassigned shards: 当首次建立索引或者重启节点,其分片将在转换到“started”或“unassigned”状态以前暂时处于“initializing”状态,此时主节点正在尝试将分片分配到集群中的数据节点。 若是您看到分片仍处于初始化或未分配状态太长时间,则多是您的集群不稳定的警告信号。

6. 资源saturation and errors

es节点使用线程池来管理线程如何消耗内存和CPU。 因为线程池设置是根据处理器数量自动配置的,因此调整它们一般没有意义。However, it’s a good idea to keep an eye on queues and rejections to find out if your nodes aren’t able to keep up; 若是没法跟上,您可能须要添加更多节点来处理全部并发请求。Fielddata和过滤器缓存使用是另外一个要监视的地方,as evictions may point to inefficient queries or signs of memory pressure.
Thread pool queues and rejections
每一个节点维护许多类型的线程池; 您要监视的确切位置将取决于您对es的具体用途,通常来讲,监控的最重要的是搜索,索引,merge和bulk,它们与请求类型(搜索,索引,合并和批量操做)相对应。 线程池队列的大小反应了当前等待的请求数。 队列容许节点跟踪并最终服务这些请求,而不是丢弃它们。 一旦超过线程池的maximum queue size,Thread pool rejections就会发生。

指标要点:

  • Thread pool queues: 大队列不理想,由于它们耗尽资源,而且若是节点关闭,还会增长丢失请求的风险。若是你看到线程池rejected稳步增长,你可能但愿尝试减慢请求速率(若是可能),增长节点上的处理器数量或增长群集中的节点数量。 以下面的截图所示,查询负载峰值与搜索线程池队列大小的峰值相关,as the node attempts to keep up with rate of query requests。

  • Bulk rejections and bulk queues: 批量操做是一次发送许多请求的更有效的方式。 一般,若是要执行许多操做(建立索引或添加,更新或删除文档),则应尝试以批量操做发送请求,而不是发送许多单独的请求。 bulk rejections 一般与在一个批量请求中尝试索引太多文档有关。根据Elasticsearch的文档,批量rejections并非很须要担忧的事。However, you should try implementing a linear or exponential backoff strategy to efficiently deal with bulk rejections。

  • Cache usage metrics: 每一个查询请求都会发送到索引中的每一个分片的每一个segment中,Elasticsearch caches queries on a per-segment basis to speed up response time。另外一方面,若是您的缓存过多地堆积了这些heap,那么它们可能会减慢速度,而不是加快速度! 在es中,文档中的每一个字段能够以两种形式存储:exact value 和 full text。 例如,假设你有一个索引,它包含一个名为location的type。每一个type的文档有个字段叫city。which is stored as an analyzed string。你索引了两个文档,一个的city字段为“St. Louis”,另外一个的city字段为“St. Paul”。在倒排索引中存储时将变成小写并忽略掉标点符号,以下表

分词的好处是你能够搜索st。结果会搜到两个。若是将city字段保存为exact value,那只能搜“St. Louis”, 或者 “St. Paul”。 Elasticsearch使用两种主要类型的缓存来更快地响应搜索请求:fielddata和filter。

  • Fielddata cache: fielddata cache 在字段排序或者聚合时使用。 a process that basically has to uninvert the inverted index to create an array of every field value per field, in document order. For example, if we wanted to find a list of unique terms in any document that contained the term “st” from the example above, we would: 1.扫描倒排索引查看哪些文档(documents)包含这个term(在本例中为Doc1和Doc2) 2.对1中的每一个步骤,经过索引中的每一个term 从文档中来收集tokens,建立以下结构:


3.如今反向索引被再反向,从doc中compile 独立的tokens(st, louis, and paul)。compile这样的fielddata可能会消耗大量堆内存。特别是大量的documents和terms的状况下。 全部字段值都将加载到内存中。对于1.3以前的版本,fielddata缓存大小是无限制的。 从1.3版开始,Elasticsearch添加了一个fielddata断路器,若是查询尝试加载须要超过60%的堆的fielddata,则会触发。

  • Filter cache: 过滤缓存也使用JVM堆。 在2.0以前的版本中,Elasticsearch自动缓存过滤的查询,最大值为堆的10%,而且将最近最少使用的数据逐出。 从版本2.0开始,Elasticsearch会根据频率和段大小自动开始优化其过滤器缓存(缓存仅发生在索引中少于10,000个文档的段或小于总文档的3%)。 所以,过滤器缓存指标仅适用于使用2.0以前版本的Elasticsearch用户。 例如,过滤器查询能够仅返回年份字段中的值在2000-2005范围内的文档。 在首次执行过滤器查询时,Elasticsearch将建立一个与其相匹配的文档的位组(若是文档匹配则为1,不然为0)。 使用相同过滤器后续执行查询将重用此信息。 不管什么时候添加或更新新的文档,也会更新bitset。 若是您在2.0以前使用的是Elasticsearch版本,那么您应该关注过滤器缓存以及驱逐指标(更多关于如下内容)。

  • Fielddata cache evictions: 理想状况下,咱们须要限制fielddata evictions的数量,由于他们很吃I/O。若是你看到不少evictions而且你又不能增长内存。es建议限制fielddata cache的大小为20%的heap size。这些是能够在elasticsearch.yml中进行配置的。当fielddata cache达到20%的heap size时,es将驱逐最近最少使用的fielddata,而后容许您将新的fielddata加载到缓存中。 es还建议使用doc values,由于它们与fielddata的用途相同。因为它们存储在磁盘上,它们不依赖于JVM heap。尽管doc values不能被用来分析字符串, they do save fielddata usage when aggregating or sorting on other types of fields。在2.0版本后,doc values会在文档被index的时候自动建立,which has reduced fielddata/heap usage for many users。
  • Filter cache evictions: 如前所述,filter cache eviction 指标只有在es2.0以前的版本可用。每一个segment都维护本身的filter cache eviction。由于eviction在大的segment上操做成本较高,没有的明确的方法来评估eviction。可是若是你发现eviction很频繁,代表你并无很好地利用filter,此时你须要从新建立filter,即便放弃原有的缓存,你也可能须要调整查询方式(用bool query 而不是 and/or/not filter)。
  • Pending tasks:

pending task只能由主节点来进行处理,这些任务包括建立索引并将shards分配给节点。任务分优先次序。若是任务的产生比处理速度更快,将会产生堆积。待处理任务的数量是您的群集运行平稳的良好指标,若是您的主节点很是忙,而且未完成的任务数量不会减小,咱们须要仔细检查缘由。

  • Unsuccessful GET requests: GET请求比正常的搜索请求更简单 - 它根据其ID来检索文档。 get-by-ID请求不成功意味着找不到文档I
相关文章
相关标签/搜索