ZooKeeper学习笔记二 Paxos的工程实践
本文学习内容来自:
《从Paxos到ZooKeeper分布式一致性原理与实践》 电子工业出版社
https://www.cnblogs.com/leesf456/p/6005806.html
Chubby
Google Chubby是一个分布式锁服务,GFS和Big Table等大型系统都用它来解决分布式协作、元数据存储和Master选举等一系列与分布式锁服务相关的问题。Chubby的底层一致性就是以Paxos算法为基础的。
Chubby是一个面向松耦合分布式系统的锁服务。一个分布式锁服务的目的是允许它的客户端进程同步彼此的操作,并对当前所处环境的基本状态信息达成一致。针对这个目的,Chubby提供了粗粒度的分布式锁服务,开发人员不需要使用复杂的同步协议,而是直接调用Chubby的锁服务接口即可实现分布式系统多个进程之间粗粒度的同步控制,从而保证分布式数据的一致性。
应用场景
在Chubby的应用场景中,最为典型的就是集群中服务器的Master选举。GFS中使用Chubby锁服务来实现对GFSMaster服务器的选举。而在BigTable中,Chubby同样被用于Master选举,并且借助Chubby,Master能够非常方便地感知到其所控制的那些服务器。同时,通过Chubby,BigTable的客户端还能够方便地定位到当前Bigtable集群的Master服务器。此外,在GFS和Bigtable中,都使用Chubby来进行系统运行时元数据的存储。
设计目标
Chubby被设计成一个需要访问中心化节点的分布式锁服务。Chubby之所以设计成这样一个完整的分布式锁服务,是因为锁服务具有以下4个传统算法库所不具有的优点:
1. 对上层应用程序的侵入性更小
2. 便于提供数据的发布与订阅
3. 开发人员对基于锁的接口更为熟悉
4. 更便捷地构建更可靠的服务
同时,在Chubby的设计过程中,提出了以下几个设计目标:
- 提供一个完整的、独立的分布式锁服务,而非仅仅是一个一致性协议的客户端库
- 提供粗粒度的锁服务
- 在提供锁服务的同时提供对小文件的读写功能
- 高可用、高可靠
- 提供事件通知机制
Chubby技术架构
Chubby的整个系统结构主要由服务端和客户端两部分组成,客户端通过RPC调用与服务端进行通信。
一个典型的Chubby集群,或称为Chubby cell,通常由5台服务器组成。这些副本服务器采用Paxos协议,通过投票的方式来选举产生一个获得过半投票的服务器作为Master。一旦某台服务器成为了Master,Chubby就会保证在一段时期内不会再有其它服务器成为Master——这段时间被称为Master租期(Master lease)。在运行过程中,Master服务器会通过不断续租的方式来延长Master租期,而如果Master服务器出现故障,那么余下的服务器就会进行新一轮的Master选举,最终产生新的Master服务器,开始新的Master租期。
集群中的每个服务器都维护着一份服务器数据库的副本,但在实际运行过程中,只有Master服务器才能对数据库进行写操作,其它服务器都是使用Paxos协议从Master服务器上同步数据库数据的更新。
Chubby客户端通过向记录有Chubby服务端机器列表的DNS来请求获取所有的Chubby服务器列表,然后逐一发起请求询问该服务器是否是Master,在这个询问过程中,那些非Master的服务器,则会将当前Master所在的服务器标志反馈给客户端,这样客户端就能很快速的定位到Master服务器了。
只要该Master服务器正常运行,那么客户端就会将所有的请求都发送到该Master服务器上,针对写请求,Master会采用一致性协议将其广播给集群中所有的副本服务器,并且在过半的服务器接受了该写请求后,再响应给客户端正确的应答,而对于读请求,则不需要在集群内部进行广播处理,直接由Master服务器单独处理即可。
若该Master服务器发生故障,那么集群中的其他服务器会在Master租期到期后,重新开启新的一轮Master选举,通常一次Master选举大概花费几秒钟的时间,而如果其他副本服务器崩溃,那么整个集群继续工作,该崩溃的服务器会在恢复之后自动加入到Chubby集群中去,新加入的服务器首先需要同步Chubby最新的数据库数据,完成数据库同步之后,新的服务器就可以加入到正常的Paxos运作流程中与其他服务器副本一起协同工作。若崩溃后几小时后仍无法恢复工作,那么需要加入新的机器,同时更新DNS列表(新IP代替旧IP),Master服务器会周期性地轮询DNS列表,因此会很快感知服务器地址的变更,然后Master就会将集群数据库中的地址列表做相应的变更,集群内部的其他副本服务器通过复制方式就可以获取到最新的服务器地址列表了。
目录与文件
Chubby对外提供了一套与Unix文件系统非常相近但是更简单的访问接口。Chubby的数据结构可以看作是一个由文件和目录组成的树,其中每一个节点都可以表示为一个使用斜杠分割的字符串。典型的节点路径表示如下:
/ls/foo/wambat/pouch
其中,ls是所有Chubby节点所共有的前缀,代表着锁服务,是LockService的缩写。foo则指定了Chubby集群的名字,从DNS可以查询到一个或多个服务器组成该Chubby集群;剩余部分的路径则是一个真正包含业务含义的节点名字,由Chubby服务器内部解析并定位到数据节点。
Chubby的命名空间,包括文件和目录,称之为节点。在同一个Chubby集群数据库中,每一个节点都是全局唯一的。和Unix系统一样,每个目录都可以包含一系列的子文件和子目录列表,而每个文件中则会包含文件内容。Chubby的客户端应用程序也可以通过自定义的文件系统访问接口来访问Chubby服务端数据,比如可以使用GFS的文件系统访问接口,这就大大减少了用户使用Chubby的成本。
Chubby上的每个数据节点都分为持久节点和临时节点两大类,其中持久节点需要地调用API来进行删除,而临时节点则会在其对应的客户端会话失效后被自动删除。也就是说,临时节点的生命周期和客户端会话绑定,如果该临时对应的文件没有被任何客户端打开的话,那么它就会被删除掉。因此,临时节点通常可以用来进行客户端会议有效性的判断依据。
另外Chubby上的每个数据节点都包含了少量的元数据信息,其中包括用于权限控制的访问控制列表(ACL)的信息。同时,每个节点的元数据还包括4个单调递增的64位编号,分别如下:
- 实例编号
- 文件内容编号
- 锁编号
- ACL编号
锁和锁序列器
Chubby采用了锁延迟和锁序列器两种策略来解决由于消息延迟和重排序引起的分布式锁问题。
Chubby中的事件通知机制
常见的Chubby事件:
- 文件内容变更
- 节点删除
- 子节点新增、删除
- Master服务器转移
Chubby中的缓存
会话和会话**
KeepAlive请求
会话超时
Chubby Master故障恢复
Paxos协议实现
Chubby服务端的基本架构大致分为三层:
- 最底层的是容错日志系统,通过Paxos算法能够保证集群中所有机器上的日志完全一致,同时具备较好的容错性
- 日志层之上是Key-Value类型的容错数据库(Fault-Tolerant DB),其通过下层的日志来保证一致性和容错性
- 存储层之上就是Chubby对外提供的分布式锁服务和小文件存储服务。
Hypertable
Hypertable是一个使用C++语言开发的开源、高性能、可伸缩的数据库,其以Google的BigTable相关论文为基础指导,采用与HBase非常相似的分布式模型,其目的是要构建一个针对分布式海量数据的高并发数据库。
Hypertable只支持基本的增、删、改、查功能,不支持事务、关联查询。其优势是:
- 支持对大量并发请求的处理
- 支持对海量数据的管理
- 扩展性良好,在保证可用性的前提下,能够通过随意添加集群中的机器来实现水平扩容
- 可用性极高,具有非常好的容错性,任何节点的失败,既不会造成系统瘫痪也不会影响数据的完整性。