当前位置: 首页 > news >正文

GFS读写过程

适合学习和回忆的 GFS 中 Client 向 Master 请求元数据、再与 ChunkServer 通信的全过程

读流程写流程,写流程比读复杂,涉及 primary / secondary / lease / 数据流水线


GFS 中三类角色

Client:
发起读写请求的客户端Master:
只管理元数据,不直接传输文件数据
管理:
- 文件名空间
- 文件 -> chunk 映射
- chunk 副本位置
- chunk lease(谁是 primary)ChunkServer:
真正存储 chunk 数据

一、先记住最核心原则

GFS 的关键设计思想

Master 不在数据通路上,只在控制通路上。

也就是:

  • Master 负责告诉 Client 去哪里读/写
  • 真正的数据传输发生在 Client 和 ChunkServer 之间

这个是 GFS 最重要的一句。


二、GFS 读数据全过程

假设用户要读取:

/foo.txt 的某个 offset 开始的一段数据

1)读流程总图

sequenceDiagramparticipant Clientparticipant Masterparticipant CS1 as ChunkServer Aparticipant CS2 as ChunkServer Bparticipant CS3 as ChunkServer CClient->>Master: 1. 询问文件 offset 对应的 chunk 句柄 + 副本位置Master-->>Client: 2. 返回 chunk handle + replicas(CS1,CS2,CS3)Client->>CS2: 3. 直接向某个最近的 ChunkServer 发起读请求CS2-->>Client: 4. 返回 chunk 数据Note over Client,Master: Client 会缓存 chunk 元数据,后续同一 chunk 读请求通常不必再问 Master

2)逐步解释

第一步:Client 先根据文件名和 offset 定位 chunk

GFS 文件被切成很多固定大小的 chunk(经典论文里通常是 64MB)。

所以 Client 读取时,先要算出:

chunk index = offset / chunk_size

比如:

读取 /foo.txt 的 offset = 130MB
chunk_size = 64MB

那么它要找的就是:

第 2 号 chunk

第二步:Client 向 Master 请求元数据

Client 不会直接问 “把数据给我”。

它问的是:

给我 /foo.txt 第 i 个 chunk 的:
- chunk handle
- 这个 chunk 的副本位置

Master 返回:

chunk handle = 12345
replicas = [ChunkServer A, B, C]

这里:

  • chunk handle 是 chunk 的全局唯一标识
  • replicas 是这个 chunk 的多个副本所在的 ChunkServer

第三步:Client 直接选一个 ChunkServer 读

Client 拿到副本列表后,会自己选一个 ChunkServer,通常选:

  • 距离更近的
  • 网络更快的
  • 当前看起来更合适的

然后直接发请求:

请把 chunk handle=12345 从某个内部 offset 开始的数据发给我

注意这里已经 不经过 Master 了。


第四步:ChunkServer 返回数据

ChunkServer 找到本地 chunk 数据,返回给 Client。

如果这个请求只覆盖一个 chunk,流程结束。

如果读跨越多个 chunk,Client 会:

  • 对下一个 chunk 再发请求
  • 如果缓存里没有元数据,再去问 Master

3)读流程一句话总结

Client 先向 Master 要“位置”,再直接向 ChunkServer 要“数据”。


三、GFS 读流程的细节补充

1. Client 会缓存元数据

Master 负担不能太重,所以 Client 会缓存:

  • 文件到 chunk 的映射
  • chunk handle
  • chunk 副本位置

所以后续连续读常常是:

第一次问 Master
后面直接找 ChunkServer

2. Master 不返回数据本身

Master 只返回:

  • chunk handle
  • 副本位置

它不转发真实数据。


3. 如果 ChunkServer 失败怎么办

如果 Client 发现某个 ChunkServer 不可用:

  • 换另一个副本重试
  • 如果元数据过期,再重新问 Master

四、GFS 写数据全过程

写流程比读复杂很多,因为要保证多个副本的一致性。

核心角色:

  • Master:告诉 Client 哪些副本参与写,以及谁是 primary
  • Primary ChunkServer:负责给这次写操作确定顺序
  • Secondary ChunkServer:按 primary 指定的顺序执行写入

五、GFS 写流程总图

sequenceDiagramparticipant Clientparticipant Masterparticipant P as Primary ChunkServerparticipant S1 as Secondary ChunkServerparticipant S2 as Secondary ChunkServerClient->>Master: 1. 请求某 chunk 的写入信息Master-->>Client: 2. 返回 primary + secondaries + leaseNote over Client,P: 3. Client 先把数据推送到所有副本(数据流)Client->>S1: push dataClient->>S2: push dataClient->>P: push dataNote over Client,P: 4. Client 向 primary 发送写命令(控制流)Client->>P: write(handle, data_id, offset)P->>P: 5. 为写操作分配全局顺序P->>S1: 6. 按顺序转发写命令P->>S2: 7. 按顺序转发写命令S1-->>P: 8. ackS2-->>P: 9. ackP->>P: 10. 本地提交完成P-->>Client: 11. 返回成功

六、为什么写流程要分成“推数据”和“发写命令”两步

这是 GFS 很经典的设计。

第一步:数据先推送到所有副本

Client 会先把数据送到所有参与写入的 ChunkServer,但此时它们只是:

  • 把数据暂存在内部缓冲区
  • 还没有真正写到正式位置

第二步:再由 primary 发号施令

真正写的时候,Client 只向 primary 发送控制命令:

请把刚才那份数据写到 chunk 的某个位置

这样做的好处是:

  • 数据传输和控制解耦
  • primary 只负责排序,不必承载全部数据转发压力
  • 写入顺序统一,便于副本一致

七、写流程详细展开


第 1 步:Client 向 Master 请求写元数据

Client 告诉 Master:

我要写 /foo.txt 的某个 chunk

Master 返回:

  • 该 chunk 的各个副本位置
  • 哪个副本当前是 primary
  • 对应 lease 信息

例如:

chunk handle = 12345
primary = ChunkServer A
secondaries = [B, C]

第 2 步:Client 把数据推送给所有副本

Client 不会只把数据发给 primary。

而是会把数据发送到全部副本。实际实现里常是 链式流水线

例如:

Client -> A -> B -> C

或者按网络拓扑优化路径推送。

重点是:

  • 每个 ChunkServer 都先收到同一份数据
  • 数据先缓存起来
  • 此时还没正式提交

第 3 步:Client 向 primary 发送写请求

当所有副本都拿到数据后,Client 向 primary 发控制请求:

write(chunk_handle, data_id, offset)

这里 data_id 表示刚才那份已经推送到各副本缓存区的数据。


第 4 步:Primary 决定全局顺序

这一步是 GFS 写一致性的关键。

多个 Client 可能同时往同一个 chunk 写,primary 要决定:

这次写是第几号操作
先执行谁,后执行谁

也就是:

primary 给这个 chunk 上的并发修改建立一个串行顺序。


第 5 步:Primary 把写命令转发给 secondaries

Primary 告诉 secondary:

按这个顺序执行这次写

Secondaries 接到后,在本地正式写入对应位置。


第 6 步:Secondaries 回 ACK 给 Primary

每个 secondary 写完之后返回确认。


第 7 步:Primary 汇总结果并回复 Client

如果所有副本都成功,primary 回复 Client 成功。

如果某些副本失败,Client 会收到错误,然后重试或重新询问 Master。


八、GFS 写流程的本质

数据先分发到所有副本,命令由 primary 排序后统一执行。


九、Append 流程和普通 Write 的区别

GFS 里还有一个非常有代表性的操作:Record Append

它和普通写的区别是:

  • 普通写:Client 指定 offset
  • Record Append:Client 只说“把这条记录追加到文件末尾”

这时由 primary 决定最终追加位置。


Record Append 流程概念图

sequenceDiagramparticipant Clientparticipant Masterparticipant P as Primaryparticipant S1 as Secondaryparticipant S2 as SecondaryClient->>Master: 请求 append 所需元数据Master-->>Client: 返回 primary + replicasClient->>P: 发送 append 请求P->>P: 选择实际追加偏移P->>S1: 按选定 offset 执行 appendP->>S2: 按选定 offset 执行 appendS1-->>P: ackS2-->>P: ackP-->>Client: 返回成功 + 实际偏移

为什么 GFS 很强调 Append

因为 GFS 面向的典型场景是:

  • 大量日志写入
  • 追加式数据生成
  • 批处理数据生产

所以 “追加” 比 “随机覆盖写” 更常见。


十、读写全过程总览图

flowchart TDA[Client 发起请求] --> B{读还是写?}B -->|读| C[根据文件名+offset定位 chunk] C --> D[向 Master 请求 chunk handle 和副本位置] D --> E[Master 返回 replicas] E --> F[Client 直接选择一个 ChunkServer] F --> G[ChunkServer 返回数据]B -->|写| H[向 Master 请求 chunk 副本位置和 primary] H --> I[Master 返回 primary + secondaries + lease] I --> J[Client 先把数据推送到所有副本] J --> K[Client 向 primary 发送写命令] K --> L[primary 决定写顺序] L --> M[primary 命令 secondaries 执行写入] M --> N[secondaries ack 给 primary] N --> O[primary 回复 Client]

十一、GFS 中 Master 到底干了什么

可以把 Master 记成:

Master 负责控制面

  • 文件名空间管理
  • 文件到 chunk 的映射
  • chunk 副本位置管理
  • 分配新的 chunk handle
  • 选 primary,授予 lease
  • 垃圾回收、重复制、负载均衡

Master 不负责数据面

  • 不转发文件内容
  • 不参与正常读写数据流

十二、“全过程简版”

读流程

1. Client 根据文件名和 offset 确定要访问哪个 chunk
2. Client 向 Master 请求 chunk handle 和副本位置
3. Master 返回 chunk 元数据
4. Client 直接联系某个 ChunkServer 读取数据
5. ChunkServer 返回数据给 Client

写流程

1. Client 向 Master 请求 chunk 的副本位置和 primary
2. Master 返回 primary 和 secondaries
3. Client 先把数据推送到所有副本
4. Client 向 primary 发送写命令
5. primary 确定并发写入顺序
6. primary 通知 secondaries 按相同顺序写入
7. secondaries 返回确认
8. primary 汇总后回复 Client

十三、一句总总结

你可以把 GFS 整个通信过程记成这两句:

先问 Master 位置,再找 ChunkServer 拿数据。

先问 Master 谁是 primary,再把数据发给副本,由 primary 统一排序提交。


十四、“学习脑图版”

mindmaproot((GFS Client请求全过程))读Client 计算 chunk index请求 Master获取 chunk handle获取 replicas直接联系 ChunkServer返回数据Client 缓存元数据写请求 Master获取 primary获取 secondaries获取 lease数据先推送全部副本Client 向 primary 发命令primary 排序secondaries 执行ack 返回primary 回复 ClientMaster管理元数据不走数据流ChunkServer存储 chunk提供读写关键机制replicationleaseprimary-secondarypipelineappend
http://www.jsqmd.com/news/656971/

相关文章:

  • 完全指南:高效使用开源工具突破Cursor AI Pro限制
  • 如何用LangChain开发一个Agent,20分钟搞定!
  • SAP接口集成-PO/PI-SLD配置实战:从系统格局到集成目录
  • 2026LINE养号:新号总被封?LINE账号养号与防封完整指南
  • 新年快乐 wp
  • Beyond Compare 5 密钥生成器:从技术原理到企业级部署指南
  • reverse2 wp
  • Element UI中国省市区级联数据:终极完整指南与实战教程
  • 独立站SEO流量增长:提高Google排名的优化方法
  • Eigen 3.4.90 矩阵操作实战 | C++高效线性代数指南(一)
  • 2026年美国投资移民机构排名及选择参考 - 品牌排行榜
  • 计算从1到输入整数之间的奇数之和
  • 汇川EASY系列与汇川HMI标签通讯及HMI索引
  • 适合零基础的口腔执业医师考试网课选择指南 - 医考机构品牌测评专家
  • Windows与iOS设备USB网络协议兼容性解决方案:Apple-Mobile-Drivers-Installer技术实现
  • 手把手教你用Keil5给51单片机编程:读取DHT11、SGP30等四种传感器数据
  • 手把手教你用VPI和Matlab搭建一个完整的相干光通信仿真链路(含完整DSP代码)
  • UVM线程通信实战:从event到mailbox的5个常见坑点及解决方案
  • 告别命令行:用Cockpit Web界面在CentOS7上可视化管理SNMP服务
  • Qwen3-32B驱动的漫画脸描述生成:二次元角色设计保姆级部署指南
  • [SUCTF2019]SignIn wp
  • 不踩雷不溢价!闪电喵星人联名鞋,Z世代穿搭刚需首选 - 中媒介
  • OpenCASCADE避坑指南:手把手教你从TopoDS_Shape提取三角网格,构建自己的BVH碰撞检测器
  • 深度解析:为什么Thorium浏览器是Chromium性能优化的终极选择
  • 避坑指南:STM32CubeMX配置GPIO驱动LED/蜂鸣器时,LL库与HAL库的关键区别与选择
  • 基于TDC-GPX的多通道高精度时间测量系统设计与激光雷达应用
  • 2026年3月门窗品牌推荐,铝门窗/安全门窗/慕莎尼奥门窗/断桥铝门窗/侧压平移推拉窗/门窗,门窗批发厂家推荐 - 品牌推荐师
  • 2026年美国投资移民中介排名及服务能力分析 - 品牌排行榜
  • 2026年康安倍泰秘语风花植物精华:植物力量守护女性私密健康 - 品牌排行榜
  • Zotero-GPT完全指南:3步打造你的AI文献研究助手