2月10日分布式案例GFS学习笔记|青训营笔记

186 阅读4分钟

这是我参与【第五届青训营】伴学笔记创作活动的第九天

谷歌文件系统


1.1 设计动机

  1. 组件失效是常态:GFS是由几百甚至几千台普通的廉价设备组装成的存储机器,但是这同时也是一个弊端,任何时间都可能会有某些组件无法工作。
  2. 文件非常巨大:存在很多数GB的文件,I/O操作和Block的尺寸都需要重新考虑。
  3. 绝大部分文件的修改都是在文件尾部追加数据,而不是覆盖数据。
  4. 应用程序和文件系统API协同设计以提高整个系统的灵活性。

1.2 设计思想

  1. 文件以数据块的形式进行存储:数据块大小固定,每个数据块都有句柄
  2. 利用副本技术保证可行性:每个数据库至少在3个块服务器上存储副本;每个数据库作为本地文件存储在Linux文件系统中。
  3. 主服务器维护所有文件系统的元数据:每个GFS簇只有一个主服务器,利用周期性的心跳信息更新服务器。 ![[Pasted image 20230210210828.png]]
  4. Chunk(块)服务器在硬盘上存储实际数据,同时会有多个Chunk服务器备份数据来避免服务器崩溃而丢失数据。一旦被Matser访问指明,客户端程序就会直接从Chunk服务器中读取文件。
  5. 客户端和块服务器不需要缓存文件数据。原因:Chunk以本地文件的方式保存,Linux操作系统的文件系统缓存会把经常访问的数据缓存到内存中。

2. Master服务器不存在性能瓶颈的原因

Master服务器在不同的数据文件里保持元数据。数据以64MB为单位存储在文件系统中,客户端于Master服务器通讯在文件上做元数据操作并且包含找到用户需要的数据。 //元数据:又称中介数据,中继数据,为描述数据的数据。

  1. 只存储元数据,不存储文件数据,不让==磁盘容量==成为Master瓶颈
  2. 元数据存储在磁盘和内存中,不让==磁盘IO==成为Master瓶颈
  3. 元数据大小内存完全能装得下,不让==内存容量==成为Master瓶颈
  4. 所有数据流,数据缓存,都不走Master,不让==带宽==成为Master瓶颈
  5. 元数据可以缓存在客户端,每次从客户端本地缓存访问元数据,只有元数据不正确的时候,才会访问Master,不让CPU成为==Matser==瓶颈

3. 读、写、添加操作流程


3.1 读

  1. 应用程序发起读请求
  2. GFS客户端从(文件名,字节范围)->(文件名,组块索引)转换请求,并将其发送到Master服务器。
  3. Master服务器以句柄和副本位置(即存储副本的Chunk服务器)作为响应.
  4. 客户端选择一个位置,然后将(块句柄,字节范围)请求发送到该位置
  5. Chunk服务器将请求的数据发送到客户端
  6. 客户端将数据转发给应用程序

![[Pasted image 20230210213756.png]] ![[Pasted image 20230210213817.png]]


3.2 写

互斥:任何的写或者追加操作

  • 数据需要被写到所有的副本上
  • 当多个用户请求修改操作时,保证同样的次序

写过程: 1. GFS客户端发送请求到主服务器:发请求 2. 主服务器返回块的句柄和副本的位置信息:给块服务器信息 3. 客户端将写数据发送给所有副本服务器:发要写入的数据 4. 数据存储在副本服务器的缓存中:把数据存在缓存中 5. 客户发送写命令给主副服务器:客户发写命令 6. 主副服务器给出写的次序:给出写的顺序 7. 主副服务器将次序发送给二级副本服务器:把顺序给下级服务器 8. 二级副本管理器响应主副本服务器:开写 9. 主服务器响应客户端:写好给响应


3.3 添加操作

  1. 应用程序提出添加操作的请求
  2. GFS client解析请求,并发给主服务器
  3. 主服务器返回块服务器的句柄和位置
  4. Client将要写入的数据推入各个副本
  5. Primary(主服务器)检查添加操作是否会导致该块超过最大的规模
  6. 如果记录满足最大规模,那就添加上,并告诉其他副本在同样的位置写数据,最后primary向client报告写操作成功
  7. 如果超过:把块扩充到最大规模,其他副本做同样的事情,同时通知client该操作需要在下一块上重新尝试。