本文目录导读:

- 核心原则
- 场景一:Redis/缓存集群(如Redis Cluster, Codis)
- 场景二:ZooKeeper / Etcd(共识算法系统)
- 场景三:MySQL / PostgreSQL 分布式(如 ShardingSphere, MyCat)
- 场景四:Kafka / Pulsar(消息队列)
- 场景五:HBase / Cassandra(列式存储)
- 通用Java应用层恢复策略
- 关键注意点(避坑指南)
- 总结:手动恢复流程 checklist
在Java分布式系统中,“手动恢复”通常指当自动化恢复机制失效(如网络中断、数据损坏、脑裂、副本不一致等)时,由运维或开发人员通过人工干预来修复数据一致性和可用性的过程。
这是一个高风险操作,需要非常谨慎,以下是针对不同场景的Java分布式数据手动恢复方法论和具体步骤:
核心原则
- 先快照,后操作:在进行任何手动数据修改前,务必对受影响节点的数据目录、数据库、日志文件进行全量冷备份或快照。
- 确认“停止服务”或“隔离节点”:在恢复过程中,通常需要将该节点从集群中踢出,防止脏数据被其他节点读取。
- 明确数据源权威:确定哪个节点或副本的数据是“正确的”(通常基于时间戳、版本号、Raft/ Paxos Leader身份)。
Redis/缓存集群(如Redis Cluster, Codis)
典型问题:某节点宕机后重启,数据丢失;集群出现槽位不一致。
手动恢复步骤:
- 确定主从角色:使用
cluster nodes命令查看哪些节点是Master,哪些是Slave,找到数据完整的Master节点。 - 备份权威数据:在权威Master节点执行
SAVE或BGSAVE,得到dump.rdb文件。 - 恢复目标节点:
- 停止目标Redis节点。
- 将备份的
dump.rdb复制到目标节点的数据目录。 - 启动目标节点。
- 修复集群状态:
redis-cli --cluster fix <any_node_ip>:<port>:自动修复槽位指派问题。
- 强制选举(如果原主节点无法恢复):
- 手动将从节点提升为主节点:在从节点上执行
CLUSTER FAILOVER FORCE。
- 手动将从节点提升为主节点:在从节点上执行
ZooKeeper / Etcd(共识算法系统)
典型问题:磁盘损坏导致一个节点数据滞后,或节点数据目录损坏无法启动。
手动恢复步骤(以ZooKeeper为例):
- 识别“好”节点:连接集群中其他正常运行的节点,确认当前Leader和安全的Follower。
echo stat | nc <leader_ip> 2181。 - 清理损坏节点:
- 停止损坏节点的ZK进程。
- 删除
dataDir和dataLogDir目录下的所有文件(务必先备份)。
- 同步数据:
- 从正常的Follower节点(或Leader)上,同步整个
dataDir目录,通常包含version-2下的snapshot和log。 - 修改
myid文件,使其ID与集群配置一致。
- 从正常的Follower节点(或Leader)上,同步整个
- 启动并观察:
- 启动该节点。
- 查看日志,确认它成功与Leader同步(
LEADERELECTION完成,进入FOLLOWING或LEADING状态)。
- Etcd特殊处理:
- 如果整个集群都坏了,需要手动恢复一个快照:
etcdctl snapshot restore snapshot.db --data-dir /var/lib/etcd-restored,然后启动这个单节点集群,再通过member add添加其他节点。
- 如果整个集群都坏了,需要手动恢复一个快照:
MySQL / PostgreSQL 分布式(如 ShardingSphere, MyCat)
典型问题:一张表数据损坏,需要基于Binlog或WAL日志进行行级别恢复。
手动恢复步骤:
- 锁定数据来源:确认主库上的数据是否完整。
- 使用日志闪回:
- MySQL:使用
mysqlbinlog解析Binlog,找到误操作前的准确位置,通过mysqlbinlog --stop-datetime提取出正确的SQL,执行回滚。 - PostgreSQL:使用
pg_waldump分析WAL日志,还原到特定事务ID。
- MySQL:使用
- 分片级恢复:
- 如果整个分片节点挂了:
- 使用主从切换(
change master to)。 - 如果无可用从库,从全量备份恢复,并应用增量Binlog到故障前一刻。
- 使用主从切换(
- 如果整个分片节点挂了:
- 分库分表校验:
- 恢复后,使用
pt-table-checksum(Percona Toolkit) 或自定义脚本,对比分片间的数据一致性。
- 恢复后,使用
Kafka / Pulsar(消息队列)
典型问题:某个Partition的Leader副本损坏,导致数据不可消费;或磁盘爆满后部分日志段损坏。
手动恢复步骤:
- 优先Leader切换(最安全):
- 使用
kafka-leader-election.sh --bootstrap-server ... --election-type PREFERRED --topic my_topic将Leader切换到其他副本。
- 使用
- 手动恢复损坏分区:
- 如果所有副本都损坏:
- 停止所有Broker。
- 定位到该Topic的日志目录(
/data/kafka-logs/topic-name-partition-x)。 - 使用
kafka-run-class.sh kafka.tools.DumpLogSegments检查.log文件损坏程度。 - 最粗暴方式:手动删除该分区目录。
- 使用工具修复:
truncate --size <last_known_good_offset>截断最后的日志段文件。 - 使用
kafka-reassign-partitions.sh手动创建新副本。
- 如果所有副本都损坏:
- Pulsar特殊点:
- 如果BookKeeper的Ledger损坏,使用
bookkeeper shell recover命令尝试修复Ledger。 - 如果无法恢复,需使用Pulsar的
--ledger-manage工具手动删除损坏的Ledger元数据。
- 如果BookKeeper的Ledger损坏,使用
HBase / Cassandra(列式存储)
典型问题:Region Server宕机导致Region数据不一致,或HFile文件损坏。
手动恢复步骤(HBase为例):
- 归档损坏Region:
hbase hbck -fixAssignments尝试自动修复。- 手动介入:使用
hbase hbck -repair damaged_region。
- 手动合并HFile:
- 如果HFile损坏导致Major Compaction失败:
- 从备份中恢复HFile到
/.tmp目录。 - 使用
HBase HFileTool验证:hbase org.apache.hadoop.hbase.io.hfile.HFile -v /path/to/hfile。 - 使用
HFile Recover命令手动恢复。
- 从备份中恢复HFile到
- 如果HFile损坏导致Major Compaction失败:
- Cassandra:
- 如果SSTable损坏:
nodetool refresh -- <keyspace> <table>强制重加载SSTable。- 如果仍失败,使用
sstableloader/sstableutil手动清理损坏的SSTable。
- 如果SSTable损坏:
通用Java应用层恢复策略
如果上述底层组件都无法直接操作,你需要在应用代码层面进行恢复:
- 事务日志重放:
- 你的应用是否有记录操作日志?例如Spring的
@Transactional+ 手动记录event_store表。 - 编写一个补偿脚本(Java Main方法),读取事件存储,反向执行补偿操作(Saga模式)。
- 你的应用是否有记录操作日志?例如Spring的
- 手动执行补偿SQL:
- 通过MySQL客户端,手写SQL更新“总账户余额”和“账户状态表”。
- 关键:务必在应用暂停写入(或使用分布式锁)的情况下执行,防止写写冲突。
- 利用版本号/乐观锁:
- 在恢复前,查询当前记录的版本号(如
version列)。 - 在手动更新时,
UPDATE table SET version = version + 1 WHERE id = X AND version = Y,如果失败,说明有并发写入,停止恢复并告警。
- 在恢复前,查询当前记录的版本号(如
关键注意点(避坑指南)
- 永远不要在多节点上同时执行恢复命令:这可能导致数据分裂(Split-brain)。
- 优先使用高可用方案而非手动恢复:手动恢复是灾难场景的最后手段,应优先确保:
- 配置自动故障转移(如Redis Sentinel, Kafka Replicator)。
- 开启WAL、Binlog、CommitLog。
- 定期做全量+增量备份。
- 恢复后必须验证:使用求和校验、行数对比、业务正确性测试。
- Java版本兼容性:手动恢复时,确认使用的客户端工具(如hbase shell, redis-cli)版本与集群版本兼容。
手动恢复流程 checklist
- 暂停服务:停止该节点或整个集群的写入口。
- 全量备份:
cp -a或 云快照。 - 分析损坏范围:是全部数据还是部分分区?
- 选择权威副本:选Master或最新版本节点。
- 拷贝/修复数据:使用对应组件的工具。
- 重新加入集群:启动节点,确认同步。
- 恢复服务:逐步恢复写入流量。
- 事后分析:为什么自动化没有修复?补全监控和告警。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播