这是我参与【第五届青训营】伴学笔记创作活动的第九天
谷歌文件系统
1.1 设计动机
- 组件失效是常态:GFS是由几百甚至几千台普通的廉价设备组装成的存储机器,但是这同时也是一个弊端,任何时间都可能会有某些组件无法工作。
- 文件非常巨大:存在很多数GB的文件,I/O操作和Block的尺寸都需要重新考虑。
- 绝大部分文件的修改都是在文件尾部追加数据,而不是覆盖数据。
- 应用程序和文件系统API协同设计以提高整个系统的灵活性。
1.2 设计思想
- 文件以数据块的形式进行存储:数据块大小固定,每个数据块都有句柄
- 利用副本技术保证可行性:每个数据库至少在3个块服务器上存储副本;每个数据库作为本地文件存储在Linux文件系统中。
- 主服务器维护所有文件系统的元数据:每个GFS簇只有一个主服务器,利用周期性的心跳信息更新服务器。 ![[Pasted image 20230210210828.png]]
- Chunk(块)服务器在硬盘上存储实际数据,同时会有多个Chunk服务器备份数据来避免服务器崩溃而丢失数据。一旦被Matser访问指明,客户端程序就会直接从Chunk服务器中读取文件。
- 客户端和块服务器不需要缓存文件数据。原因:Chunk以本地文件的方式保存,Linux操作系统的文件系统缓存会把经常访问的数据缓存到内存中。
2. Master服务器不存在性能瓶颈的原因
Master服务器在不同的数据文件里保持元数据。数据以64MB为单位存储在文件系统中,客户端于Master服务器通讯在文件上做元数据操作并且包含找到用户需要的数据。 //元数据:又称中介数据,中继数据,为描述数据的数据。
- 只存储元数据,不存储文件数据,不让==磁盘容量==成为Master瓶颈
- 元数据存储在磁盘和内存中,不让==磁盘IO==成为Master瓶颈
- 元数据大小内存完全能装得下,不让==内存容量==成为Master瓶颈
- 所有数据流,数据缓存,都不走Master,不让==带宽==成为Master瓶颈
- 元数据可以缓存在客户端,每次从客户端本地缓存访问元数据,只有元数据不正确的时候,才会访问Master,不让CPU成为==Matser==瓶颈
3. 读、写、添加操作流程
3.1 读
- 应用程序发起读请求
- GFS客户端从(文件名,字节范围)->(文件名,组块索引)转换请求,并将其发送到Master服务器。
- Master服务器以句柄和副本位置(即存储副本的Chunk服务器)作为响应.
- 客户端选择一个位置,然后将(块句柄,字节范围)请求发送到该位置
- Chunk服务器将请求的数据发送到客户端
- 客户端将数据转发给应用程序
![[Pasted image 20230210213756.png]] ![[Pasted image 20230210213817.png]]
3.2 写
互斥:任何的写或者追加操作
- 数据需要被写到所有的副本上
- 当多个用户请求修改操作时,保证同样的次序
写过程: 1. GFS客户端发送请求到主服务器:发请求 2. 主服务器返回块的句柄和副本的位置信息:给块服务器信息 3. 客户端将写数据发送给所有副本服务器:发要写入的数据 4. 数据存储在副本服务器的缓存中:把数据存在缓存中 5. 客户发送写命令给主副服务器:客户发写命令 6. 主副服务器给出写的次序:给出写的顺序 7. 主副服务器将次序发送给二级副本服务器:把顺序给下级服务器 8. 二级副本管理器响应主副本服务器:开写 9. 主服务器响应客户端:写好给响应
3.3 添加操作
- 应用程序提出添加操作的请求
- GFS client解析请求,并发给主服务器
- 主服务器返回块服务器的句柄和位置
- Client将要写入的数据推入各个副本
- Primary(主服务器)检查添加操作是否会导致该块超过最大的规模
- 如果记录满足最大规模,那就添加上,并告诉其他副本在同样的位置写数据,最后primary向client报告写操作成功
- 如果超过:把块扩充到最大规模,其他副本做同样的事情,同时通知client该操作需要在下一块上重新尝试。