为什么Elasticsearch允许我在单个节点集群中索引不符合仲裁要求的文档?

时间:2018-02-19 17:37:10

标签: elasticsearch indexing quorum

来自https://www.elastic.co/guide/en/elasticsearch/guide/2.x/distrib-write.html

  

请注意,number_of_replicas是索引设置中指定的副本数,而不是当前活动的副本数。如果您已指定索引应具有三个副本,则仲裁将如下所示:

     

int((primary + 3 replicas)/ 2)+ 1 = 3

     

但是如果只启动两个节点,则会有不足的活动分片副本来满足仲裁,并且您将无法索引或删除任何文档。

我在单节点集群上运行了以下命令,即使上面的数学表明我不能索引文档,我也能成功索引文档。

curl -X DELETE http://localhost:9200/a/?pretty
curl -X PUT -siH 'Content-Type: application/json' \
     http://localhost:9200/a?pretty -d '{

    "settings": {
        "number_of_replicas": 3
    }
}'
curl -sH 'Content-Type: application/json' -X PUT http://localhost:9200/a/a/1?pretty -d '{"a": "a"}'
curl -si http://localhost:9200/_cluster/health?pretty
curl -si http://localhost:9200/a/a/1?pretty

这是输出:

$ curl -X PUT -siH 'Content-Type: application/json' \
     http://localhost:9200/a?pretty -d '{

    "settings": {
        "number_of_replicas": 3
    }
}'
HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 77

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "a"
}

$ curl -sH 'Content-Type: application/json' -X PUT http://localhost:9200/a/a/1?pretty -d '{"a": "a"}'
{
  "_index" : "a",
  "_type" : "a",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 4,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

$ curl -si http://localhost:9200/_cluster/health?pretty
HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 468

{
  "cluster_name" : "docker-cluster",
  "status" : "yellow",
  "timed_out" : false,
  "number_of_nodes" : 1,
  "number_of_data_nodes" : 1,
  "active_primary_shards" : 5,
  "active_shards" : 5,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 15,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 25.0
}

$ curl -si http://localhost:9200/a/a/1?pretty
HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 124

{
  "_index" : "a",
  "_type" : "a",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "a" : "a"
  }
}

即使我已经将索引配置为具有3个副本分片并且数学表明我必须至少有3个节点,我如何仅用1个节点索引文档?

1 个答案:

答案 0 :(得分:1)

这是ES 2.x中的旧法定人数规则。从ES 5.x开始,写入一致性检查已经稍微改变了一个黄色集群,即一个集群将分配所有主分片,将通过写操作的一致性检查,并允许您索引和删除文档。

现在决定是否可以进行写入的方法是在索引操作中使用wait_for_active_shards参数。默认情况下,如果所有主分片都已启动,则将允许索引操作。您可以通过指定在授权索引操作之前希望处于活动状态的分片数来覆盖该设置,例如:在您的情况下,wait_for_active_shards=all相当于wait_for_active_shards=4(4 = 1个主要+ 3个副本)。如果您需要与之前相同的仲裁规则,请指定wait_for_active_shards=3

可以在official documentationhere

中找到更多信息