转:
以下尝试说明Google所设计的对应Yahoo! Zookeeper的Chubby分布式锁服务的工作原理与方法。
首先,Chubby是什么?Chubby主要用于解决分布式一致性问题。在一个分布式系统中,有一组的Process,它们需要确定一个Value。于是每个Process都提出了一个Value,一致性就是指只有其中的一个Value能够被选中作为最后确定的值,并且当这个值被选出来以后,所有的Process都需要被通知到。这就是一致性问题。 其次,它是一个粗粒度的分布式锁服务。本质上,Chubby是Google设计的提供粗粒度锁服务的文件系统,存储大量小文件。每个文件就代表一个锁。在GFS中,创建文件就是进行“加锁”操作,创建文件成功的那个server其实就是抢占到了“锁”。用户通过打开、关闭、读取文件来获取共享锁或者独占锁;并通过通信机制,向用户发送更新信息。一群机器需要选举master时,这些机器同时申请某个锁文件。成功获取锁得服务器当选主服务器,并在文件中写入自己的地址。其他服务器通过读取文件中的数据获取master的地址。其他分布式系统可以使用它对共享资源的访问进行同步。同时这种锁服务是建议性的,而非强制性的,这样能带来更大的灵活性。 Chubby的设计目标基于以下几点:高可用性、高可靠性、支持粗粒度的建议性锁服务、支持小规模文件直接存储,这些当然是拿高性能与存储能力tradeoff来的。 图1是Chubby的整体架构,容易看出几点。一,Chubby共有5台服务器,其中一个是master,客户端与服务器之间使用RPC交互。我们会问,其他服务器是干什么的?没错,它们纯粹是作为master挂掉后的替代品。Zookeeper的多余服务器均是提供就近服务的,也就是,服务器会根据地理位置与网络情况来选择对哪些客户端给予服务。Chubby的这些Replica并不能提供这类服务。由此可见,Google佬的东西我们也不应该什么都盲目崇拜。Google也坦言,在设计Chubby时是战战兢兢的,生怕master挂掉就大手笔准备了5台。 图1 |
图2是Client与Chubby的通信协议。Keep Alive是周期性发送的一种消息,它有两方面功能:延长租约有效期,携带事件信息告诉客户端更新。事件包括:文件内容修改、子节点增删改、Master出错等。正常情况下,租约会由Keep Alive一直不断延长。这里我将图2中涉及的情况作适当阐述。如果C1在没用完租约期时发现还需使用,便发送锁请求给Master,Master给它Lease-M1;C2在租约期过了后,发送锁请求给Master,可是没收到Master的回答。其实此刻Master已经挂了,于是Chubby进入宽限期,在这期间Chubby要选举出新的Master。论文里对于这段时期有个更形象的名字—Grace Period,群龙无首的河蟹阶段呵呵。在选举出Master后,新老大下令前老大的发的Lease失效,大家必须申请一份新的。然后C2获得了Lease-M2。C3又恢复到正常情况。在图2中的4、5、6、7、8是通过Paxos算法选举Master的颤抖期。在此期间,最有可能产生问题,Amazon的分布式服务就曾因此宕机,导致很长时间service unavailable。
图2 |
最后想说的是,大部分系统都是靠在实践中运行很长一段时间才能谨慎的表示,目前系统已经基本没有发现大的问题了。Yahoo!开源的ZooKeeper是一个开源的类Paxos实现。它的编程接口看起来很像一个可提供强一致性保证的分布式小文件系统。但是,ZooKeeper并不是遵循Paxos协议,而是基于自身设计并优化的一个2 phase commit的协议,因此它的理论并未经过完全证明。要证明分布式容错算法的正确性通常比实现算法还困难,Google没法证明Chubby是可靠的,Yahoo!也不敢保证它的ZooKeeper理论正确性。