You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

滚动升级Cassandra集群时出现异DC及非Cassandra节点异常问题

Cassandra跨集群合并与虚假节点问题排查与修复

问题背景

对6节点Cassandra集群(DC1)执行滚动升级时,nodetool status出现异常:

  • 显示来自另一个数据中心(DC2)的UN状态节点
  • 显示来自不存在的DC3的DN状态非Cassandra节点

DC1与DC2初始部署正常,此前nodetool status无异常,可正常存储数据。集群配置细节:

  • DC1使用3个奇数编号节点作为种子,DC2种子节点与DC1完全不同
  • DC1与DC2的cluster_name完全相同,推测这是问题根源

核心疑问

  • DC2为何会加入DC1?开发环境如何复现该问题?曾尝试相同cluster_name的双集群场景,但未触发该问题。
  • 为何会显示来自虚假DC的非Cassandra节点?
  • 为何问题在滚动升级后才显现,初始部署时无异常?
  • 最佳修复方案是什么?

实际命令输出

nodetool status输出

# nodetool status
Datacenter: DC1
=========================================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address         Load       Tokens       Owns    Host ID                               Rack
UN  IP_1_DC_1  4.87 GiB   256          ?       aaaaaaaa-ffff-ffff-ffff-gggggggggggg  RAC2
UN  IP_2_DC_1  6.66 GiB   256          ?       bbbbbbbb-ffff-ffff-ffff-gggggggggggg  RAC3
UN  IP_3_DC_1  5.28 GiB   256          ?       cccccccc-ffff-ffff-ffff-gggggggggggg  RAC1
UN  IP_4_DC_1  9.55 GiB   256          ?       dddddddd-ffff-ffff-ffff-gggggggggggg  RAC2
UN  IP_5_DC_1  6.32 GiB   256          ?       eeeeeeee-ffff-ffff-ffff-gggggggggggg  RAC1
UN  IP_6_DC_1  6.47 GiB   256          ?       ffffffff-ffff-ffff-ffff-gggggggggggg  RAC3
Datacenter: DC3
=========================================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address         Load       Tokens       Owns    Host ID                               Rack
DN  IP_1_DC_3   11.99 GiB  256          ?       gggggggg-ffff-ffff-ffff-gggggggggggg  RAC3
DN  IP_2_DC_3   12.66 GiB  256          ?       hhhhhhhh-ffff-ffff-ffff-gggggggggggg  RAC1
DN  IP_3_DC_3   12.57 GiB  256          ?       iiiiiiii-ffff-ffff-ffff-gggggggggggg  RAC2
DN  IP_4_DC_3   12.63 GiB  256          ?       jjjjjjjj-ffff-ffff-ffff-gggggggggggg  RAC2
DN  IP_5_DC_3   13.1 GiB   256          ?       kkkkkkkk-ffff-ffff-ffff-gggggggggggg  RAC3
Datacenter: DC2
=========================================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address         Load       Tokens       Owns    Host ID                               Rack
UN  IP_1_DC_2   14.92 GiB  256          ?       llllllll-ffff-ffff-ffff-gggggggggggg  RAC1
UN  IP_2_DC_2   9.08 GiB   256          ?       mmmmmmmm-ffff-ffff-ffff-gggggggggggg  RAC2
UN  IP_3_DC_2   8.8 GiB    256          ?       nnnnnnnn-ffff-ffff-ffff-gggggggggggg  RAC2
UN  IP_4_DC_2   10.26 GiB  256          ?       oooooooo-ffff-ffff-ffff-gggggggggggg  RAC3
UN  IP_5_DC_2   9.59 GiB   256          ?       pppppppp-ffff-ffff-ffff-gggggggggggg  RAC1
UN  IP_6_DC_2   10.75 GiB  256          ?       qqqqqqqq-ffff-ffff-ffff-gggggggggggg  RAC3

Note: Non-system keyspaces don't have the same replication settings, effective ownership information is meaningless

nodetool describecluster输出

# nodetool describecluster
Cluster Information:
    Name: DSE-Cassandra-same-name
    Snitch: org.apache.cassandra.locator.GossipingPropertyFileSnitch
    DynamicEndPointSnitch: enabled
    Partitioner: org.apache.cassandra.dht.Murmur3Partitioner
    Schema versions:
        aaaaaaaa-cccc-cccc-cccc-bbbbbbbbbbbb: [IP_1_DC_1, IP_2_DC_1, IP_3_DC_1, IP_4_DC_1, IP_5_DC_1, IP_6_DC_1, IP_1_DC_2, IP_2_DC_2, IP_3_DC_2, IP_4_DC_2, IP_5_DC_2, IP_6_DC_2]

        UNREACHABLE: [IP_1_DC_3, IP_2_DC_3, IP_3_DC_3, IP_4_DC_3, IP_5_DC_3]

预期输出

# nodetool status
Datacenter: DC1
=========================================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address         Load       Tokens       Owns    Host ID                               Rack
UN  IP_1_DC_1  4.87 GiB   256          ?       aaaaaaaa-ffff-ffff-ffff-gggggggggggg  RAC2
UN  IP_2_DC_1  6.66 GiB   256          ?       bbbbbbbb-ffff-ffff-ffff-gggggggggggg  RAC3
UN  IP_3_DC_1  5.28 GiB   256          ?       cccccccc-ffff-ffff-ffff-gggggggggggg  RAC1
UN  IP_4_DC_1  9.55 GiB   256          ?       dddddddd-ffff-ffff-ffff-gggggggggggg  RAC2
UN  IP_5_DC_1  6.32 GiB   256          ?       eeeeeeee-ffff-ffff-ffff-gggggggggggg  RAC1
UN  IP_6_DC_1  6.47 GiB   256          ?       ffffffff-ffff-ffff-ffff-gggggggggggg  RAC3

问题解答

1. DC2为何加入DC1?如何复现?

Cassandra集群的核心识别标识是cluster_name,当两个集群cluster_name相同时,Gossip协议会认为它们属于同一集群。初始部署时未触发,可能是因为两个集群的网络隔离(比如防火墙限制Gossip端口7000/7001),或者种子节点未交叉指向,但滚动升级过程中,可能出现节点重启后临时的网络连通性变化,或者节点启动时意外发现了对方集群的节点,通过Gossip同步后合并。

复现步骤:

  • 搭建两个独立集群,设置相同cluster_name,使用GossipingPropertyFileSnitch
  • 确保两个集群网络互通(开放7000/7001端口)
  • 对其中一个集群执行滚动升级,逐个重启节点,观察nodetool status是否出现对方集群节点

2. 为何显示虚假DC3的非Cassandra节点?

这些节点是之前某个集群残留的Gossip元数据。可能是DC1曾与某个已销毁的集群(使用DC3标识)有过Gossip交互,元数据保存在本地系统表中。滚动升级时节点重启,加载了旧的Gossip数据,而由于这些节点已不可达,所以显示为DN状态。

3. 为何滚动升级后才显现?

初始部署时,两个集群的Gossip网络可能未连通(比如防火墙规则、节点启动顺序导致未发现对方)。滚动升级过程中,节点重启会重新发起Gossip探测,若此时网络连通性允许(比如临时开放了端口,或者路由变化),就会发现对方集群节点,触发合并。另外,升级过程中Cassandra版本变化可能导致Gossip协议行为调整,更容易发现跨集群节点。

4. 最佳修复方案

方案步骤:

  1. 立即隔离两个集群:关闭DC1和DC2之间的Gossip端口(7000/7001),防止进一步的元数据同步
  2. 修改其中一个集群的cluster_name:
    • 停止目标集群的所有节点
    • 修改cassandra.yaml中的cluster_name为新值
    • 启动节点时,添加参数-Dcassandra.allow_cluster_name_change=true(仅在启动时生效,用于覆盖系统表中存储的旧集群名称)
    • 验证nodetool describecluster显示新的集群名称
  3. 清理虚假DC3节点:
    • 在DC1的所有节点上执行nodetool removenode <host_id>,移除DC3的所有节点ID
    • 或者重启节点时使用-Dcassandra.reset_gossip=true,重置Gossip元数据(会暂时影响集群稳定性,需在维护窗口执行)
  4. 验证集群状态:执行nodetool status确认仅显示DC1节点,nodetool describecluster无异常节点

注意:修改cluster_name需要停机维护,需提前做好备份,选择业务低峰期执行。

内容的提问来源于stack exchange,提问作者FaresDZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 12:33:12