注意elasticsearch的版本不一样,此处的描述可能会有稍许误差html
Elasticsearch是一款用Java编写的开源分布式文档存储和搜索引擎,能够用于near real-time存储和数据检索。node
在开始探索性能指标以前,让咱们来看看Elasticsearch的工做原理,在elasticsearch中,集群由一个或者更多的节点组成,以下图:
每一个节点是Elasticsearch的单个运行实例,其“elasticsearch.yml”配置文件指定其所属的集群(“cluster.name”)以及它能够是什么类型的节点。 配置文件中设置的任何属性(包括集群名称)也能够经过命令行参数指定。 上图中的集群由一个专用主节点和五个数据节点组成。 三种最多见的es节点类型有:数据库
data节点
默认状况下(不动配置),每一个节点都是数据节点,以shards的形式存储数据并执行与索引,搜索和聚合数据相关的操做。
在大集群中,咱们能够经过设置node.master : false来设置该节点为专用数据节点。确保这些节点具备足够的资源来处理与数据相关的请求,而不须要承担与集群相关的管理任务类的工做负载。缓存
client 节点
若是将node.master 和node.data都设置为false。那么该节点就是一个client节点。该client节点被设计为负载均衡器的角色,以帮助路由索引和搜索请求。
client节点有助于承担部分搜索工做量,以便数据和主节点节点能够专一于其核心任务。client节点并非必须的,由于数据节点可以本身处理请求路由。若是你的search/index workload比较重,能够在集群中配一个client节点。bash
在es中,相关联的数据一般存储在相同的索引中,每一个索引包含一组JSON格式的相关联文档。Elasticsearch的全文搜索秘诀是Lucene的倒排索引。在索引(存入)数据的时候,es会自动为每一个字段建立一个倒排索引,倒排索引将索引的词(terms)映射(map)到包含该词的文档(document)中。index被存储在一个或多个主副shard中,每一个shard都是一个完整的Lucenes实例,是一个完整的迷你搜索引擎。
网络
建立索引时,能够指定主分片的数量以及每一个主节点的副本数,默认为五个分片和一个副本。索引建立后,分片数不能被修改。若是要修改可能须要reindex。副本数能够在后期被修改。 为了防止数据丢失,主节点的调度机制会确保主副分片不会出如今同一个数据节点上。并发
Elasticsearch提供了大量的Metric,能够帮助您检测到问题的迹象,在遇到节点不可用、out-of-memory、long garbage collection times的时候采起相应措施。 一些关键的检测以下:负载均衡
这里提供了一个metric搜集和监控的框架 Monitoring 101 series ,全部这些指标均可以经过Elasticsearch的API以及Elasticsearch的Marvel和Datadog等通用监控工具访问。框架
搜索请求是Elasticsearch中的两个主要请求类型之一,另外一个是索引请求。 这些请求有时相似于传统数据库系统中的读写请求。 Elasticsearch提供与搜索过程的两个主要阶段(查询和获取)相对应的度量。 下图显示了从开始到结束的搜索请求的路径。curl
step1. 客户端向Node 2 发送搜索请求
step2. Node 2(此时客串协调角色)将查询请求发送到索引中的每个分片的副本
节点处理时,由谁分发,就由谁交付
若是您使用Elasticsearch主要用于搜索,或者若是搜索是面向客户的功能。您应该监视查询延迟和设定阈值。 监控关于查询和提取的相关指标很重要,能够帮助您肯定搜索随时间的变化。 例如,您可能但愿跟踪查询请求的尖峰和长期增加,以便您能够作好准备。
搜索性能指标的要点:
索引请求相似于传统数据库系统中的写入请求,若是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 意味着以下:
当多个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提供了许多指标,可用于评估索引性能并优化更新索引的方式。
索引性能指标的要点:
curl -XPUT <nameofhost>:9200/<name_of_index>/_settings -d '{ "index" : { "refresh_interval" : "-1" } }'
完成索引后,您能够恢复为默认值“1s”
在运行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指标的要点:
虽然Elasticsearch经过API提供了许多特定于应用程序的指标,但您也应该从每一个节点收集和监视几个主机级别的指标。 Host指标要点:
能够用任何语言发送请求,但Java将使用RESTful API经过HTTP与Elasticsearch进行通讯。 若是打开的HTTP链接总数不断增长,可能表示您的HTTP客户端没有正确创建持久链接。 从新创建链接会在您的请求响应时间内添加额外的毫秒甚至秒。 确保您的客户端配置正确,以免对性能形成负面影响,或使用已正确配置HTTP链接的官方Elasticsearch客户端。
指标要点:
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就会发生。
指标要点:
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。
3.如今反向索引被再反向,从doc中compile 独立的tokens(st, louis, and paul)。compile这样的fielddata可能会消耗大量堆内存。特别是大量的documents和terms的状况下。 全部字段值都将加载到内存中。对于1.3以前的版本,fielddata缓存大小是无限制的。 从1.3版开始,Elasticsearch添加了一个fielddata断路器,若是查询尝试加载须要超过60%的堆的fielddata,则会触发。
pending task只能由主节点来进行处理,这些任务包括建立索引并将shards分配给节点。任务分优先次序。若是任务的产生比处理速度更快,将会产生堆积。待处理任务的数量是您的群集运行平稳的良好指标,若是您的主节点很是忙,而且未完成的任务数量不会减小,咱们须要仔细检查缘由。