我正在AWS中运行3.6.6版本的5节点Hazelcast集群。 我将其用作工作负载分配器,并且使用
IExecutorService
<T> void submit(Runnable task,
MemberSelector memberSelector,
ExecutionCallback<T> callback)
API,以对我选择的成员执行任务。我不使用基于分区的平衡,因为不同的分区将具有不同的权重。
启动群集后,它可以正常运行几天,然后提交成员开始接收OperationTimeoutException。一旦开始,所有成员都将开始接收此超时,并且它偶尔会发生,可能会在很短的时间内使所有工作顺利进行,然后再次开始发生此异常。目标成员会在不到一秒钟的时间内收到任务并正确执行。 异常本身看起来像这样:
2019年7月3日,世界标准时间10:54:01:
560000毫秒无响应。中止调用! 调用{serviceName ='hz:impl:executorService', op = com.hazelcast.executor.impl.operations.MemberCallableTaskOperation {identityHash = 1179024466, serviceName ='hz:impl:executorService',partitionId = -1,replicaIndex = 0, callId = 684145,invocationTime = 1562150679963(UTC Jul 03 10:44:39 UTC 2019),waitTimeout = -1,callTimeout = 500000,name = exec_service_3}, partitionId = -1,replicateIndex = 0,tryCount = 250,tryPauseMillis = 500, invokeCount = 1,callTimeout = 500000, target = Address [x.x.x.x]:5701,backupsExpected = 0, backupsCompleted = 0,连接=连接[/x.x.x.x:5701-> /x.x.x.x:35360],端点=地址[x.x.x.x]:5701, alive = true,类型= MEMBER}未收到响应! backups-expected:0备份已完成:0,执行时间:3445 毫秒
Stacktrace:
at com.hazelcast.spi.impl.operationservice.impl.Invocation.newOperationTimeoutException(Invocation.java:536) ~[anodot-arnorld-1.0-SNAPSHOT.jar:na]
at com.hazelcast.spi.impl.operationservice.impl.IsStillRunningService$IsOperationStillRunningCallback.setOperationTimeout(IsStillRunningService.java:241)
at com.hazelcast.spi.impl.operationservice.impl.IsStillRunningService$IsOperationStillRunningCallback.onResponse(IsStillRunningService.java:229)
at com.hazelcast.spi.impl.operationservice.impl.InvocationFuture$1.run(InvocationFuture.java:127)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at com.hazelcast.util.executor.HazelcastManagedThread.executeRun(HazelcastManagedThread.java:76) [anodot-arnorld-1.0-SNAPSHOT.jar:na]
at com.hazelcast.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:92)
at ------ End remote and begin local stack-trace ------.(Unknown Source) ~[na:na]
... 8 frames truncated
例外的时间很奇怪:
July 3rd 2019, 10:53:57.956 - task submitted for execution by sending instance
July 3rd 2019, 10:53:58.024 - execution starts on target instance
July 3rd 2019, 10:54:01.391 - the sending instance receives the exception
在我的日志中,我看到超时是在任务提交后不久发生的,“执行已执行:”部分是非常精确的,在引用的情况下,确实是从任务发送到执行以来经过的时间是大约3.5秒。另一方面,引用时间中的“ invocationTime”(UTC 2019年7月3日星期三 10:44:39 )大约是过去的10分钟,甚至在实际提交执行任务之前(2019年7月3日,10:53:57 UTC)
我已经看到此异常归因于长时间的GC暂停,但是当我不断监视GC时,我确定情况并非如此。此外,集群成员之间的联网看起来非常活跃,延迟很短。
根据我在Hazelcast代码中看到的内容,“ invocationTime”是从“ clusterClock”中获取的,而不是直接从系统时间中获取的,这表明出于某种原因群集时钟已关闭10分钟,但我无法弄清楚为什么会这样。群集非常繁忙,但是当此异常开始发生时,我看不到任何异常的负载激增。 当我卸下整个群集然后重新启动时,问题消失了。 我计划在clusterTime上添加监视,以查看它何时开始漂移,但仍将无法解释为什么会发生这种情况。 有什么想法吗?
更新: 简而言之,群集时间从系统时间开始随时间漂移,并且一旦差距足够大,任务就会因超时异常而开始失败。 有关详细信息:https://github.com/hazelcast/hazelcast/issues/15339
答案 0 :(得分:0)
最后,通过将 Hazelcast 版本升级到 3.12.11(4.x.x 破坏了太多东西)解决了这个问题,看起来集群时间的管理方式对 GC 暂停不敏感。一些 API 被破坏了,需要在代码中进行调整,没什么大不了的。警告说明,3.6.6 与 3.12.11 不兼容,因此无法进行滚动集群升级。我们进行了一次完整的集群重启,幸运的是,这是可能的。