一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

MongoDB分片集群如何优雅地重启分片节点

时间:2026-07-13 09:31:56 编辑:袖梨 来源:一聚教程网

不能直接重启单个shard节点,因其属于副本集,强制重启会触发选举、中断chunk迁移、导致mongos路由表错乱或返回stale数据。

分片节点可以单独重启,但直接 db.shutdownServer() 或 systemctl 重启会触发主从切换、中断 chunk 迁移、甚至让 mongos 路由表错乱——这不是“优雅”,是埋雷。

为什么不能直接重启单个 shard 节点?

分片节点属于副本集,单节点重启会强制触发一次 replica set election。如果该节点是 PRIMARY,选举期间写入失败;如果正在迁移 chunk,moveChunk 命令会卡住或回滚,后续 sh.status() 可能显示 chunkTooBigjumbo 标记;更隐蔽的问题是:mongos 缓存的路由信息可能未及时刷新,导致部分查询落到旧 primary 上,返回 stale 数据。

  • 必须确认该节点当前不是 PRIMARY(用 rs.status().myState 判断,值为 2 表示 SECONDARY)
  • 必须确保没有进行中的 moveChunk(查 db.adminCommand({listCurrentOperations: 1, $all: true}),过滤 "command": "moveChunk"
  • 如果它是 PRIMARY,先执行 rs.stepDown() 等待新 PRIMARY 选出并稳定(rs.status().members[n].stateStr === "PRIMARY"),再操作

真正安全的 shard 节点重启流程

不是“重启一个节点”,而是“在副本集上下文中可控地替换一个成员”。关键动作都在 admin 库下完成,不依赖外部进程管理器:

  • 连上目标节点(比如 mongo --host shard1-node2:27018),use admin
  • 运行 db.shutdownServer({force: false, timeoutSecs: 30}) —— force: false 防止强制终止活跃连接,timeoutSecs 给复制积压留出缓冲
  • 等该节点完全退出(检查进程或端口是否释放),再启动它(如果是 systemd,用 systemctl start mongod@shard1-node2,注意实例名别写错)
  • 启动后立刻验证:mongo --host shard1-node2:27018 --eval "rs.status().ok" 返回 1,且 rs.status().members[n].stateStrSECONDARYARBITER

云厂商控制台重启的隐藏陷阱

京东云、紫光云等控制台点“重启”按钮看似方便,但实际行为不可控:

  • 它调用的是底层 kill -15 + 二进制拉起,不走 MongoDB 内部关闭流程,moveChunk 可能被硬中断
  • Config Server 节点在多数云平台默认禁用重启按钮(文档明确写“分片集群不支持实例级别重启”),但控制台有时仍显示可点——点了就报 Failed to load config database
  • 重启后外网域名可能变更(尤其弹性 IP 未绑定时),应用连接字符串若写死域名,会静默失败

最常被跳过的环节是验证:重启完一个 shard 节点,必须跑 sh.status()chunks 分布是否均衡、balancer 是否仍在 off 状态、所有 shardok 字段是否为 1。漏掉这一步,问题往往在第二天凌晨流量高峰时才暴露。

热门栏目