GFS FT

GFS 真正精髓部分:Fault Tolerance(容错机制)

前面是正常读写流程,真正让 GFS 伟大的,是它默认机器会坏、磁盘会坏、网络会断,然后系统还能继续工作。


📌 GFS 故障处理总览

这些核心场景:

1. ChunkServer 掉线
2. 数据损坏(checksum error)
3. 副本丢失 / 数据恢复
4. 写入失败
5. 新增 Chunk 失败
6. 垃圾回收(GC)
7. Master 宕机(补充)
8. 副本均衡迁移(补充)

就是 GFS 的核心可靠性设计。


📌 一张总流程图(建议收藏)

mindmap root((GFS Fault Tolerance)) ChunkServer掉线 heartbeat超时 标记失效 客户端换副本读 Master触发重新复制 数据损坏 checksum检测 返回错误 从其他副本复制恢复 写入失败 primary返回错误 client重试 lease失效重新选primary 副本不足 Master后台re-replication 垃圾回收 延迟删除文件 orphan chunk清理 Chunk创建失败 重试分配chunk handle Master故障 shadow master 日志恢复


一、ChunkServer 掉线怎么处理


正常机制

Master 会周期性收到 ChunkServer 的 Heartbeat(心跳)

例如:

ChunkServer A 每几秒报告:
我还活着
我有哪些 chunk
磁盘状态如何

如果掉线

Master 超时没收到心跳:

ChunkServer A DEAD

然后:

Master 立即做三件事:

① 把该 ChunkServer 标记失效

以后 Client 不再被分配到它。

② Client 自动切换其他副本

原来 chunk 有 3 副本:

A B C

A 挂了,读写改走:

B C

③ Master 后台触发重新复制

为了恢复 3 副本数:

B/C -> 复制一份到 D

变成:

B C D

图示

flowchart LR A[ChunkServer A 掉线] --> B[Master心跳超时发现] B --> C[标记A失效] C --> D[Client改访问B/C] D --> E[后台复制到D机器] E --> F[恢复3副本]

一句话记忆:

节点挂了先绕开,再补副本。



二、数据损坏(磁盘坏块 / silent corruption)

这是分布式存储最危险的问题。

磁盘可能返回错误数据,但系统不知道。


GFS 解决方式:Checksum

每个 chunk 被切成很多 block(如 64KB)。

每块都有 checksum:

block1 -> crc
block2 -> crc
...

Client 读取时:

ChunkServer 返回数据前先校验:

checksum(data) == stored checksum ?

如果损坏:

不返回坏数据
返回 error

Client 换其他副本读取。

Master 得知后:

从健康副本复制恢复该 chunk

图示

flowchart TD A[读取chunk] --> B[checksum校验] B -->|通过| C[返回数据] B -->|失败| D[报告损坏] D --> E[Client换其他副本] E --> F[Master重新复制修复]

一句话:

发现坏数据不修补本地,直接用健康副本覆盖恢复。



三、副本丢失 / 数据恢复

例如:

chunk123 原有副本:
A B C

B 挂了。

剩:

A C

副本数低于目标值(例如 3)。


Master 后台扫描发现:

under-replicated chunk

然后挑机器 D:

A -> D

恢复为:

A C D

Master 会优先恢复:

1. 副本数最少的 chunk
2. 热门 chunk
3. 最近故障 chunk

一句话:

Master 持续巡检,副本少了就自动补。



四、写入失败怎么处理

写流程里可能失败的位置:

1. Client 推数据失败
2. Primary 写失败
3. Secondary 写失败
4. Lease 过期

场景1:某 Secondary 写失败

Primary 收不到 ack:

返回 Client error

Client:

重新向 Master 请求最新副本信息
重试写入

场景2:Primary 挂了

Master 发现 primary 掉线:

重新选新的 primary
发 lease

Client 重试。


图示

sequenceDiagram Client->>Primary: write Primary->>Secondary: replicate Secondary--xPrimary: fail Primary-->>Client: error Client->>Master: 请求新primary Master-->>Client: 新primary Client->>NewPrimary: retry

一句话:

写失败就刷新元数据并重试。



五、新增 Chunk 失败

当文件写满当前 chunk:

需要创建新 chunk

Client 请求 Master:

alloc new chunk

Master:

分配 chunk handle
选3台机器放副本

如果其中某台机器失败:

换别的机器重新分配

一句话:

创建 chunk 本质是元数据分配 + 选副本机器。



六、垃圾回收(GC)

这是 GFS 非常经典设计。


为什么不用立即删除?

立即删文件很复杂:

Master删元数据
ChunkServer删物理数据
网络失败怎么办?
部分删掉怎么办?

GFS 做法:延迟删除

用户删除文件:

/foo.txt

Master 不立刻删 chunk。

而是:

rename -> hidden name
标记 deleted timestamp

例如:

/.deleted/foo.txt#123

等几天后后台清理:

真正删除 metadata
通知 ChunkServer 删除 chunk

图示

flowchart TD A[用户删除文件] --> B[Master仅标记删除] B --> C[隐藏文件名] C --> D[等待几天] D --> E[后台GC删除metadata] E --> F[ChunkServer删除chunk数据]

好处:

1. 删除快
2. 避免误删可恢复
3. 简化一致性问题

一句话:

GFS 删除是“先忘记,再清理”。



七、孤儿 Chunk(Orphan Chunk)

可能发生:

Master元数据没了
但ChunkServer还有物理chunk

这叫:

orphan chunk

解决:

Master 定期扫描:

ChunkServer汇报 chunk list
Master 对照 metadata
发现无主 chunk -> 删除

八、Master 宕机(补充)

论文里 Master 是单点。

解决方式:


1. 操作日志(operation log)

所有 metadata 修改先写日志:

create file
allocate chunk
rename
delete

Master 重启后回放日志恢复。


2. Checkpoint

定期保存快照,避免日志太长。


3. Shadow Master(只读备份)

可提供只读查询。


九、数据均衡(rebalance)

有些机器 chunk 太多,有些太少。

Master 后台迁移:

serverA -> serverD

保持:

容量均衡
热点均衡
网络均衡

十、完整异常处理总图

flowchart TD A[异常发生] --> B{类型} B -->|ChunkServer掉线| C[心跳超时] C --> D[切换副本] D --> E[重新复制] B -->|数据损坏| F[checksum失败] F --> G[换副本读取] G --> H[健康副本覆盖恢复] B -->|写失败| I[返回错误] I --> J[刷新primary信息] J --> K[重试] B -->|副本不足| L[后台re-replication] B -->|删除文件| M[延迟删除] M --> N[后台GC] B -->|孤儿chunk| O[扫描删除] B -->|负载不均| P[rebalance]

十一、总结

GFS 假设机器会坏,因此所有机制都围绕自动恢复设计:

1. 节点挂了:切副本 + 补副本
2. 数据坏了:checksum发现 + 健康副本恢复
3. 写失败:重新找primary重试
4. 文件删除:延迟删除 + 后台GC
5. 元数据丢失:日志恢复
6. 负载不均:后台迁移

十二、一句话理解 GFS

GFS 不是避免故障,而是默认故障一直发生,并快速恢复。


posted @ 2026-04-17 19:26  BuerH  阅读(14)  评论(0)    收藏  举报