【问题标题】:ElasticSearch randomly fails when running tests运行测试时 ElasticSearch 随机失败
【发布时间】:2017-05-04 04:29:35
【问题描述】:

我有一个测试 ElasticSearch 框 (2.3.0),我使用 ES 的测试以随机顺序失败,这真的很令人沮丧(失败并出现 All shards failed 异常)。

查看elastic_search.log 文件,它只显示了这个

[2017-05-04 04:19:15,990][DEBUG][action.search.type       ] [es-testing-1] All shards failed for phase: [query]
RemoteTransportException[[es-testing-1][127.0.0.1:9300][indices:data/read/search[phase/query]]]; nested: IllegalIndexShardStateException[CurrentState[RECOVERING] operations only allowed when shard state is one of [POST_RECOVERY, STARTED, RELOCATED]];
Caused by: [derp_test][[derp_test][3]] IllegalIndexShardStateException[CurrentState[RECOVERING] operations only allowed when shard state is one of [POST_RECOVERY, STARTED, RELOCATED]]
    at org.elasticsearch.index.shard.IndexShard.readAllowed(IndexShard.java:993)
    at org.elasticsearch.index.shard.IndexShard.acquireSearcher(IndexShard.java:814)
    at org.elasticsearch.search.SearchService.createContext(SearchService.java:641)
    at org.elasticsearch.search.SearchService.createAndPutContext(SearchService.java:618)
    at org.elasticsearch.search.SearchService.executeQueryPhase(SearchService.java:369)
    at org.elasticsearch.search.action.SearchServiceTransportAction$SearchQueryTransportHandler.messageReceived(SearchServiceTransportAction.java:368)
    at org.elasticsearch.search.action.SearchServiceTransportAction$SearchQueryTransportHandler.messageReceived(SearchServiceTransportAction.java:365)
    at org.elasticsearch.transport.TransportService$4.doRun(TransportService.java:350)
    at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

知道发生了什么吗?到目前为止,我的研究只告诉我这很可能是由于损坏的 translog 造成的——但我认为删除 translog 不会有帮助,因为测试会删除每个命名空间的测试索引

ES 测试盒有 3.5GB RAM,使用 2.5GB 堆大小,测试期间 CPU 使用率非常正常(峰值为 15%)


澄清一下:当我说测试失败时,我的意思是上面提到的奇怪异常的错误(由于值不正确而没有失败测试)。我在每次插入/更新操作后都进行了手动刷新,所以值是正确的。

【问题讨论】:

  • 您是否使用ESIntegTestCase 进行集成测试?
  • @chengpohi 不,目前它只是将测试框视为普通的 es 框..这是反模式还是什么?

标签: elasticsearch


【解决方案1】:

在调查 ElasticSearch 日志文件(在 DEBUG 级别)和源代码后,事实证明,在创建索引后,分片进入RECOVERING 状态,有时我的测试尝试在 ElasticSearch 上执行查询,而分片尚未激活——因此例外。

修复很简单 - 创建索引后,只需使用 setWaitForActiveShards 函数等待分片处于活动状态,为了更加偏执,我还添加了 setWaitForYellowStatus

【讨论】:

  • 感谢您的提醒。由于在接受自己的答案之前有 2 天的延迟而忘记了它?
【解决方案2】:

建议使用ESIntegTestCase 进行集成测试。

ESIntegTestCase 有一些辅助方法,例如:ensureGreenrefresh ... 以确保 Elasticsearch 已准备好继续测试。并且可以配置node settings进行测试。

如果直接使用Elasticsearch作为测试框,可能会导致各种问题:

  1. 就像你的Exception,这似乎正在为索引恢复碎片 derp_test
  2. 即使您已将数据索引到索引中,但是当您立即搜索时会失败,因为集群需要 flushrefresh ...

大多数问题可以使用Thread.sleep 等待一段时间来修复:),但这样做是一种糟糕的方法。

【讨论】:

  • 嗯,我不确定在这种情况下是否可以轻松使用 ESIntegTestCase,因为它是一个 clojure 项目,而 ES 只是等式的一部分。我会看看我是否可以摆弄刷新/刷新来解决这个问题
  • 是的,你应该试试这个同步操作。
【解决方案3】:

在插入数据后和执行查询之前尝试手动刷新索引,以确保数据可搜索。

要么:

【讨论】:

  • 哎呀,我的错,我应该说得更清楚,当我说“测试失败”时,我的意思是错误而不是给出无效的结果。每次插入/更新后我也刷新了
【解决方案4】:

可能还有其他原因。我的 elasticsearch 单元测试遇到了同样的问题,起初我认为问题的根本原因是在 .Net Core 或 Nest 或我的代码之外的其他地方,因为测试会成功运行 在调试模式(调试测试时)但在发布模式下随机失败(运行测试时)

经过大量调查和多次尝试和错误,我发现问题根本原因(在我的情况下)是并发!!或另一方面比赛条件曾经发生过

由于测试同时运行,并且我曾经在测试类构造函数上重新创建和播种索引(初始化和准备),这意味着在每个测试开始时执行,并且由于测试将同时运行,因此很可能会发生竞争条件并且让我的测试失败

这是我的初始化代码,导致测试在运行时随机失败(在发布模式下)

 public BaseElasticDataTest(RootFixture fixture)
        : base(fixture)
    {
        ElasticHelper = fixture.Builder.Build<ElasticDataProvider<FakePersonIndex>();
        deleteFakeIndex();
        createFakeIndex();
        fillFakeIndexData();
    }

上面的代码用于同时在每个测试上运行。我解决了我的问题,每个测试类只执行一次初始化代码(测试类中的所有测试用例一次),问题就消失了。

这是我固定的测试类构造函数代码:

 static bool initialized = false;
 public BaseElasticDataTest(RootFixture fixture)
        : base(fixture)
    {
        ElasticHelper = fixture.Builder.Build<ElasticDataProvider<FakePersonIndex>>();
        if (!initialized)
        {
            deleteFakeIndex();
            createFakeIndex();
            fillFakeIndexData();
            //for concurrency
            System.Threading.Thread.Sleep(100);
            initialized = true;
        }

    }

希望对你有帮助

【讨论】:

    猜你喜欢
    • 2020-03-13
    • 2016-01-31
    • 2021-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 2019-08-27
    • 2015-03-15
    相关资源
    最近更新 更多