在之前说HDFS和HBase架构的时候就说到了Zookeeper,在分布式系统的多台服务器要对数据状态达成一致,其实是一件很有难度的事情,因为服务器集群的硬件的问题随时会发生,所以对数据的记录保持一致,是需要一定技巧的。
今天要说的就是分布式系统一致性和Zookeeper架构。
我们知道HDFS为了保证整个集群的高可用,需要部署两台NameNode服务器,一台作为主服务器,一台作为从服务器。当主服务器宕机,就切换到从服务器上访问。但是如果不同的应用程序或者DataNode做出的关于主服务器是否可以用的判断不同,就会出错。
比如说,我们有两个应用程序都需要对一个相同的文件路径进行读写,但是这两个应用程序对于哪台是namenode的判断不同,就会连接到不同的namenode上,就会引起数据冲突,同一个文件指向了两份不同的数据。
这就叫做“脑裂”,为了防止脑裂产生的根本,我们需要单独引入一个进行判断的服务器当裁判,让裁判去决定哪个服务器是主服务器。
这样确实是个好注意,但是如果这个进行判断的服务器也宕机,那不是又脑裂了?所以为了保证高可用,必须准备多台服务器来保证不会因为某一台宕机而影响系统的可用性。
那么问题又来了,这些用于判断的服务器又如何防止自身脑裂?
这时,我们就有了Zookeeper,来保证多台服务器的状态一致性。
Paxos算法与ZooKeeper架构
比如一个提供锁服务的分布式系统,由多台服务器构成一个集群对外提供锁服务,应用程序连接到任意一台服务器都可以获取或者释放锁,因此这些服务器必须严格保证状态一致,要把获取和释放锁的对象确认好了,是很难的事情,所以,就有了Paxos算法。
应用程序连接到任意一台服务器后提起状态修改请求(也可以是获得某个状态锁的请求),然后这个服务器会将这个请求发送给其他集群进行举手表决,如果某个服务器同时收 到了另一个应用程序同样的修改请求,那就会拒绝之前的表决,并且自己也发起一个举手表决,然后其他服务器再根据时间戳和服务器排序规则进行举手表决。
表决结果会发送给所有服务器,而发起表决的服务器会根据举手表决决定是否执行程序。
Paxos算法比较复杂,为了简化实现,ZooKeeper使用了一种叫ZAB(ZooKeeper原子消息广播协议)的算法使Zookeeper集群保证数据更新的一致性,并且通过集群方式保证Zookeeper系统高可用。但是Zookeeper集群中都存储了相同的信息,也就是数据不满足分片耐受性。
以下为Zookeeper存储数据的结构:
应用程序可以通过路径的方式访问Zookeeper中的数据,比如/services/Yaview/services/stupidname这样的路径方式修改,读取数据。Zookeeper还支持监听模式,当数据发生改变的时候,通知应用程序。
因为大数据的系统普遍都是一主多从,主服务器管理的是集群的状态和metaInfo,为了保证集群不脑裂,所以运行期只有一个老大工作,举hdfs的例子来说,也就是一个Active状态的Namenode,但是为了保证高可用,所以还需要一个Standby状态的Namenode。
那么问题就来了,其他服务器集群怎么知道哪个是active namenode,哪个是standby namenode?
所以大数据系统更多的都是依赖于Zookeeper,当主服务器启动的时候,会自动告知Zookeeper自己是老大,还是active的老大,保证程序正常运行。
因为ZooKeeper系统的多台服务器存储相同数据,并且每次数据更新都要所有服务器投票表 决,所以和一般的分布式系统相反,ZooKeeper集群的性能会随着服务器数量的增加而下降。
ZooKeeper通过Paxos选举算法实现数据强一致性,并为各种大数据系统提供主服务器选举服 务。虽然ZooKeeper并没有什么特别强大的功能,但是在各类分布式系统和大数据系统中, ZooKeeper的出镜率非常高,因此也是很多系统的基础设施。