Elasticsearch: 由于未按预期清理索引而导致 CI​​ 失败

创建于 2019-08-28  ·  48评论  ·  资料来源: elastic/elasticsearch

清理代码似乎存在某种问题,以确保在测试之间清理所有索引。 很难确定,但是在创建一个在测试本身中没有明显原因的索引时,似乎存在由于ResourceAlreadyExistsException导致各种测试失败的趋势。

我在这个主入口构建中注意到了这IndexLifecycleIT.testStartStopILM ,它创建一个索引作为它所做的第一个操作之一 - 此时集群应该是空白的。

查看包含resource_already_exists_exception消息的失败的构建统计信息,我们可以看到它在 7 月 23 日之前非常安静,并且构建的越来越多,这表明这可能与最近的构建更改有关:
Screen Shot 2019-08-28 at 11 56 40 AM
[注意:此图不包括 8 月 15 日的 10 分钟时段,其中有 608 次失败,以使比例更清晰]

由于不应该存在的索引已经存在而失败的测试与特定的功能区域之间没有明确的关系。 它似乎最常发生在客户端和 YAML 测试中,尽管不是唯一的。 在我看到的一些抽查中:

  • IndexLifecycleIT.testStartStopILM
  • CCSDuelIT.testPagination
  • test {yaml=search/240_date_nanos/date_nanos requires dates after 1970 and before 2262}
  • IndicesClientIT.testCloseExistingIndex
  • DatafeedJobsRestIT.testLookbackWithGeo

当集群应该是一张白纸时,所有这些似乎都在创建索引时失败了。

我相信这也是https://github.com/elastic/elasticsearch/issues/45605https://github.com/elastic/elasticsearch/issues/45805的原因

:DeliverBuild >test >test-failure Delivery

最有用的评论

另一方面,没有证据表明这种情况发生在我们不使用--parallel运行的非主分支上

所有48条评论

ping @elastic/es-core-infra

还有#45600

当集群应该是一张白纸时,所有这些似乎都在创建索引时失败了。

查看服务器端日志。 它们是否显示如下内容:

[2019-08-14T18:07:42,945][WARN ][o.e.i.IndicesService     ] [integTest-0] [test/ee-7zmiUQGayvOq6LgEShg] failed to delete index
org.elasticsearch.env.ShardLockObtainFailedException: [test][0]: obtaining shard lock timed out after 0ms, previous lock details: [shard creation] trying to lock for [deleting index directory]

如果是这样,那么应该责备的不仅仅是测试客户端清理代码,而是客户将在生产中运行的相同服务器代码,这对于 7.4 来说似乎是一个大问题。 见https://github.com/elastic/elasticsearch/issues/45600#issuecomment -521620912

@DaveCTurner我相信你现在也在努力。 所以平:)

是的,我正在查看是否可以重现此问题,特别是测试失败https://github.com/elastic/elasticsearch/issues/45956。 我确实看到我的机器在 1400 次迭代后报告了类似的ShardLockObtainFailedException测试失败,同时运行stress -c 16 -i 4 -m 8 -d 4 ,但不幸的是我在假期前的提交上运行(302d29c87059658f776fb9c22bc76362bd46d0a0)。 我添加了更多日志记录并更新到更新的master并再次尝试。

testStartStopILM失败没有任何迹象表明删除失败。 有一个与失败大致一致的异常,但它是由双重创建的索引上的IndexNotFoundException引起的,在它被记录为被删除后:

[2019-08-28T17:05:49,025][WARN ][o.e.i.s.RetentionLeaseBackgroundSyncAction] [integTest-0] unexpected error during the primary phase for action [indices:admin/seq_no/retention_lease_background_sync], request [RetentionLeaseBackgroundSyncAction.Request{retentionLeases=RetentionLeases{primaryTerm=1, version=1, leases={peer_recovery/sIFqVv9GQ86guDpZYRI0pg=RetentionLease{id='peer_recovery/sIFqVv9GQ86guDpZYRI0pg', retainingSequenceNumber=0, timestamp=1567011946292, source='peer recovery'}}}, shardId=[baz][0], timeout=1m, index='baz', waitForActiveShards=0}]
org.elasticsearch.index.IndexNotFoundException: no such index [baz]
    at org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.concreteIndices(IndexNameExpressionResolver.java:190) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.concreteIndices(IndexNameExpressionResolver.java:116) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.concreteSingleIndex(IndexNameExpressionResolver.java:278) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.TransportReplicationAction.concreteIndex(TransportReplicationAction.java:234) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.TransportReplicationAction$ReroutePhase.doRun(TransportReplicationAction.java:651) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.TransportReplicationAction$ReroutePhase$2.onNewClusterState(TransportReplicationAction.java:795) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.cluster.ClusterStateObserver$ContextPreservingListener.onNewClusterState(ClusterStateObserver.java:311) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.cluster.ClusterStateObserver.waitForNextChange(ClusterStateObserver.java:169) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.cluster.ClusterStateObserver.waitForNextChange(ClusterStateObserver.java:120) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.cluster.ClusterStateObserver.waitForNextChange(ClusterStateObserver.java:112) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.TransportReplicationAction$ReroutePhase.retry(TransportReplicationAction.java:792) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.TransportReplicationAction$ReroutePhase$1.handleException(TransportReplicationAction.java:771) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.transport.TransportService$ContextRestoreResponseHandler.handleException(TransportService.java:1091) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.transport.TransportService$DirectResponseChannel.processException(TransportService.java:1200) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.transport.TransportService$DirectResponseChannel.sendResponse(TransportService.java:1174) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.transport.TaskTransportChannel.sendResponse(TaskTransportChannel.java:60) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.ChannelActionListener.onFailure(ChannelActionListener.java:56) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.TransportReplicationAction$AsyncPrimaryAction.onFailure(TransportReplicationAction.java:408) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.TransportReplicationAction$AsyncPrimaryAction.handleException(TransportReplicationAction.java:402) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.TransportReplicationAction$AsyncPrimaryAction.lambda$runWithPrimaryShardReference$3(TransportReplicationAction.java:370) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.ActionListener$1.onFailure(ActionListener.java:70) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.ActionListener$1.onFailure(ActionListener.java:70) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.ActionListener$1.onFailure(ActionListener.java:70) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:64) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.ActionListener.lambda$map$2(ActionListener.java:145) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:62) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.ActionListener.completeWith(ActionListener.java:253) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.index.seqno.RetentionLeaseBackgroundSyncAction.shardOperationOnPrimary(RetentionLeaseBackgroundSyncAction.java:97) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.index.seqno.RetentionLeaseBackgroundSyncAction.shardOperationOnPrimary(RetentionLeaseBackgroundSyncAction.java:54) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.TransportReplicationAction$PrimaryShardReference.perform(TransportReplicationAction.java:916) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.ReplicationOperation.execute(ReplicationOperation.java:108) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.TransportReplicationAction$AsyncPrimaryAction.runWithPrimaryShardReference(TransportReplicationAction.java:393) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.TransportReplicationAction$AsyncPrimaryAction.lambda$doRun$0(TransportReplicationAction.java:315) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:62) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.index.shard.IndexShard.lambda$wrapPrimaryOperationPermitListener$21(IndexShard.java:2753) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.ActionListener$3.onResponse(ActionListener.java:112) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.index.shard.IndexShardOperationPermits.acquire(IndexShardOperationPermits.java:285) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.index.shard.IndexShardOperationPermits.acquire(IndexShardOperationPermits.java:237) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.index.shard.IndexShard.acquirePrimaryOperationPermit(IndexShard.java:2727) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.TransportReplicationAction.acquirePrimaryOperationPermit(TransportReplicationAction.java:857) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.TransportReplicationAction$AsyncPrimaryAction.doRun(TransportReplicationAction.java:311) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.support.replication.TransportReplicationAction.handlePrimaryRequest(TransportReplicationAction.java:274) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.xpack.security.transport.SecurityServerTransportInterceptor$ProfileSecuredRequestHandler$1.doRun(SecurityServerTransportInterceptor.java:228) [x-pack-security-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.common.util.concurrent.EsExecutors$DirectExecutorService.execute(EsExecutors.java:196) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.xpack.security.transport.SecurityServerTransportInterceptor$ProfileSecuredRequestHandler.lambda$messageReceived$0(SecurityServerTransportInterceptor.java:277) [x-pack-security-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:62) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.xpack.security.authz.AuthorizationService.authorizeSystemUser(AuthorizationService.java:376) [x-pack-security-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.xpack.security.authz.AuthorizationService.authorize(AuthorizationService.java:184) [x-pack-security-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.xpack.security.transport.ServerTransportFilter.lambda$inbound$1(ServerTransportFilter.java:112) [x-pack-security-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:62) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.lambda$authenticateAsync$2(AuthenticationService.java:246) [x-pack-security-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.lambda$lookForExistingAuthentication$6(AuthenticationService.java:306) [x-pack-security-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.lookForExistingAuthentication(AuthenticationService.java:317) [x-pack-security-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.xpack.security.authc.AuthenticationService$Authenticator.authenticateAsync(AuthenticationService.java:244) [x-pack-security-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.xpack.security.authc.AuthenticationService.authenticate(AuthenticationService.java:139) [x-pack-security-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.xpack.security.transport.ServerTransportFilter.inbound(ServerTransportFilter.java:103) [x-pack-security-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.xpack.security.transport.SecurityServerTransportInterceptor$ProfileSecuredRequestHandler.messageReceived(SecurityServerTransportInterceptor.java:284) [x-pack-security-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.transport.RequestHandlerRegistry.processMessageReceived(RequestHandlerRegistry.java:63) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.transport.TransportService$7.doRun(TransportService.java:724) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:769) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
    at java.lang.Thread.run(Thread.java:834) [?:?]

这个失败似乎是相关的: https :

#45605 重复?

另一个构建失败,似乎是相关的: https :

另一个: https :

@original-brownbear 看起来这仍然导致构建失败。 有什么想法吗 ?

@atorok团队正在调查这个,今天早上。

我们解释了为什么创建索引可能会导致resource_already_exists_exception响应。 默认情况下,如果在 30 秒内没有收到响应,正在使用的HttpAsyncClient将重试。 我们观察到 CI 机器停止一段时间的情况,导致创建索引需要超过 30 秒(回想一下,它不仅创建索引,还等待主索引启动)。 这会触发客户端的重试,但第二次尝试发现第一次尝试已经创建了索引并返回我们看到的resource_already_exists_exception

我们可以通过在索引创建完成后等待客户端超时来重现这一点:

diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java b/server/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java
index 9bfbec9..1dc3163 100644
--- a/server/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java
+++ b/server/src/main/java/org/elasticsearch/cluster/metadata/MetaDataCreateIndexService.java
@@ -215,6 +215,11 @@ public class MetaDataCreateIndexService {
                         } else {
                             logger.trace("[{}] index created and shards acknowledged", request.index());
                         }
+                        try {
+                            Thread.sleep(30000);
+                        } catch (InterruptedException e) {
+                            throw new AssertionError(e);
+                        }
                         listener.onResponse(new CreateIndexClusterStateUpdateResponse(response.isAcknowledged(), shardsAcknowledged));
                     }, listener::onFailure);
             } else {

我们可以延长客户端的超时时间来解决这个问题,我认为最好阻止它重试,以免我们在下一次经历同样令人困惑的调查。 然而,根本问题是为什么在 CI 中创建索引需要超过 30 秒。

我们详细调查的那个在第一次创建索引时花费了大约 6 秒的时间将元数据写入磁盘(通过TRACE记录的MetaStateService )然后大约 4 秒应用生成的集群状态和然后大约 22 秒才能真正启动主。 缓慢的元数据写入表明 CI 工作线程上的 IO 存在问题。

打开https://github.com/elastic/elasticsearch/pull/46455暂时加倍超时。 就我所见,禁用重试有点棘手,因为我们进行了一些节点重启等测试,如果我们开始在单个节点上精确定位请求停止,我不知道这是否会立即生效重试。

缓慢的元数据写入表明 CI 工作线程上的 IO 存在问题。

这只是并行运行许多 ES 节点和测试的 IO 争用。 我们限制了这个_somewhat_,但我们被构建中的一些限制所束缚。 这应该会在 Gradle 6.0 中得到改进,因为我们将能够为启动测试节点定义明确的许可。 现在 Gradle 将测试任务旋转 3 个节点视为与旋转单个节点的任务相同,这可能会导致问题。

@mark-vieira ,在我深入研究的所有情况下,也在#46144 中,看起来有并发的 gradle 任务构建发行版等,例如这些(来自 #46144):

18:33:18 > Task :distribution:archives:buildNoJdkDarwinTar
18:33:29 > Task :test:fixtures:krb5kdc-fixture:composeDown
18:33:36 > Task :distribution:packages:buildDeb
18:33:38 > Task :distribution:archives:buildNoJdkLinuxTar

原因可能是并行测试活动或我们在测试期间执行这些高吞吐量 IO 操作的事实。 我认为我们的大多数休息风格测试对 IO 并没有那么重,并且认为那些通过 IO 相互干扰的可能性很小。 这是一种预感,而不是经过验证的声明。 但是我认为在测试时尝试避免构建发行版值得尝试看看这是否可以解决问题。

我有点担心将其写为 IO 争用,并担心 CI 还存在其他一些影响它或使其变得更糟的问题,主要是因为:

  1. 它发生在过去
  2. 我们已经用--parallel了很长一段时间,我本来希望它会早点浮出水面
  3. 我不是 100% 确定,但我认为在使用--parallel运行之前,我们在 bwc 测试中通过 @original-brownbear 看到了这一点

我不是 100% 确定,但我认为在使用 --parallel 运行之前,我们在 bwc 测试中通过 @original-brownbear 看到了这一点

是的,在我想到之前,我们确实看到了非并行构建的这个问题。 但这不一定是出乎意料的 IMO(只是不太可能)。

我认为对于我们目前看到的情况(激活了更好的日志记录),IO 争用是原因。 如果还有其他问题,我想这些问题会及时浮出水面,一旦我们解决了明显的 IO 问题,我们就会更轻松地追踪它们? :)

我并不是说 IO 争用不是真实的,而且绝对不想破坏派对,这是一个很棒的发现。 如果这是唯一的问题就好了,我只是认为我们还不需要放松警惕。

另一个数据点:在启用并行之前,我运行了大量测试,其中一些是在具有更高并行级别(在相同磁盘大小上)的较大实例上进行的,并且从未遇到过此问题,也没有其他与此相关的故障,构建成功,只是改进太小,无法证明成本是合理的。

我正在本地运行一些测试,并恢复您的更改以尝试在标准实例和一些本地 SSD 上重现这一点。

另一方面,没有证据表明这种情况发生在我们不使用--parallel运行的非主分支上

这是checkPart1的 GCP 控制台的一些屏幕截图(失败没有重现)。

更新:这是在 300GB 磁盘上,而 CI 使用 150GB 磁盘。

centos

centos

Ubuntu 14

ubuntu14

Ubuntu 18

ubuntu18

同样在本地 SSD 上运行

更新:这是在 300GB 磁盘上,而 CI 使用 150GB 磁盘。

centos

centos

Ubuntu 14

ubuntu14

Ubuntu 18

ubuntu18

附带说明一下,在本地 ssd 上运行可节省约 5 分钟的构建时间(约 16%)

我还在 ramdisk 上运行一些测试。
根据当前 CI 的结构,我们可能也可以切换到 ramdisk,并且设置起来也可能更容易

建立在 ramdisk 上可节省约 7 分钟(约 23%),并且具有从等式中完全消除磁盘 io 的优势。

这听起来很棒,是 PR 和摄入量构建的一个很好的解决方案。

我想知道是否仍然保持一些针对 SSD 运行的作业是否有意义,以确保我们也针对存储运行集成测试,但可预测性较低且时间较慢。 例如, testAckedIndexing在 RAM 磁盘与 SSD 上的表现可能不那么混乱,这可能是依赖此类测试结果的问题。

我同意 Elasticsearch CI 的 _all_ 在 RAM 磁盘上运行是危险的。 我们最终可能会交付经常失败的软件,而这种存储是生产中每个人都会使用的。

我们有一个操作系统可比性矩阵。 我认为这将是继续针对真实磁盘运行并以最小优化(可能在较低的并行级别)运行的正确位置。
大多数其他测试可以继续使用它,但我正在努力只为使用--parallel运行启用它,所以现在这将只针对 master 的入口和公关。

在过去的几个小时里,我一直在循环中运行checkPart1并且看起来 IO 并没有饱和。 似乎有短暂的峰值,但没有任何迹象表明它已经饱和了几秒钟。
这似乎在 ubuntu 上比在 centos 上发生得更多(在 50 次失败中只有一个在 centos 上)所以在构建运行时启动某些东西(例如检查更新)并不是不可能的。 将它推到边缘必须是相当 IO 密集型的。

@original-brownbear 您认为一旦我们开始在 ramdisk 上运行,我们是否应该恢复增加的超时时间? 至少暂时考虑一下你来自 Pr 的评论。 如果磁盘 IO 不是整个故事,这可能会使“其他东西”更难以检测。

@mark-vieira 我的测试中没有启用 Gradle 缓存,你认为它会增加大量的 IO 开销吗?

您认为一旦我们开始在 ramdisk 上运行,我们是否应该恢复增加的超时时间? 至少暂时考虑一下你来自 Pr 的评论。 如果磁盘 IO 不是整个故事,这可能会使“其他东西”更难以检测。

我可以回到30s (甚至可以降低到20s因为我们有很多地方,其中内部超时为30s用于主操作和30s是字面上最难解释的价值 IMO)。

我更愿意在恢复到 30 秒时禁用重试,这将使其失败更加干净。 我认为推动较低的超时限制是在我们不需要它的时候(现在)要求额外的麻烦,一旦这一切都解决了,我们可以在不同的时间(如果有的话)追求它。

我开始使用-Dscan.capture-task-input-files --build-cache运行,第一次尝试失败了 2 次(这是过去 4 小时内没有失败的同一个哈希)。 奇怪的是 GCP 控制台同时停止更新,所以不确定我们在磁盘 io 上的位置。

此外,在 ramdisk 上运行似乎不会在 CI(在本地 CI 设置中测试)中产生显着的节省(约 3 分钟或更短),这是启用缓存的情况。

另一件事要指出的是来自 GCP:

但是,为了确保启动设备更广泛使用的一致性能,> 使用 SSD 永久磁盘作为启动磁盘或使用标准永久磁盘
大小至少为 200 GB。

查看 build-stats 问题仅在 8 月 8 日开始出现。
磁盘大小在 8 月 2 日在 elastic/ infra@44757b9f94 中减少,我们在 15 日添加了-Dscan.capture-task-input-files ,当天故障数量激增。

我的工作理论是这两个操作结合在一起降低了磁盘性能。

@mark-vieira 如果 Gradle 在缓存的项目目录之外的任何地方写入,我们也应该将它添加到 ramdisk。

不幸的是,我运行的测试不是很具有代表性,因为我使用的脚本没有更新并且使用的是300 GB 磁盘,是 CI 在150GB使用的两倍

查看scan.capture-task-input-files的文档后,它似乎没有做任何 IO 密集型的事情,并且运行测试证实了这一点,所以不确定是什么导致了当天的峰值,也许只是降低了 GCP 上的磁盘 IO日 ? 提交似乎是一个巧合。

总之

  • 摄入量和 PR 检查现在在 ramdisk 中运行(弹性/基础设施#14376)
  • CI 中的磁盘大小增加回 350GB (elastic/infra#14379)
  • 本地 gradle 缓存已移动,因此它也将位于 ramdisk (#46486)

这是在 ubuntu 18 上的运行。第一个是scan.capture-task-input-files ,第二个没有。
ubuntu2
ubunut1

它似乎并不比300GB磁盘差,可能是因为 vCPU 的数量也有影响。

scan.capture-task-input-files主要只会影响构建扫描有效负载的大小。 它不应该产生任何额外的 IO,因为无论是否启用该选项,Gradle 都必须对输入文件进行快照。

就构建缓存的 IO 使用而言,它肯定会增加。 对于每次构建缓存未命中,我们都会打包输出并将其发送到远程缓存。 我们在这里可以做的一件事是禁用推送到 CI 中的本地缓存,因为我们使用的是临时工作人员。 这将有助于解决与构建上的缓存未命中相关的开销,否则不会推送(PR 构建)。

但是我认为在测试时尝试避免构建发行版值得尝试看看这是否可以解决问题。

我们可以通过排序规则尽早构建所有分布来帮助这种情况。

自从引入 ram 磁盘以来,似乎没有出现任何故障:tada:

@mark-vieira 在构建过程中或在构建结束时执行缓存实现推送。 如果有一种方法可以延迟它,这样它就不会干扰它,那就太好了。

@mark-vieira 在构建过程中或在构建结束时执行缓存实现推送。 如果有一种方法可以延迟它,这样它就不会干扰它,那就太好了。

缓存推送发生在每个任务的执行结束时,因此它会随着构建的进行而发生。 因为它是任务执行的一部分,所以它实际上受到现有并行性的限制。 禁用本地缓存后,这里的额外 IO 应该是最小的,因为我们已经构建了输出,并且 Gradle 将结果流式传输到远程服务器。 唯一的 IO 开销是读取的形式,无论如何,这可能会受到网络 IO 到远程缓存的瓶颈。 据我所知,它主要是编写 IOPS 伤害测试。

换句话说,我怀疑与构建/测试本身相比,添加远程构建缓存的 IO 开销可以忽略不计。 我过去做过实验也证实了这种怀疑。

不确定那些是相同的失败@matriv更有可能是那个特定的测试。 我建议我们为它打开一个不同的问题并静音

我将继续并关闭此问题以避免混淆。
移动到内存磁盘后,这在一个多星期内没有再次发生。
@original-brownbear 如果您愿意,我们可以在不同的票证中跟踪从客户端删除重试的情况。 这就是我最初打开这个的原因。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

rpalsaxena picture rpalsaxena  ·  3评论

DhairyashilBhosale picture DhairyashilBhosale  ·  3评论

matthughes picture matthughes  ·  3评论

abrahamduran picture abrahamduran  ·  3评论

ttaranov picture ttaranov  ·  3评论