2.4 GFS的松弛一致性
GFS把自己的一致性称为松弛的一致性模型(relaxed consistency model)。GFS的一致性分为元数据的一致性和文件数据的一致性,松弛一致性主要是指文件数据。
2.4.1 元数据的一致性
元数据的操作都是由单一的master处理的,并且操作通过锁来保护,所以保证了原子性,也保证了正确性。
2.4.2 文件数据的一致性
在介绍松弛的一致性模型之前,我们先看松弛一致性模型中的两个概念。对于一个文件中的区域:
● 无论从哪个副本读取,所有客户端总是能看到相同的数据,这称为一致的(consistent)。
● 在一次数据变更后,这个文件的区域是一致的,并且客户端可以看到这次数据变更写入的所有数据,这称为界定的(defined)。
在GFS论文[1]中,总结了GFS的松弛一致性,如表2.1所示。
表2.1 GFS的松弛一致性
下面分别说明表中的几种情况。
● 在没有并发的情况下,写入不会相互干扰,成功的写入是界定的,那么也就是一致的。
● 在并发的情况下,成功的写入是一致的,但不是界定的。比如,在前面所举的“例子1”中,chunk1的各个副本是一致的,chunk2的各个副本也是一致的,但是chunk1和chunk2中包含的数据既不是客户端1写入的全部数据,也不是客户端2写入的全部数据。
● 如果写入失败,那么不管是write操作失败还是record append操作失败,副本之间会出现不一致性。比如,在前面所举的“例子2”中,当一些写入失败后,chunk的副本之间就可能出现不一致性。
● record append能够保证区域是界定的,但是在界定的区域之间夹杂着一些不一致的区域。record append会填充数据,不管各个副本是否填充相同的数据,这部分区域都会被认为是不一致的。比如前面所举的“例子3”。
2.4.3 适应GFS的松弛一致性
GFS的松弛一致性模型,实际上是一种不一致的模型,或者更准确地说,在一致的数据中间夹杂着不一致的数据。
这些夹杂在其中的不一致的数据,对应用来说是不可接受的。在这种一致性下,应该如何使用GFS呢?在GFS的论文[1]中,给出了几条使用GFS的建议:依赖追加(append)而不是依赖覆盖(overwrite)、设立检查点(checkpoint)、写入自校验(write self-validating)、自记录标识(self-identifying record)。下面我们用两个场景来说明这些方法。
场景1:在只有单个客户端写入的情况下,按从头到尾的方式生成文件。
方法1:先临时写入一个文件,在全部数据写入成功后,将文件改名为一个永久的名字,文件的读取方只能通过这个永久的文件名访问该文件。
方法2:写入方按一定的周期写入数据,在写入成功后,记录一个写入进度检查点,其信息包含应用级的校验数(checksum)。读取方只校验和处理检查点之前的数据。即便写入方出现宕机的情况,重启后的写入方或者新的写入方也会从检查点开始,继续写入数据,这样就修复了不一致的数据。
场景2:多个客户端并发向一个文件尾部追加数据,就像一个生产消费队列,多个生产者向一个文件尾部追加消息,消费者从文件中读取消息。
方法:使用record append接口,保证数据至少被成功写入一次。但是应用需要应对不一致的数据和重复数据。
● 为了校验不一致的数据,为每条记录添加校验数,读取方通过校验数识别出不一致的数据,并且丢弃不一致的数据。
● 对于重复数据,可以采用数据幂等处理。具体来说,可以采用两种方式处理。第一种,对于同一份数据处理多次,这并无负面影响;第二种,如果执行多次处理带来不同的结果,那么应用就需要过滤掉不一致的数据。写入方写入记录时额外写入一个唯一的标识(identifier),读取方读取数据后,通过标识辨别之前是否已经处理过该数据。
2.4.4 GFS的设计哲学
前面讲解了基于GFS的应用,需要通过一些特殊手段来应对GFS的松弛一致性模型带来的各种问题。对于使用者来说,GFS的一致性保证是非常不友好的,很多人第一次看到这样的一致性保证都是比较吃惊的。
GFS在架构上选择这样的设计,有它自己的设计哲学。GFS追求的是简单、够用的原则。GFS主要解决的问题是如何使用廉价的服务器存储海量的数据,且达到非常高的吞吐量(GFS非常好地做到了这两点,但这不是本书的主题,这里就不展开介绍了),并且文件系统本身要简单,能够快速地实现出来(GFS的开发者在开发完GFS之后,很快就去开发BigTable了[2])。GFS很好地完成了这样的目标,但是留下了一致性问题,给使用者带来了负担。这个问题在GFS推广应用的初期阶段不明显,因为GFS的主要使用者(BigTable系统是GFS系统的主要调用方)就是GFS的开发者,他们深知应该如何使用GFS。这种不一致性在BigTable中被屏蔽掉(采用上面所说的方法),BigTable提供了很好的一致性保证。
但是随着GFS推广应用的不断深入,GFS简单、够用的架构开始带来很多问题,一致性问题仅仅是其中之一。Sean Quinlan作为Leader主导GFS的研发很长时间,在一次采访中,他详细说明了在GFS渡过推广应用的初期阶段之后,这种简单的架构带来的各种问题[2]。
在清晰地看到GFS的一致性模型给使用者带来的不便后,开源的HDFS(Hadoop分布式文件系统)坚定地摒弃了GFS的一致性模型,提供了更好的一致性保证(第3章将介绍HDFS的实现方式)。