ElasticStack系列之四 & 索引后半段过程

  • segment归并的影响
  • 归并线程配置与策略
  • optimize
  • ES数据写入流程
 
1. segment归并的影响
影响原因:
由之前的讲解我们已经知道数据怎么进入ElasticSearch并且如何才能让数据更快的被检索使用。其中用一句话概括了Lucene的设计思路就是“开新文件”,但另一个方面看,开新文件也会给服务器带来负载压力。因为默认每5s都会有一个新文件产生,每个文件都需要有文件句柄、内存、CPU使用等各种资源,这样对应的响应性能绝对好不了!
ES解决办法:
为了解决这个办法,ElasticSearch会不断在后台运行任务,主动将这些零散的segment做数据归并,尽量让索引内只保存少量的、每个比较大的segment文件。
这个过程是有独立的线程来进行的,并不影响新segment的产生。归并过程中,索引状态如上图所示,尚未完成的较大的segment是被排除在检索可见范围之外的,具体逻辑如下:
当归并完成,较大的这个segment刷到磁盘后,commit文件作出相应的变更,删除之前几个小的segment,改成新的大segment。等检索请求都从小的segment转到大segment上以后,删除没用的小segment。这时候,索引里segment数量就下降了,具体状态图如下所示:
 
2-1. 归并线程的配置与策略
segment归并的过程具体有:读取segment-->归并计算-->再写一遍segment-->刷到磁盘, 可以说这是一个非常消耗磁盘 I/O 和 CPU 的任务。所以,ElasticSearch提供了对归并线程的限制机制,确保这个任务不会过分影响到其他任务。
默认情况下,归并线程的限速是:20MB/s , 对于写入量较大,磁盘转速较高,甚至使用SSD盘的服务器来说,这个限速明显过低,建议可以适当调大到 100MB 或者更高。
归并线程数目,ElasticSearch也是有所控制的,默认归并线程的计算公式如下所示:
Math.min(3, Runtime.getRuntime().availableProcessors() / 2)
即服务器 CPU 核数的一半 > 3时,启动3个归并线程;否则启动跟 CPU 核数的一半相等的线程数。一般的服务器 CPU 核数都会在6以上,所以一般来说归并线程数就是 3。如果你确定自己磁盘性能跟不上,可以降低index.merge.scheduler.max_thread_count配置,免得 I/O 情况恶化。
2-2. 归并策略
归并线程是按照一定的运行策略来挑选segment进行归并的,具体有以下几条:
  • index.merge.policy.floor_segment 默认 2MB,小于这个大小的segment优先被归并
  • index.merge.policy.max_merge_at_once 默认一次最多归并 10 个segment。
  • index.merge.policy.max_merge_at_once_explicit 默认optimize时一次最多归并30个。
  • index.merge.policy.max_merged_segment 默认 5GB,大于这个大小的segment不用参与归并,optimize除外。
根据这段策略,我们可以从另一个角度考虑如何减少segment归并的资源消耗以及提高高响应的办法:加大flush间隔,尽量让每次新生成的segment本身大小就比较大。
 
3. optimize
ElasticSearcch默认最大的segment大小是 5GB。那么一个比较庞大的数据索引,就必然会有为数不少的segment永远存在,这对文件句柄、内存资源都是极大的浪费。但是由于归并任务太消耗资源,所以一般不太选择加大 index.merge.policy.max_merged_segment 配置,而是在负载较低的时间段,通过optimize接口,强制归并segment。
# curl -XPOST http://127.0.0.1:9200/logstash-2015-06.10/_optimize?max_num_segments=1
由于 optimize 线程对资源的消耗比普通的归并线程大得多, 所以, 绝对不建议对还在写入数据的热索引执行这个操作。
 
4. ES数据写入流程
作为分布式系统,数据副本可算是一个标配。ElasticSearch数据写入流程,自然也涉及副本。在有副本配置的情况下,数据从发向ElasticSearch节点-->到接到ElasticSearch节点响应返回流向如下图所示:
 
  1. 客户端请求发送给 Node1 节点,Node1 节点用数据的 _id 取余计算得到应该将数据存储到 shard0 上。通过 cluster state 信息发现 shard0 的主分片已经分配到了 Node3 上,Node1 转发请求数据给 Node3.
  2. Node3 完成请求数据的索引过程,存入主分片 P0 上。然后并行转发数据给分配有shard0的副本分片的 Node1 和 Node2。当Node1 和 Node2 节点同时汇报 coordinating 节点说 数据写入成功, 即会返回成功响应给客户端。
这个过程有几个参数可以用来控制或变更其行为:
  <1. consistency:在上示例中,两个副本分片只要有一个成功就可以返回给客户端了。这点也是有配置的。ElasticSearch默认值的计算公式如下所示:
  intprimary + number_of_replicas/ 2)) + 1
  <2. timeout:如果集群出现异常,有些分片当前不可用,ElasticSearch默认会等待 1 分钟看分片能否恢复。可以使用 ?timeout=30s 参数来缩短这个等待时间。
  副本配置和分片配置不一样,是可以随时调整的。有些较大的重建索引的应用场景,设置可以在optimize前,先把副本全部取消掉,等optimize或者重建索引之后,再重新开启副本,节约单个segment的重复归并消耗。
curl -XPUT http://localhost:9200/mweibo/_settings -d '{
"index" : {
"number_of_replicas" : 0
}
}'
 
posted @ 2017-02-08 18:19  星火燎原智勇  阅读(637)  评论(4编辑  收藏  举报