The Google File System 翻译和理解( 五 )


  • 当一个修改完全没有受到并发写入操作的影响并成功时,那么影响到的区域已定义(隐含一致性) consistent interspersed undefined:所有的客户端将总会看到修改已经写入的内容 。
    已定义的一定一致
  • 并发成功的修改使区域处于一致,但未定义状态 consistent but undefined:所有的客户端将看到相同的数据,但是它可能不能反映出任意一个修改已写入的内容 。
    • 通常,它是由一些来自多个修改操作的、混合的数据碎片组成的 。
    一致的未必已定义,因为数据一致,但有些操作可能未成功或成功了一半
  • 一个失败的修改会造成区域的不一致性(因此也没有被定义)inconsistent:不同的客户端在不同的时间可能会看到不同的数据 。
  • 我们将在后面描述我们的应用如何区分已定义和未定义的区域 。这些应用程序不需要更深入的区分不同种类的未定义区域间的区别 。
    数据修改操作可能是写入 write 或记录追加 append 操作 。一个写操作会将数据写入到应用指定的文件位置 。偏移位置将被返回给客户端,并标明包含这个记录的已定义区间的开始位置 。
    • 如果有多个并发修改操作,一个记录追加操作会将数据(记录)至少一次的原子性的追加到文件,而具体的偏移量是由GFS选定的 。
    • 一个通常的追加操作仅仅是将数据追加到客户端认为是当前文件结尾的位置 。
    此外 。GFS 能够在文件中插入数据或复制记录,这种情况下这些数据占据的文件区域被认为为非一致性的,但数量通常比用户数据总量要小很多 。
    在一系列成功的修改操作后,被修改的文件区域被保证为是已定义的,并且包含了最后一次修改操作写入的数据 。GFS通过以下步骤完成上面行为:
    1. 在所有副本上按相同的顺序执行一个块上的修改操作(3.1)
    2. 使用版本号来检测并复制过期文件(4.5)
      • 这种过期可能是由于块服务器宕机而造成了部分修改丢失引起的 。过期的副本不会再涉及修改操作,主节点也不会将该副本返回给客户端 。它们会尽快的进行垃圾回收操作 。
    因为客户端缓存了块位置信息,它们可能会在位置信息更新前直接访问到一个过期的副本 。这个问题出现的窗口是受缓存条目的超时时间和下一次文件的打开时间限制的,下一次文件打开时才会对这个文件的所有块信息的缓存进行清理 。此外,由于大多数文件都是只能追加的,一个过期的副本经常会返回一个因过早结束而缺失数据的块,而不是过期的数据 。当一个读客户端再次向主节点查询时,它将会立即获得块的当前位置信息 。
    在一个修改操作成功执行完一段时间后,组件的失效依然能损坏或删除数据 。
    • GFS通过在主节点和所有块服务器间定期的握手来标识失效的块服务器,并通过校验和来探测数据损坏(5.2) 。
    • 一旦问题被发现,数据将会尽快的利用有效副本进行恢复(4.3) 。
    只有在GFS反应之前的几分钟之内,一个块的所有副本都丢失,这个块才会彻底的丢失 。在这种情况下,应用会接收到明确的错误码,而不是损坏的数据 。
    2.7.2 应用的实现GFS 基于一些简单的技术实现了一个宽松的一致性模型:
    • 依赖追加而不是覆盖 。
    • 检查点
    • 写入时自验证 。
    • 自标识的记录 。
    这些技术在 GFS 的其他设计目标已经是必不可缺的,所以我们可以理解为一致性模型没有带来额外的负担 。
    实际中,我们所有的应用都是通过 append 而不是 overwriting 来修改文件 。在一个典型的例子中,一个写操作生成一个文件,并从头到尾的写入数据 。它将写入完数据的文件原子地重命名为一个不变的名字,或者周期性的创建检查点来记录有多少执行成功的写操作 。

    经验总结扩展阅读