Scala Akka集群在EC2/docker上保存并不断存储关于成员资格的错误信息
环境:Scala Akka集群在EC2/docker上保存并不断存储关于成员资格的错误信息,scala,docker,amazon-ec2,akka-cluster,Scala,Docker,Amazon Ec2,Akka Cluster,环境:scala-2.11.x,akka-2.5.9 EC2上有两台主机:H1和H2。 sbt项目有三个树模块:master、client和worker。 每个模块实现akka集群节点,该节点订阅集群事件并记录它们。此外,每个节点每1分钟记录一次集群状态(用于调试)。以下端口用于群集节点:主节点:2551,工作节点:3000,客户端:5000 该项目可在 有关基础设施的更多详细信息: 模块可以在H1或H2中随机重新部署 阿克卡星系团有一种奇怪的行为。重新部署其中一个节点(例如工作者)时。以下步骤
scala-2.11.x
,akka-2.5.9
EC2上有两台主机:H1
和H2
。
sbt项目有三个树模块:master
、client
和worker
。
每个模块实现akka集群节点,该节点订阅集群事件并记录它们。此外,每个节点每1分钟记录一次集群状态(用于调试)。以下端口用于群集节点:主节点:2551
,工作节点:3000
,客户端:5000
该项目可在
有关基础设施的更多详细信息:
模块可以在H1
或H2
中随机重新部署
阿克卡星系团有一种奇怪的行为。重新部署其中一个节点(例如工作者
)时。以下步骤说明了部署的历史记录:
初始状态-当worker
部署在H1
和master
和client
部署在H2
----[state-of-deploying-0]---
H1 = [worker]
H2 = [master, client]
cluster status: // cluster works correctly
Member(address = akka.tcp://ClusterSystem@H1:3000, status = Up)
Member(address = akka.tcp://ClusterSystem@H2:2551, status = Up)
Member(address = akka.tcp://ClusterSystem@H2:5000, status = Up)
----------------
----[state-of-deploying-1]---
H1 = [-]
H2 = [master, client, worker (Redeployed)]
cluster status: // WRONG cluster state!
Member(address = akka.tcp://ClusterSystem@H1:3000, status = Up) // ???
Member(address = akka.tcp://ClusterSystem@H2:2551, status = Up)
Member(address = akka.tcp://ClusterSystem@H2:3000, status = WeaklyUp)
Member(address = akka.tcp://ClusterSystem@H2:5000, status = Up)
----------------
之后,worker
模块已重新部署到主机H2
----[state-of-deploying-0]---
H1 = [worker]
H2 = [master, client]
cluster status: // cluster works correctly
Member(address = akka.tcp://ClusterSystem@H1:3000, status = Up)
Member(address = akka.tcp://ClusterSystem@H2:2551, status = Up)
Member(address = akka.tcp://ClusterSystem@H2:5000, status = Up)
----------------
----[state-of-deploying-1]---
H1 = [-]
H2 = [master, client, worker (Redeployed)]
cluster status: // WRONG cluster state!
Member(address = akka.tcp://ClusterSystem@H1:3000, status = Up) // ???
Member(address = akka.tcp://ClusterSystem@H2:2551, status = Up)
Member(address = akka.tcp://ClusterSystem@H2:3000, status = WeaklyUp)
Member(address = akka.tcp://ClusterSystem@H2:5000, status = Up)
----------------
上述情况时有发生。在这种情况下,群集存储了错误的成员状态,并且不会修复它:
Member(address = akka.tcp://ClusterSystem@H1:3000, status = Up) // ???
主机H1
不包含worker
的任何实例。和>telnet H1 3000
返回拒绝连接
。
但是为什么akka集群一直存储错误的信息?这种行为是有意的,生产中的akka集群应该在没有自动关闭的情况下运行,以防止大脑分裂问题 设想一个具有两个客户端(X和Y)的双节点(a和B)集群:
- 开始时,一切正常,连接到
的B
请求可以转发到Y
上运行的a
进行远程处理Actor1
- 然后,由于网络分区,
无法从a
访问,B
可能会尝试将B
标记为关闭,并在本地重新启动a
Actor1
- 客户端
向运行在Y
B
- 网络分区另一端的客户端
仍连接到X
,并将向A
Actor1
- 如果你能负担得起,可以使用手动羽绒服。操作员将识别出集群确实已关闭,并将节点标记为无法访问
- 如果您的集群具有动态数量的节点,那么您需要一些复杂的东西,如Lightbend Split Brain解析器
- 如果集群是静态的,您可以使用仲裁策略来避免大脑分裂。您始终需要运行奇数个节点
- 开始时,一切正常,连接到
的B
请求可以转发到Y
上运行的a
进行远程处理Actor1
- 然后,由于网络分区,
无法从a
访问,B
可能会尝试将B
标记为关闭,并在本地重新启动a
Actor1
- 客户端
向运行在Y
B
- 网络分区另一端的客户端
仍连接到X
,并将向A
Actor1
- 如果你能负担得起,可以使用手动羽绒服。操作员将识别出集群确实已关闭,并将节点标记为无法访问
- 如果您的集群具有动态数量的节点,那么您需要一些复杂的东西,如Lightbend Split Brain解析器
- 如果集群是静态的,您可以使用仲裁策略来避免大脑分裂。您始终需要运行奇数个节点