sofastack / sofa-jraft

A production-grade java implementation of RAFT consensus algorithm.
https://www.sofastack.tech/projects/sofa-jraft/
Apache License 2.0
3.56k stars 1.14k forks source link

不同 Raft 集群非预期通信导致 Raft 状态异常 #1012

Closed luckyxiaoqiang closed 10 months ago

luckyxiaoqiang commented 1 year ago

Describe the bug

我们的应用使用 JRaft 作为持久化模块,部署在 K8S 中(Statefulset)。Raft 集群节点之间通过 K8S headless 域名通信。应用存在多租户场景,同一个 K8S 集群中会部署多个应用集群。

当应用的多个集群同时滚动更新时,Pod IP 会变动,可能原先 A 集群中节点 IP,滚动更新后被分配到了 B 集群中的节点。 滚动更新前: Pod IP
app-cluster-a-0 10.10.10.10
app-cluster-a-1 10.10.10.11
app-cluster-a-2 10.10.10.12
app-cluster-b-0 10.10.20.10
app-cluster-b-1 10.10.20.11
app-cluster-b-2 10.10.20.12
滚动更新后: Pod IP
app-cluster-a-0 10.10.10.13
app-cluster-a-1 10.10.10.11
app-cluster-a-2 10.10.10.12
app-cluster-b-0 10.10.10.10
app-cluster-b-1 10.10.20.11
app-cluster-b-2 10.10.20.12

更新前 app-cluster-a-0 的 IP 10.10.10.10 在更新后被分配给了 app-cluster-b-0。

由于域名解析存在延迟,包括 JVM、GRPC、K8S CoreDNS 等各个层面,更新后集群 a 中的节点(app-cluster-a-1 或 app-cluster-a-2)通过域名连接 app-cluster-a-0 时,实际可能连接到 app-cluster-b-0 节点。会带来的 2 大问题:

问题与 Issue https://github.com/sofastack/sofa-jraft/issues/683 有些类似,但 PR https://github.com/sofastack/sofa-jraft/pull/690 并不能彻底解决我们面临的问题。

Expected behavior

期望 JRaft 能够解决 DNS 解析延迟带来的问题:

Actual behavior

不同 Raft 集群非预期通信导致 Raft 状态异常

Steps to reproduce

Minimal yet complete reproducer code (or GitHub URL to code)

Environment

killme2008 commented 1 year ago
  1. jraft 当然有严格校验 cluster 和peer
  2. DNS 延迟不是一个类库能完全解决的,操作系统, jvm 都可能去缓存这个信息,我觉的你们更应该想的是怎么去避免这种 ip 的短期复用。
luckyxiaoqiang commented 1 year ago
  1. jraft 当然有严格校验 cluster 和peer
  2. DNS 延迟不是一个类库能完全解决的,操作系统, jvm 都可能去缓存这个信息,我觉的你们更应该想的是怎么去避免这种 ip 的短期复用。
  1. 部分场景没有严格校验,比如 RouteTable.refreshLeader。
  2. 应用层或部署环境,是可以去做一些工作来尽量避免 IP 短期复用问题的,但也期望类库能够在连接到错误集群时能够及时收敛。
killme2008 commented 1 year ago
  1. Good catch! 可以提个修复
  2. 应用层或部署环境,是可以去做一些工作来尽量避免 IP 短期复用问题的 —— 这才是根本解决办法。