zookeeper

本文主要是来浅谈一下zookeeper,如果有什么不对的话,欢迎指教~

 

基本介绍

Zookeeper由雅虎研究院开发,是Google Chubby的开源实现,后来托管到Apache,于201011月正式成为Apache的顶级项目。

Zookeeper是一个经典的分布式数据一致性解决方案,致力于为分布式应用提供一个高性能、高可用,且具有严格顺序访问控制能力的分布式协调服务。

分布式应用程序可以基于Zookeeper实现数据发布与订阅、负载均衡、命名服务、分布式协调与通知、集群管理、Leader选举、分布式锁、分布式队列等功能。

ZooKeeper本质上是一个分布式的小文件存储系统。原本是Apache Hadoop的一个组件,现在被拆分为一个Hadoop的独立子项目,在HbaseHadoop的另外一个被拆分出来的子项目,用于分布式环境下的超大数据量的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定时检测每个机器。我们可以通过zookeeperEphemeral类型节点,再往注册watcher事件,一旦客户端与服务器会话结束与过期,那么该节点就会消失,并且将事件发给订阅者,这样监控系统就可以知道哪台机器下线了

 

Master选举:

我们可以通过ZookeeperEPHEMERAL_SEQUENTIAL的特性做一个简单的选举功能

 

基本原理

Zookeeper 有一个类似于文件系统的数据模型,由 znodes 组成。可以将 znodesZookeeper 数据节点)视为类似 UNIX 的传统系统中的文件,但它们可以有子节点。另一种方式是将它们视为目录,它们可以有与其相关的数据。每个这些目录都被称为一个 znode

该图表示了两个城市中的运动队的层次结构

zookeeper_第1张图片

 

znode

节点类型:ZK中有几种节点类型,节点类型在节点创建的时候就被确定且不可改变

临时节点(EPHEMERAL):临时创建的,会话结束节点自动被删除,也可以手动删除,临时节点不能拥有子节点

临时顺序节点(EPHEMERAL_SEQUENTIAL):具有临时节点特征,但是它会有序列号,分布式锁中会用到该类型节点

 

znode基本命令:

1ls /

2create [-e][-s] /weicheng aaa

3get /weicheng

4set /weicheng bbb

5delete /weicheng

6rmr /weicheng

持久节点(PERSISTENT):创建后永久存在,除非主动删除。

持久顺序节点(PERSISTENT_SEQUENTIAL):该节点创建后持久存在,相对于持久节点它会在节点名称后面自动增加一个10位数字的序列号,这个计数对于此节点的父节点是唯一,如果这个序列号大于2^32-1就会溢出。

 

zookeeper_第2张图片

zookeeper_第3张图片

 

Watcher

Watcher 的理念是启动一个客户端去接收从 Zookeeper 服务端发过来的消息并且同步地处理这些信息。Zookeeper Java API 提供了公共接口 Watcher,具体操作类通过实现这个接口相关的方法来实现从所连接的 Zookeeper 服务端接收数据。如果要处理这个消息,需要为客户端注册一个 callback(回调)对象。

public interface Watcher {

    abstract public void process(WatchedEvent event);        

}

zookeeper_第4张图片

zookeeper_第5张图片

 

角色介绍:

Leader: 负责进行投票的发起和决议,更新系统状态

Follower: 用于接受客户端请求并想客户端返回结果

Observer: follower用于接受客户端请求并想客户端返回结果

zookeeper_第6张图片zookeeper_第7张图片

 

ZAB

Zookeeper的核心是原子广播,这个机制保证了各个server之间的同步。实现这个机制的协议叫做ZAB协议

ZAB协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,ZAB就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leaderServer具有相同的系统状态

为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。

该协议需要做到以下几点:

1)集群在半数以下节点宕机的情况下,能正常对外提供服务

2)客户端的写请求全部转交给leader来处理,leader需确保写变更能实时同步给所有followerobserver

3leader宕机或整个集群重启时,需要确保那些已经在leader服务器上提交的事务最终被所有服务器都提交,确保丢弃那些只在leader服务器上被提出的事务,并保证集群能快速恢复到故障前的状态

4)任何时候都需要保证只有一个主进程负责进行事务操作,而如果主进程崩溃了,就需要迅速选举出一个新的主进程

 

zookeeper选举 :

leader选举是Zookeeper中最重要的技术之一,也是保证分布式数据一致性的关键所在。当集群中的一台服务器处于如下两种情况之一时,就会进入leader选举阶段——服务器初始化启动、服务器运行期间无法与leader保持连接。

选举阶段,集群间互传的消息称为投票,投票Vote主要包括二个维度的信息:SIDZXID

SID 为每个服务器的ID,集群中的每个zookeeper节点启动前就要配置好这个全局唯一的ID

ZXID 为服务器的事务ID ,该值是从机器DataTree内存中取的,即事务已经在机器上被commit过了。

 

节点进入选举阶段后的大体执行逻辑如下:

1)设置状态为LOOKING,初始化内部投票Vote (sid,zxid) 数据至内存,并将其广播到集群其它节点。节点首次投票都是选举自己作为leader,将自身的服务ID、处理的最近一个事务请求的ZXIDZXID是从内存数据库里取的,即该节点最近一个完成commit的事务id)及当前状态广播出去。然后进入循环等待及处理其它节点的投票信息的流程中。

2)循环等待流程中,节点每收到一个外部的Vote信息,都需要将其与自己内存Vote数据进行PK,规则为取ZXID大的,若ZXID相等,则取ID大的那个投票。若外部投票胜选,节点需要将该选票覆盖之前的内存Vote数据,并再次广播出去;同时还要统计是否有过半的赞同者与新的内存投票数据一致,无则继续循环等待新的投票,有则需要判断leader是否在赞同者之中,在则退出循环,选举结束,根据选举结果及各自角色切换状态,leader切换成LEADINGfollower切换到FOLLOWINGobserver切换到OBSERVING状态。

 

zookeeper_第8张图片

好了今天就先分享到这里先~欢迎大家评论~

你可能感兴趣的:(分布式)