认识ZooKeeper

  • 时间:
  • 浏览:
  • 来源:互联网

Zookeeper定义

Zookeeper是一个开源的分布式协调服务,Zookeeper的设计目标是将那些复杂且容易出错的分布式一致性封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。

Zookeeper原理

Zookeeper是一个典型的分布式数据一致性解决方案,分布式应用程序可以基于Zookeeper实现诸如数据发布/订阅,负载均衡,命名服务,分布式协调/通知,集群管理,Master选举,分布式锁和分布式队列等功能。

Zookeeper应用场景

Zookeeper一个最常用的使用场景就是用于担任生产者和服务消费者的注册中心,提供发布/订阅服务。服务生产者将自己提供的服务注册到Zookeeper中心,服务消费者在进行服务调用的时候先到Zookeeper中查找服务,获取到服务生产者的详细信息之后,再去调用服务生产者的内容与数据,如在Dubbo中,Zookeeper就担任注册中心的角色。

Zookeeper的特点

顺序一致性
从同一客户端发起的事务请求,最终将会严格地按照顺序被应用到Zookeeper中去。
原子性
所有竖起轻轻的处理结果在整个集群中所有机器上的应用情况时一直的,就是说,要么整个集群中多有的机器都成功应用了某一个事务,要么都没有应用。
单一系统映像
无论客户端连到哪一个zookeeper服务器,其看到的服务器数据模型都是一致的。
可靠性
一旦一次更改请求被应用,更改结果就会被持久化,直到被下一次更改覆盖

Zookeeper的设计目标

简单的数据模型
ZooKeeper 允许分布式进程通过共享的层次结构命名空间进行相互协调,这与标准文件系统类似。 名称空间由 ZooKeeper 中的数据寄存器组成 - 称为znode,这些类似于文件和目录。
可构建集群
为了保证高可用,最好是以集群形态部署Zookeeper,这样只要集群中大部分机器是可用的,那么zookeeper本身仍然可用。
顺序访问
对于来自客户端的每个更新请求,Zookeeper都会分配一个全局唯一的递增编号,这个编号反应了所有事物操作的先后顺序,应用程序可以使用Zookeeper这个特性来实现更高层次的同步原语,这个编号也叫时间戳-zxid。
高性能
Zookeeper是高性能的,在读多于写的应用程序中尤其的高性能,因为写会导致所有服务器同步状态。

Zookeeper集群角色

Leader
①Leader服务器是zk集群工作机制的核心.
②事务请求的唯一调度者和处理者,保证集群事务请求处理的顺序性.
Follower
①Follower服务器是zk集群状态的跟随者.
②处理非事务请求,转发事务请求给Leader服务器
③参与事务请求的proposal投票
④参与Leader选举投票
Observer
Observer是一种新型的zk节点,Observer服务器只提供非事务服务.通常用于不影响集群事务处理能力的前提下提升集群的非事务的处理能力,Observer有另外一个优势,因为它不参与投票,所以他们不属于zk集群的关键部位,即使他们Failed,或者从集群中断开,也不会影响集群的可用性。

Zookeeper脑裂

人本来就有一个大脑,但是突然某一天拥有两个或多个大脑,导致身体紊乱,称为脑裂;应用到我们正常的研发过程中的中间件,比如ElasticSearch、Zookeeper集群,而这些集群环境有一个统一的特点,就是它们有一个大脑,比如ElasticSearch集群中有Master节点,Zookeeper集群中有Leader节点。

Zookeeper脑裂场景

部署高可用集群,两个Zookeeper集群,集群A有三台,集群B有三台,互相通信,不考虑“过半机制”正常情况A集群选举Leader节点,网络环境都正常所以集群没有任何问题,当网络出现问题,集群A与集群B出现问题网络问题,那么通过ZK内部的选举节点集群A和集群B都会选举出Leader节点,这样在整个大的集群中就出现两个Leader节点,形成脑裂。

过半机制

Zookeeper领导者选举的过程中,如果某台zkServer获得了超过半数的选票,则此zkServer就可以成为Leader了,为什么需要用该算法机制呢?其实是因为这样利用该方法就不需要等待所有zkServer都投了同一个zkServer就可以选举出来一个Leader了,这样比较快也称“快速领导者选举”算法
源码如下

public class QuorumMaj implements QuorumVerifier {
	private static final Logger LOG = LoggerFactory.getLogger(QuorumMaj.class);
	int half;
	// n表示集群中zkServer的个数(准确的说是参与者的个数,参与者不包括观察者节点)
	public QuorumMaj(int n){
		this.half = n/2;
	}
	// 验证是否符合过半机制
	public boolean containsQuorum(Set set){
		// half是在构造方法里赋值的
		// set.size()表示某台zkServer获得的票数
		return (set.size() > half);
	}
}

应用部署
基本两个部署集群,A集群+B集群的数据目按照 2n+1和2n即可,因为这样部署通过过半机制即使网络断了要么没有leader要么只有一个leader这样保证ZK不会脑裂

如有雷同纯属巧合!

本文链接http://www.dzjqx.cn/news/show-617403.html