zookeeper实战全面讲解(一)

zookeeper实战全面讲解(一)

这里没有太多的分析,只是做为一些简单配置及安装记录,生怕自己忘记了。

zk是什么?

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop的重要组件,CDH版本中更是使用它进行Namenode的协调控制。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。ZooKeeper的目标就是封装好复杂易出错的关键服务,提供简单易用的接口和性能高效、功能稳定的系统提供给用户。分布式应用程序可以基于它实现同步服务,配置维护和命名服务等

分布式协调技术主要用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种临界资源,防止造成"脏数据"的后果。

zk的角色

  1. Leader:领导者负责进行投票的发起与决议,更新系统状态,写数据,查看数据
  2. follower:用于接收客户端请求并向客户端返回结果,在选举过程中参与投票。
  3. observer:可以接收客户端连接,将写请求转发给leader节点,但observer不参与投票过程,只同步leader的状态。observer的目的是为了扩展系统,提高读写速度。

系统模型图

客户端请求处理器(requestprocessor),构成ZooKeeper服务的每个服务器都有一个备份。复制的数据库(replicateddatabase)是一个内存数据库,包含整个数据树。为了可恢复,更新会被log到磁盘,并且在更新这个内存数据库之前,先序列化到磁盘。

每个ZooKeeper都为客户端提供服务。客户端只连接到一个服务器,并提交请求。读请求直接由本地的复制数据库提供数据。对服务状态进行修改的请求、写请求通过一个约定的协议进行通讯。

作为这个协议的一部分,所有的写请求都被传送到一个叫“首领(leader)”的服务器,而其他的服务器,叫做“(随从)followers”,follower从leader接收信息修改的提议,并同意进行。当leader发生故障时,协议的信息层(messaginglayer)关注leader的替换,并同步到所有的follower。

ZooKeeper采用一个自定义的信息原子操作协议zab,由于信息层的操作是原子性的,ZooKeeper能保证本地的复制数据库不会产生不一致。当leader接收到一个写请求,它计算出写之后系统的状态,把它变成一个事务(二次提交协议)

zk的特点

  1. 最终一致性:client不论连接到哪个Server,展示给它都是同一个视图,这是zookeeper最重要的性能。
  2. 可靠性:具有简单、健壮、良好的性能,如果消息m被到一台服务器接受,那么它将被所有的服务器接受。
  3. 实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。
  4. 等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。
  5. 原子性:更新只能成功或者失败,没有中间状态。
  6. 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。
ZooKeeper的读写机制

Zookeeper是一个由多个server组成的集群一个leader,多个follower

  • 每个server保存一份数据副本
  • 全局数据一致
  • 分布式读写
  • 更新请求转发,由leader实施

zk的工作原理

Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。

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

选主流程

当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。先介绍basic paxos流程:

  1. 选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;
  2. 选举线程首先向所有Server发起一次询问(包括自己);
  3. 选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
  4. 收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;
  5. 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数, 设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。

通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于n+1.

每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。

fast paxos流程是在选举过程中,某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。

转载自http://blog.csdn.net/a807557328/article/details/78016928

zk的数据模型-Znode


从图中我们可以看出ZooKeeper的数据模型,在结构上和标准文件系统的非常相似,都是采用这种树形层次结构,ZooKeeper树中的每个节点被称为—Znode

Znode特点

zk的数据模型从结构上看似和Linux系统的文件系统相似,但是zk的znode节点非常却非常的不同。

引用方式

Zonde通过路径引用,如同Unix中的文件路径。路径必须是绝对的,因此他们必须由斜杠字符来开头。除此以外,他们必须是唯一的,也就是说每一个路径只有一个表示,因此这些路径不能改变,所以zk并没有相对路径存在。在ZooKeeper中,路径由Unicode字符串组成,并且有一些限制。
zk对路径的命名有一些要求,几乎所有的unicode编码都适用,除了以下几点:

  • \u0000 空字符不允许使用,因为会造成c语义绑定失败
  • \u0001 - \u001F 和 \u007F - \u009F范围内字符不允许使用,因为显示不友好且会confuse
  • \ud800 - uF8FF, \uFFF0 - uFFFF范围内字符也不允许使用
  • .和…不允许单独使用,zk不允许相对路径,比如”/a/b/./c”、”/a/b/…/c”是非法的,但”/a/b/.a/c”、”/a/b/…a/c”是合法的
  • 字符串“zookeeper”不允许使用,这是保留字,字符串"/zookeeper"用以保存管理信息,比如关键配额信息。
Znode结构

ZooKeeper命名空间中的Znode,兼具文件和目录两种特点。既像文件一样维护着数据、元信息、ACL、时间戳等数据结构,又像目录一样可以作为路径标识的一部分。图中的每个节点称为一个Znode。 每个Znode由3部分组成:

  • stat:此为状态信息, 描述该Znode的版本, 权限等信息
  • data:与该Znode关联的数据
  • children:该Znode下的子节点

ZooKeeper虽然可以关联一些数据,但并没有被设计为常规的数据库或者大数据存储,相反的是,它用来管理调度数据,比如分布式应用中的配置文件信息、状态信息、汇集位置等等。这些数据的共同特性就是它们都是很小的数据,通常以KB为大小单位。ZooKeeper的服务器和客户端都被设计为严格检查并限制每个Znode的数据大小一般在kb大小,至多1M,但常规使用中应该远小于此值。如果需要存储大型数据,建议将数据存放在hdfs等文件存储系统

数据访问

ZooKeeper中的每个节点存储的数据要被原子性的操作。也就是说读操作将获取与节点相关的所有数据,写操作也将替换掉节点的所有数据。另外,每一个节点都拥有自己的ACL(访问控制列表),这个列表规定了用户的权限,即限定了特定用户对目标节点可以执行的操作。

节点类型

节点类型有四种,分别是PERSISTENT、PERSISTENT_SEQUENTIAL、EPHEMERAL、EPHEMERAL_SEQUENTIAL,分别为永久节点,永久有序节点,临时节点和临时有序节点。节点的类型在创建时即被确定,并且不能改变。

  1. 临时节点:该节点的生命周期依赖于创建它们的会话。一旦会话(Session)结束,临时节点将被自动删除,当然可以也可以手动删除。虽然每个临时的Znode都会绑定到一个客户端会话,但他们对所有的客户端还是可见的。另外,ZooKeeper的临时节点不允许拥有子节点。
  2. 永久节点:该节点的生命周期不依赖于会话,并且只有在客户端显示执行删除操作的时候,他们才能被删除。
  3. 有序节点:当创建Znode的时候,用户可以请求在ZooKeeper的路径结尾添加一个递增的计数。这个计数对于此节点的父节点来说是唯一的,它的格式为"%10d"(10位数字,没有数值的数位用0补充,例如"0000000001")。当计数值大于2的32次方-1时,计数器将溢出。
哨兵watches

客户端可以在节点上设置watch,我们称之为监视器。当节点状态发生改变时(Znode的增、删、改)将会触发watch所对应的操作。当watch被触发时,ZooKeeper将会向客户端发送且仅发送一条通知,因为watch只能被触发一次,这样可以减少网络流量。

Znode的时间

查看node2节点的信息“get /node2”

[zk: 127.0.0.1:2181(CONNECTED) 2] get /node2
sdffff
cZxid = 0x200000007
ctime = Thu Dec 07 16:37:55 CST 2017
mZxid = 0x2400000006
mtime = Mon Dec 18 10:57:16 CST 2017
pZxid = 0x2400000004
cversion = 4
dataVersion = 8
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 2
  1. zxid
    致使ZooKeeper节点状态改变的每一个操作都将使节点接收到一个Zxid格式的时间戳,并且这个时间戳全局有序。也就是说,也就是说,每个对节点的改变都将产生一个唯一的Zxid。 每次节点的变更都会有一个自增票戳(stamp),例如0x200000009、0x20000000a、0x20000000b。
    ZooKeeper的每个节点维护者三个Zxid值为别为:cZxid、mZxid、pZxid

    • cZxid:节点创建票戳
    • mzxid:节点最后修改票戳
    • pzxid:子节点最后修改票戳

实现中Zxid是一个64为的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch。低32位是个递增计数。

  1. version
    对节点的任何变更,都会触发版本的升级,包括三个:

    • dataVersion:当前节点数据变更版本
    • cversion:子节点变更版本
    • aclVersion:变更版本
  2. time
    zk并没有使用真正的时间,而是存储相对与起始(epoch)的毫秒数,包括两个:—有疑问?
    ctime:创建时的毫秒数
    mtime:距离上次修改的毫秒数

  3. ephemeralOwner
    如果是ephemeral node节点,将会存储session id,否则存储为0;zk服务器会依据这个session id判断是否删除该临时节点。

  4. dataLength:当前节点存储的数据长度;

  5. numChildren:当前节点的子节点个数;

Watch触发器

(1) watch概述
ZooKeeper可以为所有的读操作设置watch,这些读操作包括:exists()、getChildren()及getData()。watch事件是一次性的触发器,当watch的对象状态发生改变时,将会触发此对象上watch所对应的事件。watch事件将被异步地发送给客户端,并且ZooKeeper为watch机制提供了有序的一致性保证。理论上,客户端接收watch事件的时间要快于其看到watch对象状态变化的时间。

(2) watch类型

ZooKeeper所管理的watch可以分为两类:

① 数据watch(data watches):getData和exists负责设置数据watch
② 孩子watch(child watches):getChildren负责设置孩子watch

我们可以通过操作返回的数据来设置不同的watch:
① getData和exists:返回关于节点的数据信息
② getChildren:返回孩子列表

因此
① 一个成功的setData操作将触发Znode的数据watch
② 一个成功的create操作将触发Znode的数据watch以及孩子watch
③ 一个成功的delete操作将触发Znode的数据watch以及孩子watch

(3) watch注册与处触发

  1. exists操作上的watch,在被监视的Znode创建、删除或数据更新时被触发。
  2. getData操作上的watch,在被监视的Znode删除或数据更新时被触发。在被创建时不能被触发,因为只有Znode一定存在,getData操作才会成功。
  3. getChildren操作上的watch,在被监视的Znode的子节点创建或删除,或是这个Znode自身被删除时被触发。可以通过查看watch事件类型来区分是Znode,还是他的子节点被删除:NodeDelete表示Znode被删除,NodeDeletedChanged表示子节点被删除。

Watch由客户端所连接的ZooKeeper服务器在本地维护,因此watch可以非常容易地设置、管理和分派。当客户端连接到一个新的服务器时,任何的会话事件都将可能触发watch。另外,当从服务器断开连接的时候,watch将不会被接收。但是,当一个客户端重新建立连接的时候,任何先前注册过的watch都会被重新注册。

(4) 需要注意的几点

Zookeeper的watch实际上要处理两类事件:
① 连接状态事件(type=None, path=null)
这类事件不需要注册,也不需要我们连续触发,我们只要处理就行了。
② 节点事件
节点的建立,删除,数据的修改。它是one time trigger,我们需要不停的注册触发,还可能发生事件丢失的情况。

上面2类事件都在Watch中处理,也就是重载的process(Event event)

节点事件的触发,通过函数exists,getData或getChildren来处理这类函数,有双重作用:
① 注册触发事件
② 函数本身的功能

触发只能一次触发,这个zk触发器的设计,这样可以减少网络流量,但是在我们使用中可以循环的去监听事件。所幸的是我们本身不用去写for循环之类的循环监听。而是通过zk提供的api来设置一个参数就OK了。
上面说的都是zk的本质,在使用过程中可以使用zkclient第三方的jar包,将大大简化我们的操作。

//使用zk原生的api,当设置为true时,则表示一直监听,如果为false则只会监听一次。
zooKeeper.getData(watchedEvent.getPath(), true, stat)

//使用zkclient订阅节点的变化,无须设置true或 false直接一直监听子节点的变化
zkClient.subscribeChildChanges("/node2", new ZkChildListener());

下载安装配置

单机部署

1.官网下载zookeeper
2.新建一个文件夹service(可以自己随意),将zookeeper解压到service文件夹下
3.进入到/service/zookeeper/conf这个目录
3.在conf目录下复制zoo_sample.cfg文件,改名为zoo.cfg,删除zoo_sample.cfg文件。
4.修改zook.cfg

tickTime=2000
dataDir=/service/data
dataLogDir=/service/dataLog        
clientPort=2181

伪集群部署

伪集群部署和集群部署差不多,只不过伪集群是在同一台机器上面部署多个zk。

service1文件夹下:
在service1文件夹下的data下面创建一个文件myid(没有后缀哦)里面填写1

tickTime=2000
clientPort=2181
dataDir=/service1/data
dataLogDir=/service1/dataLog
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890

service2文件夹下:
在service2文件夹下的data下面创建一个文件myid(没有后缀哦)里面填写2

tickTime=2000
##修改一下端口
clientPort=2182
dataDir=/service2/data
dataLogDir=/service2/dataLog
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890

service3下类似就OK了。

启动服务

进入到/service1/zookeeper/bin目录下启动service1
./zkServer.sh start

同样进入到/service2/zookeeper/bin目录下启动service2.

检查service是否启动成功。
echo stat|nc 127.0.0.1 2181

配置说明
  • client:监听客户端连接的端口。
  • tickTime:基本事件单元,这个时间是作为Zookeeper服务器之间或客户端与服务器之间维持心跳的时间间隔,每隔tickTime时间就会发送一个心跳;最小 的session过期时间为2倍tickTime
  • dataDir:存储内存中数据库快照的位置。如果不设置参数,更新事务的日志将被存储到默认位置。
  • dataLogdDir:这个操作让管理机器把事务日志写入“dataLogDir”所指定的目录中,而不是“dataDir”所指定的目录。这将允许使用一个专用的日志设备,帮助我们避免日志和快照的竞争
  • maxClientCnxns:这个操作将限制连接到Zookeeper的客户端数量,并限制并发连接的数量,通过IP来区分不同的客户端。此配置选项可以阻止某些类别的Dos攻击。将他设置为零或忽略不进行设置将会取消对并发连接的限制。
  • minSessionTimeout和maxSessionTimeout:即最小的会话超时和最大的会话超时时间。在默认情况下,minSession=2tickTime;maxSession=20tickTime。
集群配置

集群配置
(1) initLimit
此配置表示,允许follower(相对于Leaderer言的“客户端”)连接并同步到Leader的初始化连接时间,以tickTime为单位。当初始化连接时间超过该值,则表示连接失败。

(2) syncLimit
此配置项表示Leader与Follower之间发送消息时,请求和应答时间长度。如果follower在设置时间内不能与leader通信,那么此follower将会被丢弃。

(3) server.number=ip:leaderPort:zkPort
如:server.3=127.0.0.1:2890:3890
A:其中numbe是一个数字,表示这个是服务器的编号,从myid中的值对应
B:ip是这个服务器的 ip 地址;
C:leaderPort为Leader选举的端口;
D:zkPort为Zookeeper服务器之间的通信端口。

(4) myid和zoo.cfg
除了修改 zoo.cfg 配置文件,集群模式下还要配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面就有一个数据就是 A 的值,Zookeeper 启动时会读取这个文件,拿到里面的数据与 zoo.cfg 里面的配置信息比较从而判断到底是那个 server。

搭建要求:

  • zk服务器集群规模不小于3个节点
  • 要求各服务器之间系统时间要保持一致。

zk四字操作命令

nc为netcat命令的简写

echo stat | nc localhost 2181

conf: 输出相关服务配置的详细信息。
cons: 列出所有连接到服务器的客户端的完全的连接 / 会话的详细信息。包括“接受 / 发送”的包数量、会话 id 、操作延迟、最后的操作执行等等信息。
dump: 列出未经处理的会话和临时节点。
envi: 输出关于服务环境的详细信息(区别于 conf 命令)。
reqs: 列出未经处理的请求
ruok: 测试服务是否处于正确状态。如果确实如此,那么服务返回“ imok ”,否则不做任何相应。
stat: 输出关于性能和连接的客户端的列表。
wchs: 列出服务器 watch 的详细信息。
wchc: 通过 session 列出服务器 watch 的详细信息,它的输出是一个与 watch 相关的会话的列表。
wchp: 通过路径列出服务器 watch 的详细信息。它输出一个与 session 相关的路径。
crst: 重置当前这台服务器所有连接/会话的统计信息
srst: 重置服务器的统计信息
srvr: 输出服务器的详细信息。zk版本、接收/发送包数量、连接数、模式(leader/follower)、节点总数。

还可以使用telnet查看是否启动成功
telnet 10.1.101.162 2181连接后按回车,然后输入四字命令

zk的shell操作

进入到/server1/zookeeper/bin目录下面可以看到一个叫zkCli.sh的工具
./zkCli.sh -timeout 5000 -server 127.0.0.1:2181
进入到service1的zk的shell控制台中。
敲入:h查看帮助,会看到有10多个简单的命令,看帮助文档也知道它的使用了。

查看/节点

ls /

查看/节点状态

stat /

创建节点(必须是全路径,后面必须有值才能创建成功)

create /node1 111

创建子节点

create /node1/node1.1 11222

获取节点信息

get /node1/node1.1

创建一个有序节点

create -s /node2 222

创建一个临时节点

create -e /node2 222
临时节点会在与客户端连接断开后,自动删除

创建一个有序的临时节点

create -e -s /node2 3dsf

修改一个节点的值

set /node2 3333

监控管理工具

taokeeper;exhibitor
exhibitor的github下载源代码 https://github.com/Netflix/exhibitor,下载zip包。

  • 进入目录:exhibitor-master\exhibitor-master\exhibitor-standalone\src\main\resources\buildscripts\standalone\maven
  • 执行命令:mvn clean package
  • 把编译好的target下的jar上传到服务器,执行:java -jar exhibitor-1.5.6.jar -c file
  • 打开浏览器:http://127.0.0.1:8080/exhibitor/v1/ui/index.html
    exhibitor可以重启集群中的Zookeeper、查看节点信息、配置集群中的Zookeeper、查看log等操作

经过使用exhibitor好难用。

zk实际应用

主要有:命名服务,分布式锁,分布式队列,master选举服务等。
对zk的应该基本都是应该了zk的znode的特点:节点唯一性;临时节点自动删除;有序节点。

详细请参看

http://www.cnblogs.com/sunddenly/p/4092654.html

我自己的代码实现可以参看

https://github.com/henjuese/zookeeperDemo.git

zk异常

在Java API中的每一个ZooKeeper操作都在其throws子句中声明了两种类型的异常,分别是InterruptedException和KeeperException。

  1. InterruptedException异常

如果操作被中断,则会有一个InterruptedException异常被抛出。在Java语言中有一个取消阻塞方法的标准机制,即针对存在阻塞方法的线程调用interrupt()。一个成功的取消操作将产生一个InterruptedException异常。

ZooKeeper也遵循这一机制,因此你可以使用这种方法来取消一个ZooKeeper操作。使用了ZooKeeper的类或库通常会传播InterruptedException异常,使客户端能够取消它们的操作。InterruptedException异常并不意味着有故障,而是表明相应的操作已经被取消,所以在配置服务的示例中,可以通过传播异常来中止应用程序的运行。

  1. KeeperException异常

(1) 如果ZooKeeper服务器发出一个错误信号或与服务器存在通信问题,抛出的则是KeeperException异常。

①针对不同的错误情况,KeeperException异常存在不同的子类。

例如: KeeperException.NoNodeException是KeeperException的一个子类,如果你试图针对一个不存在的znode执行操作,抛出的则是该异常。

②每一个KeeperException异常的子类都对应一个关于错误类型信息的代码。

例如: KeeperException.NoNodeException异常的代码是KeeperException.Code.NONODE

(2) 有两种方法被用来处理KeeperException异常:

①捕捉KeeperException异常,并且通过检测它的代码来决定采取何种补救措施;

②另一种是捕捉等价的KeeperException子类,并且在每段捕捉代码中执行相应的操作。

  1. KeeperException异常分为三大类

① 状态异常

当一个操作因不能被应用于znode树而导致失败时,就会出现状态异常。状态异常产生的原因通常是在同一时间有另外一个进程正在修改znode。例如,如果一个znode先被另外一个进程更新了,根据版本号执行setData操作的进程就会失败,并收到一个KeeperException.BadVersionException异常,这是因为版本号不匹配。程序员通常都知道这种冲突总是存在的,也都会编写代码来进行处理。

一些状态异常会指出程序中的错误,例如KeeperException.NoChildrenForEphemeralsException异常,试图在短暂znode下创建子节点时就会抛出该异常。

② 可恢复异常

可恢复的异常是指那些应用程序能够在同一个ZooKeeper会话中恢复的异常。一个可恢复的异常是通过KeeperException.ConnectionLossException来表示的,它意味着已经丢失了与ZooKeeper的连接。ZooKeeper会尝试重新连接,并且在大多数情况下重新连接会成功,并确保会话是完整的。

但是ZooKeeper不能判断与KeeperException.ConnectionLossException异常相关的操作是否成功执行。这种情况就是部分失败的一个例子。这时程序员有责任来解决这种不确定性,并且根据应用的情况来采取适当的操作。在这一点上,就需要对“幂等”(idempotent)操作和“非幂等”(Nonidempotent)操作进行区分。幂等操作是指那些一次或多次执行都会产生相同结果的操作,例如读请求或无条件执行的setData操作。对于幂等操作,只需要简单地进行重试即可。对于非幂等操作,就不能盲目地进行重试,因为它们多次执行的结果与一次执行是完全不同的。程序可以通过在znode的路径和它的数据中编码信息来检测是否非幂等操怍的更新已经完成。

③不可恢复的异常

在某些情况下,ZooKeeper会话会失效——也许因为超时或因为会话被关闭,两种情况下都会收到KeeperException.SessionExpiredException异常,或因为身份验证失败,KeeperException.AuthFailedException异常。无论上述哪种情况,所有与会话相关联的短暂znode都将丢失,因此应用程序需要在重新连接到ZooKeeper之前重建它的状态。

zk的paxos协议与Zab(原子广播)

http://www.cnblogs.com/sunddenly/articles/4143859.html(讲解的比较好)

http://www.cnblogs.com/sunddenly/p/4138580.html

http://blog.csdn.net/jin5203344/article/details/53142027 (zab原子广播)

两次提交协议

ObServer扩展性

zookeeper存储文件格式

http://blog.csdn.net/pwlazy/article/details/8080626

参考地址

http://www.cnblogs.com/sunddenly/p/4018459.html (比较全面的讲解)
http://www.cnblogs.com/sunddenly/p/4033574.html
http://blog.csdn.net/koflance/article/details/78598324
http://blog.csdn.net/a807557328/article/details/78016928 《zk的leader流程图》

  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值