Gfs阅读笔记

Posted by Xuan Peng on July 15, 2019

GFS 阅读笔记

这两天自己摸鱼了大哭😭),忏悔一下立个flag七月结束前更完InnoDB阅读笔记
Never mind 今天更一篇旧文是前些天读Google File System的一点笔记
  • 为什么需要GFS:适应大文件、顺序访问、追加写入的需求

  • GFS的几个特性

    • scalable: key feature for a FS on distributed system
    • reliability: 三副本机制保证其数据几乎不会丢失
    • 满足POSIX规范,和应用程序衔接
  • GFS主要存储两类数据:(like most mainstream FS)

    • 元数据:包含整个文件系统的目录树(一颗B+树),namespace, 文件存储位置
    • 文件数据
  • GFS里,所有的文件都会被切分成固定大小的Chunk,为64MB,然后分散存储。Chunk是数据复制的基本单元。

  • 每个Chunk会被复制三份,存在不同的地方。(文件系统基本思想,用冗余来保证可靠性)

  • GFS的节点类型

    • 元数据节点master,存放的是所有文件的元数据(still basic principle:controller responsible for schedule)
    • 数据节点:即Chunk的存储位置,每个数据节点都挂载了多个磁盘设备
  • 走一遍正常的客户端向GFS请求文件的流程:

    client->master->master retrieve info from file tree and return the corresponding addr for every chunk -> client directly request the chunk nodes -> chunk nodes return chunks

  • Major part

    • failure-handing:

      1. 每一次元数据的更新,master节点都会先写入日志,再修改B+树,以防止宕机(write ahead log, 和InnoDB master线程先写重做日志再写回脏页一样的原则)
    • optimization:

      1. 元数据信息会被master加载到内存中,提高性能
      2. master节点并不实际持久化每一个chunk的位置信息。因为数据节点会定时汇报该机器上所有chunk的位置(告诉master它在这),同时由于每个chunk都有自己唯一的chunkID用作标识,所以master只在运行时将chunk的位置信息维护在内存
      3. 只持久化目录B+树和叶子节点到ChunkID的映射
    • 数据一致性:GFS定义了以下几种一致性(这一段我自己都不懂我在写什么。根本不能理解,挖个坑,慢慢填)

      1. defined状态已定义:从客户端角度来看,客户端完全了解已写入集群的数据,例如,客户端串行写入且成功,此时的状态是defined
      2. consistent:客户端来看chunk多副本的数据完全一致,但不一定defined,如下图2,一般发生在多客户端并发更新时
      3. inconsistent:多副本数据不一致
      4. undefined
    • 串行追加写结果肯定是defined,但是并行追加写的时候,可能会存在交织写的情况。由于只有主副本能决定写入请求的先后。所以当写入请求的范围有overlap时,就会导致consistent。即对三个chunk copy,内容一致,但是客户端并不知道并行请求的写入顺序,因此有可能自己写入的数据被覆盖,如图

      1563250141148

  • GFS租约:GFS在chunk多副本之间选择出一个主副本,由主副本来协调客户端的写入,保证多副本之间维持一个全局统一的更新顺序,GFS使用了租约。

  • 租约(Lease)是由GFS中心节点Master分配给chunk的某个副本的锁。持有租约的副本方可处理客户端的更新请求,客户端更新数据前会从Master获取该chunk持有租约的副本并向该副本发送更新请求。(再一层分布)

  • 租约下的读写流程示意:

  • 1563250346941

  • 文字版: 客户端向Master查询待写入的chunk的副本信息, Master返回副本列表,第一项为主副本,即当前持有租约的副本; 客户端向多副本推送待写入数据,这里的推送是指将数据发送至chunk多副本,chunkserver会缓存这些数据,此时数据并不落盘; 客户端向主副本发起Sync请求; 主副本将数据写入本地的同时通知其他副本将数据写入各自节点,此时数据方才落盘; 主副本等待所有从副本的sync响应; 主副本给客户端返回写入成功响应

  • 假如副本A1、A2、A3(A1是主副本),在写的过程中A3掉线,此时还能继续写么?

  • GFS在论文中说明了创建chunk时副本位置的选择算法:

  1. 选择存储空间利用率最低的节点和磁盘;

  2. 选择最近一段时间内新建chunk数量较少的节点和磁盘;

  3. 将多个副本分散在不同的rack上。

    1和3比较容易理解,2是为了保证一个节点/磁盘不会被频繁新建chunk(新建完接下来就是数据写入了),否则很容易沦为热点,导致磁盘IO和网络带宽被占满,影响效率。

  • Snapshot: 故障恢复机制,与checkpoint机制类似

  • master收到snapshot请求后:

    1. 回收所有租约,方便记录之后的chunk更改(为了COW做准备)(收回租约,方便节点数据更改)
    2. master在日志中记录本次snapshot操作,然后再内存中执行snapshot动作。具体是将被Snapshot的文件或目录的元数据复制一份,被复制出的文件与原始文件指向相同的chunk;(复制元数据,方便回滚)
  • 写完了发现自己写了一坨屎…坑先挖好,慢慢填吧。。。