问题描述
我有一个应用程序使用 marathon-api 和 ClusterBootstrap 部署 Akka 集群
当部署运行时,它会执行以下操作:
我们有一个由 4 个节点组成的集群
在进行部署后,集群看起来像这样(在这个例子中假设有 2 个实例):
{
"leader": "akka.tcp://app@ip-10-0-5-15.eu-central-1.compute.internal:13655","members": [
{
"node": "akka.tcp://app@ip-10-0-4-8.eu-central-1.compute.internal:15724","nodeUid": "-1598489963","roles": [
"dc-default"
],"status": "Up"
},{
"node": "akka.tcp://app@ip-10-0-5-15.eu-central-1.compute.internal:13655","nodeUid": "-1604243482","status": "Up"
}
],"oldest": "akka.tcp://app@ip-10-0-4-8.eu-central-1.compute.internal:15724","oldestPerRole": {
"dc-default": "akka.tcp://app@ip-10-0-4-8.eu-central-1.compute.internal:15724"
},"selfNode": "akka.tcp://app@ip-10-0-5-15.eu-central-1.compute.internal:13655","unreachable": [
{
"node": "akka.tcp://app@ip-10-0-4-8.eu-central-1.compute.internal:15724","observedBy": [
"akka.tcp://app@ip-10-0-5-15.eu-central-1.compute.internal:13655"
]
}
]
}
有时leader仍然是WeaklyUp,但想法是一样的,而消失的节点可以是up或Leaving。
然后日志开始显示此消息:
Cluster Node [akka.tcp://app@ip-10-0-5-15.eu-central-1.compute.internal:13655] - leader can currently not perform its duties,reachability status: [akka.tcp://app@ip-10-0-5-15.eu-central-1.compute.internal:13655 -> akka.tcp://app@ip-10-0-4-8.eu-central-1.compute.internal:15724: Unreachable [Unreachable] (1)],member status: [
akka.tcp://app@ip-10-0-4-8.eu-central-1.compute.internal:15724 Up seen=false,akka.tcp://app@ip-10-0-5-15.eu-central-1.compute.internal:13655 Up seen=true]
部署更多次会使情况变得更糟
我想当一个节点被杀死时,它会改变集群的状态,因为它实际上无法访问,但我希望可以有某种功能可以解决这个问题
到目前为止,唯一可以解决此问题的方法是使用 Akka Cluster HTTP Management 执行 PUT /cluster/members/{address} operation:Down
我知道有一个名为 Auto-downing
的功能被删除了,因为它弊大于利。
我也尝试了 Split Brain Resolver 使用那里提供的策略,但最终这些策略最终导致整个集群宕机,日志如下:
> Cluster Node [akka://app@ip-10-0-5-215.eu-central-1.compute.internal:43211] - leader can currently not perform its duties,reachability status: [akka://app@ip-10-0-5-215.eu-central-1.compute.internal:43211 -> akka://app@ip-10-0-4-146.eu-central-1.compute.internal:2174: Unreachable [Unreachable] (1)],member status: [akka://app@ip-10-0-4-146.eu-central-1.compute.internal:2174 Up seen=false,akka://app@ip-10-0-5-215.eu-central-1.compute.internal:43211 Up seen=true]
> Running CoordinatedShutdown with reason [ClusterDowningReason]
> SBR is downing
> SBR took decision DownReachable and is downing
也许我没有用正确的配置设置正确的策略,但我不知道该尝试什么,同样我有一个 4 节点集群,所以我猜默认的 Keep Majority
应该这样做,尽管这案例与其说是网络分区,不如说是一个崩溃的节点
有没有办法使用 marathon-api 顺利部署 Akka 集群?我愿意接受建议
更新:
我还将 Akka 版本从 2.5.x
更新到 2.6.x
,文档指出它不兼容,因此我需要手动干预第一次部署。最后使用默认配置的 Split Brain Resolver 确实有效
解决方法
您需要使用像 Split Brain Resolver 这样的“真正的”downing 提供程序。这让集群可以安全地关闭无法访问的节点。 (与自动停机相反,它在不考虑安全与否的情况下将它们停机。)
还有一个单独的问题,即为什么 DC/OS 如此迅速地杀死节点,以至于他们没有机会正确关闭。但我不太了解 DC/OS,无法说明为什么会这样。而且,无论如何,停机提供程序对于集群环境至关重要,因此无论如何您都希望将其部署到位。
根据您对 SBR 的评论进行编辑:
- 首先我想澄清一下,marathan-api 在这里几乎可以肯定是无关紧要的。 marathon-api 是节点发现 DC/OS 中其他节点的方式。您遇到的问题是基本的集群问题,即无法访问的节点。具有无法访问节点的集群将以相同的方式运行,无论它在哪里运行以及节点是如何被发现的。
- 从根本上说,我最好的猜测是您在完全关闭时遇到了问题。如果 SBR 使您的整个集群宕机,那是因为无法访问的节点数量超过了实时集群。
举个例子,可能会发生什么:
- 您有 4 个活动节点并且想要升级。
- DC/OS 终止第一个节点。由于某些未知原因,您没有完全关闭,因此该节点被标记为无法访问。 (本质上是集群,因为它不是完全关闭,如果节点仍然存在但没有响应和/或在分区后面,则不会节点。)有 3 个活动节点和一个无法访问。
- DC/OS 启动第二个节点。也许启动您的应用程序需要一些时间。因此,您有 3 个活动节点、1 个无法访问的节点和 1 个未就绪节点。
- DC/OS 杀死了另一个节点。因此,您有 2 个活动节点、2 个无法访问的节点和 1 个未就绪节点。此时 SBR 不能再保证您没有网络分区,因为您没有多数。此时,为了防止损坏,必须停止集群。
所以,我会推荐以下内容:
- 我不太了解 DC/OS 的详细信息,但您可能需要放慢滚动升级的速度。在 K8S 中,我会使用类似 MinReadySeconds 的东西。
- 您可能需要考虑第五个节点。奇数更好,因为它更容易确定多数。
- 如果您仍然遇到问题,则需要提供更多来自 SBR 决定的日志。
SBR 就是答案。我意识到您没有真正的网络分区,但是您拥有无法访问的节点这一事实意味着 Akka 集群无法判断是否存在网络分区,这就是问题的根本原因。