故障模式运维手册:节点、网络、磁盘
凌晨 3 点出故障时,你需要的是一张表,而不是一本教科书。本页就是那张表。它把每一种基础设施故障模式——节点崩溃、网络分区、磁盘问题——映射到对应的数据丢失风险、可用性影响、恢复复杂度以及精确的修复步骤。贯穿全文的有三条规则:少数派故障会自愈,多数派故障需要你介入,而法定人数(quorum)就是二者的分界线。
如果想了解字节级别的内部机制——日志布局、term 文件、录制段(recording segments)——请参阅 The Aeron Files。本页是面向运维人员的手册,而非线格式(wire format)说明。
节点相关故障
Section titled “节点相关故障”先从集群本身说起。下面的模式贯穿每一行:丢失少数派,Aeron 会自行恢复;丢失多数派,则必须由你手动恢复法定人数。
| 情形 | 数据丢失风险 | 可用性影响 | 恢复复杂度 | 修复方案 |
|---|---|---|---|---|
| 单个 follower 崩溃 | 无 | 无(法定人数保持) | 低——自动追赶 | 重启节点;通过 snapshot + 从 leader 回放日志自动追赶 |
| 单个 leader 崩溃 | 未提交的消息 | 短暂(选举超时) | 低——自动选举 | 等待自动选举;重启崩溃节点以 follower 身份重新加入;客户端重连到新 leader |
| 多个节点崩溃(少数派) | 无 | 无(已无容错余量) | 低——自动追赶 | 尽快重启崩溃节点以恢复容错能力;监控法定人数健康状况 |
| 多个节点崩溃(多数派 / 法定人数丢失) | 未提交的消息 | 完全不可用,直至恢复 | 高——需手动介入 | 重启足够多的节点以恢复法定人数;若数据丢失,从最新 snapshot + 日志备份恢复 |
| 所有节点同时崩溃 | 可能丢失 | 完全不可用 | 高——snapshot + 日志恢复 | 冷启动所有节点;每个节点从本地 snapshot + 日志录制回放;若损坏,从外部备份恢复 |
- 少数派故障会自愈——Aeron 自动处理。
- 多数派故障需要手动介入——你必须恢复法定人数。
- “未提交的消息” 仅指 leader 已接受但尚未复制到多数派的消息——通常是一个非常小的时间窗口。
从外部备份恢复(第 4 个节点异步副本)
Section titled “从外部备份恢复(第 4 个节点异步副本)”当集群使用 Aeron Cluster Backup 将数据异步复制到第 4 个(非投票)节点时,可按以下流程从该外部备份恢复。
- 第 4 个节点运行
ClusterBackupagent,持续从活跃集群接收 snapshot 和日志段。 - 备份数据位置通过
ClusterBackup.Context配置(例如backupResponseChannel、backupDir)。 - 备份节点存储:最新 snapshot + 后续日志录制。
-
停止所有存活的集群节点(如果还有节点在运行),以防止脑裂(split-brain)。
-
定位第 4 个节点上的备份数据。
- 找到备份目录(在
ClusterBackup.Context.backupDir()中配置)。 - 验证最新 snapshot 和录制日志文件完好无损:
Terminal window # List snapshot and log recordings in the backup dirls -lah /path/to/backup-dir/# Use AeronStat or RecordingLog tool to inspect recording statejava -cp aeron-all.jar io.aeron.cluster.RecordingLog /path/to/backup-dir/
- 找到备份目录(在
-
将备份数据复制到每个集群节点。
- 对集群中的每个节点,用备份替换其损坏/丢失的数据:
Terminal window # On each cluster node, clear the old cluster dirrm -rf /path/to/node-X/cluster-dir/*# Copy snapshot + recording log from the 4th node backupscp -r backup-node:/path/to/backup-dir/* /path/to/node-X/cluster-dir/ - 确保每个节点上的文件归属和权限正确。
- 对集群中的每个节点,用备份替换其损坏/丢失的数据:
-
更新集群标记文件(如有需要)。
- 每个节点的
cluster-mark.dat必须反映正确的memberId。 - 如果恢复到相同节点且 member ID 不变,则无需改动。
- 如果节点身份发生变化,需相应更新集群配置。
- 每个节点的
-
先引导 leader 节点。
- 选一个节点先启动——它会回放 snapshot + 日志并成为初始 leader。
- 用以下命令启动:
Terminal window # Start the first node; it will replay snapshot and logsjava -cp your-app.jar <MainClass> --cluster-dir /path/to/node-0/cluster-dir/ - 等待它完全回放完毕并进入
LEADER状态(通过AeronStat或应用日志查看)。
-
启动其余 follower 节点。
- 逐个启动其他集群节点。
- 每个节点都会通过 snapshot 安装 + 日志回放从 leader 追赶:
Terminal window java -cp your-app.jar <MainClass> --cluster-dir /path/to/node-1/cluster-dir/java -cp your-app.jar <MainClass> --cluster-dir /path/to/node-2/cluster-dir/
-
验证集群健康状况。
- 确认所有节点已加入且法定人数已建立。
- 通过
AeronStat检查共识模块(consensus module)的计数器:Terminal window java -cp aeron-all.jar io.aeron.driver.status.AeronStat - 验证
LEADER和FOLLOWER角色分配正确。 - 运行应用级合理性检查(例如查询状态、检查序列号)。
-
重启第 4 个备份节点。
- 集群恢复健康后,在第 4 个节点上重启
ClusterBackup,使其从新 leader 恢复异步复制。
- 集群恢复健康后,在第 4 个节点上重启
- 数据缺口意识: 异步备份可能落后于实时集群。任何已被集群接受但尚未复制到备份节点的消息都会丢失。缺口大小取决于复制频率和网络延迟。
- 在将备份数据复制到所有节点之前,切勿启动集群节点——以各节点状态不一致的方式启动可能导致进一步损坏。
- snapshot 一致性: 务必将完整的 snapshot 与其对应的日志录制一同使用。切勿混用不同时间点的 snapshot 和日志。
- 定期在非生产环境中演练此流程,以验证 RTO/RPO 目标。
备份节点自身的备份
Section titled “备份节点自身的备份”第 4 个备份节点本身是灾难恢复中的单点故障。如果在集群也宕机的同时备份节点的磁盘损坏,你就失去了最后的退路。建议的做法是在 Aeron ClusterBackup agent 之上叠加一层外部的、持久化的存储。
建议做法:定期将 snapshot 归档到对象存储
Section titled “建议做法:定期将 snapshot 归档到对象存储”推荐的策略是定期将备份节点的 snapshot + 录制日志文件归档到持久化的外部存储(例如 AWS S3、GCS、Azure Blob Storage 或远程 NFS/SAN)。
- Aeron
ClusterBackup持续将最新的 snapshot 和日志段从集群复制到第 4 个节点的本地磁盘——这是实时且自动的。 - 备份节点上的定时任务(cron、systemd timer 或应用级调度器)定期将一份一致的时间点 snapshot 包复制到对象存储。
- 保留策略保留 N 份近期归档,清理较旧的归档以控制存储成本。
#!/bin/bash# backup-to-s3.sh — runs periodically via cron on the 4th backup node
BACKUP_DIR="/path/to/backup-dir"S3_BUCKET="s3://your-bucket/aeron-cluster-backups"TIMESTAMP=$(date +%Y%m%dT%H%M%S)ARCHIVE_NAME="cluster-backup-${TIMESTAMP}.tar.gz"STAGING_DIR="/tmp/aeron-backup-staging"
# 1. Pause ClusterBackup agent (optional but recommended for consistency)# Alternatively, take a filesystem-level snapshot (LVM, ZFS, EBS snapshot)# if pausing is not acceptable
# 2. Create a consistent copy of the backup directorymkdir -p "$STAGING_DIR"cp -a "$BACKUP_DIR" "$STAGING_DIR/backup-snapshot"
# 3. Resume ClusterBackup agent (if paused in step 1)
# 4. Compress and upload to S3tar -czf "/tmp/${ARCHIVE_NAME}" -C "$STAGING_DIR" backup-snapshotaws s3 cp "/tmp/${ARCHIVE_NAME}" "${S3_BUCKET}/${ARCHIVE_NAME}"
# 5. Clean up stagingrm -rf "$STAGING_DIR" "/tmp/${ARCHIVE_NAME}"
# 6. Prune old backups — keep last 7 daysaws s3 ls "${S3_BUCKET}/" | awk '{print $4}' | sort | head -n -7 | \ xargs -I {} aws s3 rm "${S3_BUCKET}/{}"
echo "Backup archived: ${S3_BUCKET}/${ARCHIVE_NAME}"通过 cron 调度(例如每 6 小时一次):
0 */6 * * * /opt/scripts/backup-to-s3.sh >> /var/log/aeron-backup-archive.log 2>&1| 方案 | 优点 | 缺点 |
|---|---|---|
| 对象存储归档(推荐) | 持久、带版本、廉价,内置跨区域复制 | 存在轻微的 RPO 缺口(两次归档之间的时间) |
| EBS/磁盘级 snapshot | 文件系统一致、快速、无需应用级脚本 | 与云厂商绑定;snapshot 恢复需要时间 |
| ZFS/LVM snapshot + 复制 | 近乎瞬时的一致 snapshot;可复制到远程 | 需要 ZFS/LVM 搭建;运维复杂度更高 |
| rsync 到远程主机 | 简单,使用标准工具 | 非原子操作——若备份正在写入,可能复制到不完整的状态 |
| 第二个备份节点(第 5 个节点) | Aeron 层面的完全冗余,无需脚本 | 备份基础设施成本翻倍;灾难恢复仍需异地副本 |
一致性注意事项
Section titled “一致性注意事项”- 最佳选择: 在
ClusterBackup运行期间使用文件系统级 snapshot(EBS snapshot、ZFS snapshot、LVM snapshot)——这能在不暂停复制的情况下,得到一份崩溃一致(crash-consistent)的时间点副本。 - 良好选择: 短暂暂停
ClusterBackupagent,执行cp -a复制目录,然后恢复。暂停窗口很短(秒级),在此期间备份节点只是稍稍落后于集群——恢复后会自动追赶。 - 应避免: 在
ClusterBackup正在写入时复制备份目录——你可能会归档到一份写到一半、无法使用的 snapshot。
- 保留策略: 至少保留 3-7 天的归档。对于合规要求严格的环境,保留 30 天以上或按监管要求执行。
- 监控归档任务: 当 cron 任务失败,或最近一次归档超过预期间隔的 2 倍时发出告警。
- 监控备份节点延迟: 跟踪备份节点落后于集群 leader 的程度(通过
ClusterBackup计数器)。若延迟增大,说明备份已陈旧。 - 定期验证恢复: 从对象存储下载一份归档,将其恢复到测试集群,并验证状态完整性。未经测试的备份不算备份。
网络故障看起来吓人,但大多能自行纠正。Raft 的核心要义就是已提交的数据能在任何分区下存活。真正需要担心的不是干净利落的断开——而是抖动(flapping)。
| 情形 | 数据丢失风险 | 可用性影响 | 恢复复杂度 | 修复方案 |
|---|---|---|---|---|
| 分区——leader 被隔离 | 未提交的消息 | 短暂(选举) | 低——自动 | 等待多数派分区中的自动选举;旧 leader 自动下台;修复网络 |
| 分区——follower 被隔离 | 无 | 无(法定人数保持) | 低——重连后自动追赶 | 修复网络;follower 重连后自动从 leader 追赶 |
| 分区——无多数派(对称分裂) | 无(已提交数据安全) | 完全不可用,直至重连 | 中——等待或手动 | 恢复网络连通性;集群自动恢复;无需手动数据恢复 |
| 间歇性抖动 | 无 | 降级(选举风暴) | 中——调整超时 | 增大选举超时和心跳间隔;修复底层网络不稳定问题;考虑专用集群网络 |
| 节点间高延迟 | 无 | 降级(提交变慢) | 低——调整超时 | 增大心跳/选举超时以容忍延迟;优化网络路径;考虑更近的节点摆放 |
网络分区行为
Section titled “网络分区行为”Scenario: Leader isolated (minority partition)
[AZ-1: Leader] ──✕── [AZ-2: Follower A, Follower B] ↓ ↓ Steps down New election → new leader (can't reach quorum) (has quorum: 2/3)Raft 的分区处理很优雅:被隔离的 leader 无法提交任何东西(无法定人数),于是它下台。多数派分区选出新 leader 并继续运行。不会丢失任何数据,因为旧 leader 上的未提交条目从未向客户端确认过。
其中两行其实是调优问题,而非故障。节点间高延迟会拖慢提交,因为每次提交都要等待一次跨节点往返——你的 p99 会随网络路径而攀升。抖动会触发选举风暴,反复使集群停滞。两者都可以通过加大心跳和选举超时来解决,让集群能容忍短暂的抖动而不做出反应——代价是故障检测变慢。超时本身不会影响热路径上的 p50/p99;它只决定一次中断会让吞吐停滞多久,集群才恢复。
磁盘是健康集群悄然停滞的地方。有两个目录至关重要,而“leader 磁盘写满”正是会拖垮整个集群的意外。
| 情形 | 数据丢失风险 | 可用性影响 | 恢复复杂度 | 修复方案 |
|---|---|---|---|---|
| leader 磁盘写满 | 无 | 完全不可用(无法提交) | 中 | 释放磁盘空间或扩容卷;触发 snapshot 以压缩日志;设置磁盘用量告警 |
| follower 磁盘写满 | 无 | 无(法定人数保持) | 低 | 释放 follower 上的磁盘空间;写入恢复后节点自动追赶 |
| 磁盘损坏(单个节点) | 无(若被检测到) | 无(法定人数保持) | 中——重建节点 | 停止节点;清空损坏的 clusterDir + archiveDir;重启——通过 snapshot 复制 + 日志追赶从 leader 重建 |
| 磁盘损坏(所有节点) | 高 | 完全不可用 | 严重——需要外部备份 | 从外部备份恢复所有节点;若无备份,数据丢失 |
| 集群目录丢失(单个节点) | 无 | 无(法定人数保持) | 中 | 彻底清空节点;重启——从 leader snapshot + 日志重新置备 |
| 集群目录丢失(所有节点) | 高 | 完全不可用 | 严重 | 从外部备份恢复集群元数据;从备份的 snapshot + 日志重建 |
| archive 目录丢失(单个节点) | 无 | 无(法定人数保持) | 中 | 清空节点;重启——通过 snapshot 复制从 leader 追赶 |
| archive 目录丢失(所有节点) | 完全丢失 | 完全不可用 | 严重 | 从外部备份恢复 archive 录制;无备份 = 数据完全丢失 |
- clusterDir——包含集群元数据、标记文件、共识状态。
- archiveDir——包含录制的流(日志条目、snapshot)。
两者都至关重要。在单个节点上丢失任意一个都可以从对等节点恢复。在所有节点上同时丢失任意一个则需要外部备份。