本文主要是来浅谈一下zookeeper,如果有什么不对的话,欢迎指教~
•Zookeeper由雅虎研究院开发,是Google Chubby的开源实现,后来托管到Apache,于2010年11月正式成为Apache的顶级项目。
•Zookeeper是一个经典的分布式数据一致性解决方案,致力于为分布式应用提供一个高性能、高可用,且具有严格顺序访问控制能力的分布式协调服务。
•分布式应用程序可以基于Zookeeper实现数据发布与订阅、负载均衡、命名服务、分布式协调与通知、集群管理、Leader选举、分布式锁、分布式队列等功能。
•ZooKeeper本质上是一个分布式的小文件存储系统。原本是Apache Hadoop的一个组件,现在被拆分为一个Hadoop的独立子项目,在Hbase(Hadoop的另外一个被拆分出来的子项目,用于分布式环境下的超大数据量的DBMS)中也用到了ZooKeeper集群。
应用案例
•RPC服务框架: Dubbo
•Mysql Binlog的订阅与消费: Cannal
•分布式数据库同步系统: Otter
•分布式搜索平台: 终搜
•实时计算引擎: Jstorm
•Hbase
•Hadoop
•kafka
•应用中可以将一些配置信息放到 ZK 上进行集中管理,比如一些服务器的IP地址
•开源的dubbo就是将服务信息注册到ZK上
•一般存储的数量不能过大
命名服务:
•名称服务是将一个名称映射到与该名称有关联的一些信息的服务。电话目录是将人的名字映射到其电话号码的一个名称服务。同样,DNS 服务也是一个名称服务,它将一个域名映射到一个 IP 地址。在分布式系统中,您可能想跟踪哪些服务器或服务在运行,并通过名称查看其状态。Zookeeper 暴露了一个简单的接口来完成此工作。也可以将名称服务扩展到组成员服务,这样就可以获得与正在查找其名称的实体有关联的组的信息。
分布式协调通知:
•zookeeper中特有的watcher注册于异步通知机制,能够很好的实现分布式环境下不同系统之间的通知于协调,实现对数据变更的实时处理。使用方法通常是不同系统对ZK上同一个znode进行注册,监听znode的变化,其中一个系统修改了znode,那么另一个系统就能够收到通知,并作出相应的处理
分布式锁:
•分布式锁,这个主要得益于 Zookeeper 为我们保证了数据的强一致性,通常的做法是把 zk 上的一个 znode 看作是一把锁,通过 create znode 的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁
集群管理:
•集群管理,比如要监控集群机器,一般的做法是会有个监控系统,定时去检测机器是否存活,通常的做法就是通过ping定时检测每个机器。我们可以通过zookeeper的Ephemeral类型节点,再往注册watcher事件,一旦客户端与服务器会话结束与过期,那么该节点就会消失,并且将事件发给订阅者,这样监控系统就可以知道哪台机器下线了
Master选举:
•我们可以通过Zookeeper的EPHEMERAL_SEQUENTIAL的特性做一个简单的选举功能
•Zookeeper 有一个类似于文件系统的数据模型,由 znodes 组成。可以将 znodes(Zookeeper 数据节点)视为类似 UNIX 的传统系统中的文件,但它们可以有子节点。另一种方式是将它们视为目录,它们可以有与其相关的数据。每个这些目录都被称为一个 znode
•该图表示了两个城市中的运动队的层次结构
znode:
•节点类型:ZK中有几种节点类型,节点类型在节点创建的时候就被确定且不可改变
•临时节点(EPHEMERAL):临时创建的,会话结束节点自动被删除,也可以手动删除,临时节点不能拥有子节点
•临时顺序节点(EPHEMERAL_SEQUENTIAL):具有临时节点特征,但是它会有序列号,分布式锁中会用到该类型节点
znode基本命令:
•1、ls /
•2、create [-e][-s] /weicheng aaa
•3、get /weicheng
•4、set /weicheng bbb
•5、delete /weicheng
•6、rmr /weicheng
•持久节点(PERSISTENT):创建后永久存在,除非主动删除。
•持久顺序节点(PERSISTENT_SEQUENTIAL):该节点创建后持久存在,相对于持久节点它会在节点名称后面自动增加一个10位数字的序列号,这个计数对于此节点的父节点是唯一,如果这个序列号大于2^32-1就会溢出。
Watcher
Watcher 的理念是启动一个客户端去接收从 Zookeeper 服务端发过来的消息并且同步地处理这些信息。Zookeeper 的 Java API 提供了公共接口 Watcher,具体操作类通过实现这个接口相关的方法来实现从所连接的 Zookeeper 服务端接收数据。如果要处理这个消息,需要为客户端注册一个 callback(回调)对象。
public interface Watcher {
abstract public void process(WatchedEvent event);
}
角色介绍:
•Leader: 负责进行投票的发起和决议,更新系统状态
•Follower: 用于接受客户端请求并想客户端返回结果
•Observer: follower用于接受客户端请求并想客户端返回结果
ZAB:
•Zookeeper的核心是原子广播,这个机制保证了各个server之间的同步。实现这个机制的协议叫做ZAB协议
•ZAB协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,ZAB就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态
•为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。
该协议需要做到以下几点:
(1)集群在半数以下节点宕机的情况下,能正常对外提供服务
(2)客户端的写请求全部转交给leader来处理,leader需确保写变更能实时同步给所有follower及observer
(3) leader宕机或整个集群重启时,需要确保那些已经在leader服务器上提交的事务最终被所有服务器都提交,确保丢弃那些只在leader服务器上被提出的事务,并保证集群能快速恢复到故障前的状态
(4)任何时候都需要保证只有一个主进程负责进行事务操作,而如果主进程崩溃了,就需要迅速选举出一个新的主进程
zookeeper选举 :
leader选举是Zookeeper中最重要的技术之一,也是保证分布式数据一致性的关键所在。当集群中的一台服务器处于如下两种情况之一时,就会进入leader选举阶段——服务器初始化启动、服务器运行期间无法与leader保持连接。
选举阶段,集群间互传的消息称为投票,投票Vote主要包括二个维度的信息:SID、ZXID
•SID 为每个服务器的ID,集群中的每个zookeeper节点启动前就要配置好这个全局唯一的ID。
•ZXID 为服务器的事务ID ,该值是从机器DataTree内存中取的,即事务已经在机器上被commit过了。
节点进入选举阶段后的大体执行逻辑如下:
(1)设置状态为LOOKING,初始化内部投票Vote (sid,zxid) 数据至内存,并将其广播到集群其它节点。节点首次投票都是选举自己作为leader,将自身的服务ID、处理的最近一个事务请求的ZXID(ZXID是从内存数据库里取的,即该节点最近一个完成commit的事务id)及当前状态广播出去。然后进入循环等待及处理其它节点的投票信息的流程中。
(2)循环等待流程中,节点每收到一个外部的Vote信息,都需要将其与自己内存Vote数据进行PK,规则为取ZXID大的,若ZXID相等,则取ID大的那个投票。若外部投票胜选,节点需要将该选票覆盖之前的内存Vote数据,并再次广播出去;同时还要统计是否有过半的赞同者与新的内存投票数据一致,无则继续循环等待新的投票,有则需要判断leader是否在赞同者之中,在则退出循环,选举结束,根据选举结果及各自角色切换状态,leader切换成LEADING、follower切换到FOLLOWING、observer切换到OBSERVING状态。
好了今天就先分享到这里先~欢迎大家评论~