首页 GFS - Zookeeper-论文阅读
文章
取消

GFS - Zookeeper-论文阅读

GFS

GFS是Google于2003年发表的论文,在真实系统上构建了大范围的分布式文件系统。GFS 的地位相当之高,与MapReduce 以及 BigTable 作为早年间Google的大数据三驾马车,虽然这些年随着时代都逐渐被取代了。下面是Google 文件系统发展的系统分支。

image-20200723104934578

GFS的研究动机:Google拥有远超过单个磁盘容量的数据,例如从整个互联网爬出来的网页,YouTube视频,用来构建搜索索引的中间文件,Web服务器中的大量日志文件等。基于此,Google的目标是构建一个大型的,快速的文件系统。并且这个文件系统是全局有效的,这样各种不同的应用程序都可以从中读取数据。

背景与假设

  • 背景 1:分布式组件经常发生错误,应当将此视为常态而不是意外

    组件(也就是分布式系统中的 commodity hardware,可以理解为配置不高的商用主机)发生错误的原因有很多,比如:应用或者操作系统 BUG,人为错误、硬盘、内存、网络甚至是电源故障;

  • 背景 2:文件通常是大文件,而不是小文件

    这里的大文件是相对于传统标准而言的,比如 GB 在这属于大文件,KB 级别属于小文件;论文指出,应当操作大文件而不是小文件,即使系统本身支持 billion 级别(十亿个)的 kB 大小的文件的操作,但是这种操作也是不明智的,因为会明显巨大的额外开销。

    这是一个非常重要的假设,因为后面会提到 GFS 中直接将 chuksize 设置为 64 MB,因为我们面对的是大文件,因此即使以 64MB 这么大的空间作为存储的管理单元,磁盘空间的浪费也不会很严重。

    背景 3:大部分文件(主要是指字节数量占比高,而不是操作次数)通过 append(在已有的文件末尾追加)新数据的方式实现修改,而不是直接重写现有数据

    这是基于 Google 对 GFS 的应用场景的判断而做出的背景,因为大部分操作都是 append,因此 GFS 系统优化的中心也放在 record append 操作上。而对于随机写 GFS 仅仅给出一个存在不一致性问题的解决方案。

    总之,这种假设下 I/O 操作都是顺序 I/O,效率比随机 I/O 高很多。

  • 背景 4:协同设计应用以及文件系统可以提高系统整体灵活性,最终使整个系统收益

GFS的架构

一个 GFS cluster(集群)分为两个组件:

  • 单个 master 节点;
  • 多个 chunkserver 节点;

一个 GFS 集群同时可以被多个 client(客户)节点访问,架构图如下所示:

image-20200719162238223

可见 GFS 集群是一个典型 Master + Worker 结构。

Master + Worker 结构说的是存在一个 Master 来管理任务、分配任务,而 Worker 是真正干活的节点。在这里干的活自然是数据的存储和读取

Chunk Servers

GFS将一个大文件(比如10GB)分为多个Chunk,Chunk大小为64MB。Chunk分散存储在多台Chunk Server上。并且可以对文件做备份,一个Chunk可以复制多份分散存储。

下图体现了 GFS 分布式系统架构的分布式结构以及文件的分块存储特性

image-20200723110430786

Master

Master 周期性通过 HeartBeat 机制和每一个 chunkserver 进行通信,进行指令的发送以及状态信息的接收。

Master记录每个Chunk 的存储位置,相当于配置文件服务器(类似于中间件的名称服务器)。Master本身不做代理,由Client直接与chunkserver通讯。

GFS 仅仅只有一个 Master 服务器,这极大地简化了设计难度。

当然,这样也会引入问题。比如 GFS 的 Master 节点在故障以后,并没有自我恢复功能,虽然需要额外的机制来保证Master节点的高容错。论文中Master 节点需要人工地进行故障恢复,这会导致小时级别的 GFS 系统不可写

Master节点配置文件管理具体来说:

  • 客户端向 Master 节点请求的 metadata 数据直接存储于 Master 的内存中,避免每次请求都需要进行磁盘 I/O;

  • Master 节点使用日志(WAL Write-Ahead Log) + checkpoint 的方式来确保数据的持久化;(snapshot of memory)

一致性

放弃了强一致性

Zookeeper

介绍

  • Zookeeper是一个构建在Zab协议上的分布式独立服务,用来帮助人们构建分布式系统,极大的减轻构建分布式应用的痛苦。

  • Zookeeper内部的Zab协议和Raft协议非常相似,功能都是提供分布式一致性,内部实现也分为选举和日志同步。相比Raft来说,Raft不是一个你可以直接交互的独立的服务,你必须要设计你自己的应用程序来与Raft库交互。
  • Zookeeper通过放弃线性一致性来解决性能和一致性的矛盾。提供更弱的一致性,带来更强的性能,更多的服务器可以提供更强读性能。

一致性保证

Zookeeper提供以下的一致性保证:

  • 写请求是线性一致性的:写请求都经过leader节点,保证线性一致。读请求可以发送到任意副本节点,不保证线性一致。
  • 对于单个客户端是线性一致的
    • 任何一个客户端的请求,都会按照客户端指定的顺序来执行,论文里称之为FIFO(First In First Out)客户端序列。
    • 对于多个客户端并访问,不能保证一致性。即A客户端写入数据后,B客户端立即来读该数据,可能读取不到A客户端写入的数据。也就是说从Zookeeper读到的数据不能保证是最新的。
    • 从实现角度,Zookeeper给每条日志加上zxid的标签,响应请求时服务端返回最新zxid。客户端记录并在发送请求时带上该zxid,表明应该至少在zxid 的日志之后执行这个请求。

API设计

Zookeeper的API设计使得它可以成为一个通用的服务,从而分担一个分布式系统所需要的大量工作。那么为什么Zookeeper的API是一个好的设计?具体来看,因为它实现了一个值得去了解的概念:mini-transaction

之所以称之为mini-transaction,是因为Zookeeper并不能提供一个完整的数据库事务(transaction)。一个真正的数据库可以使用完整的通用的事务,你可以指定事务的开始,然后执行任意的数据读写,之后结束事务。数据库可以聪明的将所有的操作作为一个原子事务提交。一个真实的事务可能会非常复杂,而Zookeeper支持非常简单的事务,使得我们可以对于一份数据实现原子操作。这对于计数器或者其他的一些简单功能足够了。所以,这里的事务并不通用,但是的确也提供了原子性,所以它被称为mini-transaction。

Zookeeper可以用来做很多有用的事情

  • 用来发布其他服务器使用的配置信息。例如,向某些Worker节点发布当前Master的IP地址。
  • 用来选举Master。master节点挂掉后,需要让所有的节点都认可同一个新的Master节点。比如用到GFS中,用来实现Master切换。
  • MapReduce系统Worker的注册,任务的分配。

复制

像前面提到的GFS与Zookeeper系统,都致力于解决数据的同步问题,或者说是数据间复制的问题。

复制(Replication):为了提供高容错高可用性,最常见的解决方式就是复制。一个很有意思的问题是:复制能处理什么样的问题?复制并不是万能的。

  • 解决fail-stop故障:如果某些东西出了故障,就会单纯停止运行。
  • 不能处理软件中的bug和硬件设计中缺陷

复制的方式有两种

  • 状态转移(State Transfer):主服务器将完整状态都传输给备份服务器。这样的方案会较为简单,但需传输的数据量较大。
    • 举例:Ctrl+C, Ctrl+V
    • Raft协议中拷贝快照,快照迁移
  • 备份状态机(Replicated State Machine):将需要备份的服务器视为一个确定性状态机,服务器执行相同的命令进行状态更新,只要执行的命令相同,最终状态一定相同。方案较为复杂,但网络传输量小很多。
    • 举例:Raft协议
    • VMware 虚拟机主从备份

主从复制

主从复制(Primary-Backup Replication)是一种常用的复制手段:

主服务器负责写请求,从服务器负责读请求,从服务器时刻和主服务保持联系,与主服务器保持一致,这样当主服务器失效后备份服务器才能立刻接管。

主从复制

链式复制

链式复制(Chain Replication),是使用非常广泛的复制模型,要将数据复制到全部节点之后,再向client应答成功。链式复制在发展过程中,从基本链式复制发展出了多种改进版本,来改进复制延迟。

链式复制中,所有服务节点组成一条链。

  • Client写请求发送给Head节点,Head节点写入之后再转发给下一个节点,依次转发直到Tail节点。只有Tail节点更新成功后该写请求才commit。

  • Client写请求发送给Tail节点,Tail节点是最后一个更新,可以读取到所有已经commit的数据,保证强一致性。

img

image-20220912093117046

参考链接

  • 什么是数据库的一致性?一致性弱意味着什么?NoSQL 的弱一致性又为什么是可以被接受的? - 华为云开发者联盟的回答 - 知乎 https://www.zhihu.com/question/20113030/answer/1834857103

  • etcd 和传统的数据库有什么区别,为什么分布式架构都要用这个玩意儿? - 达的回答 - 知乎 https://www.zhihu.com/question/283164721/answer/2315076332

本文由作者按照 CC BY 4.0 进行授权

分布式MapReduce

什么是分布式事务?