重读 Google File System

2021-01-27  本文已影响0人  扫帚的影子

前言

本着常读常新的原则,最近又一次阅读了Google三架马车之一的《Google File System》。它里面的一些设计思想,实现原则以及取舍,时至今日仍很有参考价值。

今夜,让我们一起来听(读)相声(经典)吧!

注:下文中我们将Google File System简称为GFS。

GFS特点

Google File System在考虑通用分布式文件系统设计的同时,也更多地从自身业务需求出发,提出了一些新的设计理念和新的系统特点:

GFS架构图

下面这张架构图,相信大家已经看过千百遍,我们还是让它再一次闪亮登场:

gfs-architecture.jpg

对于绝大部分分布式系统,都需要解决元数据和用户数据的存储,另外还有客户端读写数据的SDK这三部分。GFS也不例外,在上图可以看出:

GFS元数据管理

元数据分类

元数据一致性

从上面的描述可知,对元数据的变更是以变更日志的方式同步到多个Master节点,然后Master节点在启动时重放变更日志,达到与之前的Master节点一致的状态。

Master的两快

对于Master来说,最重要的是需要两类快速的操作:

Master的高可用

这部分其实前面已经提及到了,从论文上看master分为当前可用的master,实时同时变更日志的备份master,准实时的影子master。

gfs-master.png

常用MetaServer实现方案

通常来说MetaServer至关重要,meta数据的丢失可能直接导致用户数据的丢失。

目前常用的实现方案是MetaServer使用raft协议等作成AP系统,元数据的更改经raft模块后写入每台MetaServer的本地存储,比如RocksDB。

如果集群元数据量非常大,可以将MetaServer集群作分组处理,每组MetaServer管理整个集群的一个子域。客户端首先连接到一个前置服务,获取对应的MetaServer集群信息。

GFS数据读写

数据写入

写入流程图如下:

GFS-WRITE.png gfs-multi-write.png
1.  C1,C2,C3,C4分别代表四个不同的客户端发送的写请求,此刻它们在当前Chunk的三个复本上的推送情况如上图所示,C3和C4已经推送到了所有的复本,并给各自的客户端返回了推送成功的回应;

2.  C3,C4客户端分别给主Chunk发送写入的控制指令;

3.  推测主Chunk为了提高效率批量写入,可能会缓存积累多个写入控制指令。比如C3的写入指令先到,在delay时间内如果C4的写入控制指令也到了,则确定好C3,C4的顺序,先写入本地;

4.  将排序好的写入指令序列推送给其他复本,其他复本在本地写入成功后,将响应返回给主Chunk;

5.  主Chunk将响应分别返回到C3,C4两个客户端;

6.  如果有部分复本写入失败,则此失败的信息也会返回到对应的客户端。

主Chunk失效

分为两种情况:

Chunk数据一致性

说到数据一致性,线性一致性,顺序一致性,因果一致性,最终一致性,大家应该都是耳熟能详。

我们来看一下GFS中数据一致性的表述:

GFS-FILE-REGION.png

先来解释两个概念:

GFS支持多个客户端并行写入,又同时支持随机写和追加写,这给上面介绍的“defined”和“consistent”带来了很多的不确定性。

上面中客户端A的数据块1和客户端B的数据块1并行写ChunkA的尾部剩余空间,两个写入操作经主Chunk排序后会叠加覆盖,假设结终写入了客户端A的数据块1;同样的流程,新ChunkB的首部空间最终被写入的可能是客户端B的数据据2。如此这般,无论是客户端A还是客户端B想要来读取自己写入的完整数据块时,读取到的就都不完全是数据写入的数据了。

如上图所示,左边在写入数据3时,复本1写入成功,复本2写入失败

然后重试,重试后数据3都成功写入了复本1和复本2,且返回客户端的offset是最后一次都成功写入后的数据3的

Offset,客户端用此offset可以读取到数据3,行为是已定义的。

但是对于复本1,写入了两次数据3,复本2中间有空洞,出现了不一致的问题。

对于空洞,GFS的处理是写入特殊的标记,比如特殊的crc校验值,在客户端读取时告知客户端。

对于重复数据,GFS要求客户端自行处理,比如写入的数据中带有唯一标识,供客户端去重用。

2.  对于并发写,由于追加写不会发生跨Chunk的情况(如果当前Chunk剩余空间不够写入,会作填充,然后新创建一个Chunk,供当有写入用),保证了原子性,写入成功后读取是已定义的。但是会出现和串行写失败重试后出现空洞一样的问题,导致复本间数据局部不一致。

常见系统多点写处理

多点并行写入,会引入不确定性,而这些不确定性对系统的使用者来说也增加了复杂度。

因此,目前常见的系统,更多地是不支持多点写,只支持单点写。

实现上也比较简单,多个写者通过抢锁互斥,抢到锁的客户端通过不断续租来长期持有锁,并且提供主动释放锁的接口,来避免因持有锁的客户端意外挂掉,还需要等租约超时standby的客户端才能抢到锁的情况。

复本选择策略

复本位置选择,遵守两个大原则:

这就需要在选择位置时,需要考虑不同复本分散到不同机架上,磁盘使用率低于平均磁盘使用率的磁盘被优先选中,而且也要避免同一块磁盘被连续多次选中,因为新的chunk被分配后,很可能紧接着有大量的数据写入,IO容易成为瓶颈。更细致的作法是各个ChunkServer上报各个的IO负载情况,在选择Chunk位置时,结合其负载情况来选择。

后记

关于《Google File System》的重读,我们就先到这里。论文里包含得比这里介绍得要丰富详实得多,这里算作是抛砖引玉吧。

更多精彩文章,欢迎关注微信共众号:程序员Lion

上一篇 下一篇

猜你喜欢

热点阅读