ElasticSearch 1.6 似乎在高可用性测试期间丢失文档

ElasticSearch 1.6 seems to lose documents during high availability test

作为将 ElasticSearch 用作可靠文档存储的调查的一部分,我从 Java 应用程序 运行 进行基本的 HA 测试,如下所示:

我使用 ElasticSearch 1.6 (https://registry.hub.docker.com/_/elasticsearch) 的现成 Docker 映像设置了一个最小集群,其中:

然后我 运行 一个小型加载器应用程序,可插入 500,000 个文档,每个文档约 1KB。

这在我的机器上大约需要 1 分半钟。期间,我重启了当前的master节点(docker重启)。

在 运行 结束时,Java API 对我 100% 的查询做出了 OK 响应,但是当我使用 curl 请求检查文档计数时,一个缺少一些文件(在 2 到 10 之间,具体取决于我制作的 运行s)

即使在索引上有明确的“_refresh”请求,我的文档数也是一样的。

当然,我主要担心的不是某些文档在崩溃期间无法存储,而是 API 返回的肯定结果(特别是因为我正在使用 WriteConsistencyLevel.ALL 进行测试)。

我知道这张票,但不确定它是否适用于我的基本场景

我的插入是这样完成的:

client.prepareUpdate("test", "test", id)
      .setDoc(doc).setUpsert(doc)
      .setConsistencyLevel(WriteConsistencyLevel.ALL)
      .execute.get.isCreated == true

其余代码可在此处找到: https://github.com/joune/nosql/blob/master/src/main/scala/ap.test.nosql/Loader.scala

如果您认为我做的事情明显错误,请提出建议。

(我知道有些人会回答说将 ElasticSearch 视为可靠的文档存储是完全错误的,但这是研究的目标,而不是我期望的那种答案)


更新 Andrei Stefan 要求的额外日志

> grep discovery.zen.minimum_master_nodes elasticsearch.yml
discovery.zen.minimum_master_nodes: 2

> curl -XPUT 'http://localhost:9200/_cluster/settings' -d '{"transient":{"logger._root":"DEBUG"}}'
{"acknowledged":true,"persistent":{},"transient":{"logger":{"_root":"DEBUG"}}}%
> curl -XPUT 'http://localhost:9200/_cluster/settings' -d '{"transient": {"logger.index.translog":"TRACE"}}'
{"acknowledged":true,"persistent":{},"transient":{"logger":{"index":{"translog":"TRACE"}}}}%

运行 测试 200,000 个条目:

0 KO | 200000 OK
> curl -XGET 'localhost:9200/test/test/_count?preference=_primary'
{"count":199991,"_shards":{"total":5,"successful":5,"failed":0}}%  

我把日志放在这里:https://gist.github.com/ab1ed844f2038c30e63b

这里的评论中有很多好的注释。我会谦虚地建议只有两个合格主节点的集群不是 "high availability." elasticsearch docs 状态:

It is recommended to avoid having only two master eligible nodes, since a quorum of two is two. Therefore, a loss of either master node will result in an inoperable cluster.

本质上,在具有 discovery.zen.minimum_master_nodes properly set to 2, as soon as either node goes down, you can't have a master, and so you no longer have a cluster. If minimum_master_nodes was set to 1, you'd have a whole different set of problems to contend with (split-brain) 的双主集群中。我们 运行 每个 ES 集群有 3 个主节点(此外,还有 运行 个专用主节点)——我很想知道你使用 3 个主节点集群是否会得到不同的结果。

就是说,API 确认收到您的文档然后未能保留它们似乎仍然很不正确,但我认为最终它可能确实会回到 elasticsearch 不是这样的事实旨在 运行 生产-class 实施,只有两个合格的主节点。

I'm aware of this ticket, yet unsure if it applies to my basic scenario https://github.com/elastic/elasticsearch/issues/7572

我做了一些挖掘,结果确实如此。原因是在节点关闭期间,我们在关闭索引服务之前关闭了传输层,这意味着正在进行的操作被有效地分割开(就像网络问题的情况一样)。显然这不行,我打开https://github.com/elastic/elasticsearch/issues/12314来跟踪这个。

附带说明 - 使用 Elasticsearch 2.0,我们在响应中添加了 shard header,指示有多少分片成功。这为您提供了一种检查操作是否确实成功写入所有分片并在需要时重试的方法。这是成功响应的示例(同时写入主副本和副本)。

{
    "_shards" : {
        "total" : 2,
        "failed" : 0,
        "successful" : 2
    },

最后请注意,分片失败并不意味着 #7572 发挥了作用。这是高度 unlikely.However,在 #7572 确实发生的所有情况下,header 将有总 != 成功。