下面直接点,先描述一下一个增删改请求打过来Elasticsearch内部作了什么。
如图
(1)对于客户端首先会选择一个节点node发送请求过去,这个节点node就是协调节点coordinating node
(2)协调节点coordinating node会对docuemnt数据进行路由,将请求转发给对应的node(含有primary shard)
(3)实际上node的primary shard会处理请求,而后将数据同步到对应的含有replica shard的node
(4)协调节点coordinating node若是发现含有primary shard的node和全部的含有replica shard的node都搞定以后,就会返回响应结果给客户端node
下面手工画图展现一下上面的过程:
假设咱们有2个节点,5个primary shard replica=1网络
一、客户端发送增删改请求给协调节点node2
二、协调节点node2将请求路由到含有primary shard的node1
三、node1处理请求,并同步数据到对应的含有replica shard的node2
四、协调节点node2若是发现含有primary shard的node1以及全部含有replica shard的node2都搞定了,就会返回响应结果给客户端ide
consistency
默认状况下,主分片须要法定数量或大部分的分片副本(其中分片副本能够是主分片或副本分片)在尝试写入操做以前可用。这是为了防止将数据写入网络分区的 “wrong side”。法定人数定义以下:spa
int((primary + number_of_replicas)/ 2)+ 1
容许的值consistency是one(仅主要分片),all (主要和全部副本),或默认quorum或大多数分片副本。code
请注意,它number_of_replicas是索引设置中指定的副本数,而不是当前活动的副本数。若是您已指定索引应具备三个副本,则仲裁将以下所示:blog
int( (primary + 3 replicas) / 2 ) + 1 = 4
可是,若是仅启动两个节点,则将没有足够的活动分片副原本知足仲裁,而且您将没法索引或删除任何文档。索引
timeout
若是可用的分片副本不足,会发生什么?Elasticsearch等待,但愿会出现更多的分片。默认状况下,它将等待最多1分钟。若是须要,可使用timeout参数让它更快地停止:100是100毫秒,30s是30秒。
注意
默认状况下,新索引具备一个副本,这意味着应该须要两个活动分片副本以知足须要的quorum。可是,这些默认设置会阻止咱们对单节点群集执行任何有用的操做。为避免此问题,仅当number_of_replicas大于1时才强制要求仲裁。图片
移除consistency这个参数以后,用wait_for_active_shards这个参数替代了。
缘由就是,consistency检查是在Put以前作的。然而,虽然检查的时候,shard知足quorum,可是真正从primary shard写到replica以前,仍会出现shard挂掉,但Update Api会返回succeed。所以,这个检查并不能保证replica成功写入,甚至这个primary shard是否能成功写入也未必能保证。ip
为了提升对系统写入的弹性,使用wait_for_active_shards,能够将索引操做配置为在继续操做以前等待必定数量的活动分片副本。若是必需数量的活动分片副本不可用,则写入操做必须等待并重试,直到必需的分片副本已启动或发生超时。默认状况下,写入操做仅等待主分片在继续(即wait_for_active_shards=1)以前处于活动状态。
注意,此设置大大下降了写入操做不写入所需数量的分片副本的可能性,但它并未彻底消除这种可能性,由于此检查在写入操做开始以前发生。一旦写入操做正在进行,复制在任何数量的分片副本上仍然可能失败,但仍然能够在主分片上成功。在_shards写操做的响应部分揭示了其复制成功/失败碎片的份数。路由
PUT /test_index/_doc/20?wait_for_active_shards=1 { "test_field":"test consistency" } { "_index" : "test_index", "_type" : "_doc", "_id" : "20", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 10, "_primary_term" : 2 } "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }