作者:Sanjay Ghemawat
          Howard Gobioff
          Shun-Tak Leung
翻译:tinyfool

3.3 原子性的记录追加

GFS提供了一个叫做记录追加的原子性的追加操作。传统的写入操作,客户机指定数据写入的偏移位置。同意范围的并行写入是不可串行的:范围内会包括来自不同客户机的数据片段。而对于记录追加,客户机只能指定数据。GFS至少一次自动地把数据追加到文件中GFS选定的偏移位置,然后把偏移位置返回给客户机。这类似于在Unix下,多个并行写入者在没有竞争条件下,对以O_APPEND模式打开的文件的写入。

记录追加在我们的分布应用中使用的非常频繁,许多客户机并行地追加数据到同一个文件。如果采用传统的写入方式,客户机需要额外的复杂和代价昂贵的同步机制,例如一个分布的锁管理器。在我们的工作中,这样的文件经常服务于多生产者/单消费者队列,或者包含来自多个不同客户机的合并的结果。

记录追加是遵循章节3.1描述的控制流程的一个操作,仅有主块有点额外的控制逻辑。客户机把数据推送给文件最后一个块的所有副本,然后发送请求给主块。主块检查对当前块的记录追加操作是否会造成块超过最大值(64MB)。如果是这样,它首先把块填充到最大值,告诉所有二级块做同样的操作,然后回复客户机说明需要对下一个块也进行操作。(一次记录追加操作的数据尺寸严格规定不超过4倍的最大块尺寸,这样即使最坏情况下存储碎片的数量仍旧控制在可接受的级别。)如果记录不超过最大尺寸,这是比较常见的,主块把数据追加到自己的副本内,然后通知二级副本把数据写在跟主块一样的位置,最后通知客户机操作成功完成。

如果任何副本上追加失败,客户端重新进行操作。所以,同一块的不同副本可能包含不同的数据,可能包括一个记录全部或者部分的重复。GFS并不保证所有的副本是字节级别一致的。它仅保证数据会作为原子性单元被至少写入一次。这个属性是由如下的简单观察推导而来的,如果操作报告成功,数据一定已经写入在同一块的所有副本的相同偏移位置上。此后,所有的副本至少达到了记录尾部的长度,任何额外的记录都会附加到更大的偏移或者不同的块,即使其他的块后来成为了主块。在我们一致性保障措施的术语中,成功被执行追加操作的区域的数据是已定义的(所以也是一致的),反之则是不一致的(也就是未定义的)。我们的程序可以处理不一致的区域,我们在2.7.2章节讨论过这些。


<< 3.2 数据流 | 3.4 快照 >>