day09_zookeeper

1 ZooKeeper

它是一个为分布式协调服务,那么它提供了一个分布式锁服务,用以协调其他分布式的应用。

它是Google的Chubby一个开源的实现,Google的项目一般不开源,因为开源后别人也用不了,它的服务节点都非常之大

ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。

ZooKeeper代码版本中,提供了分布式独享锁、选举、队列的接口,代码在zookeeper-3.4.3\src\recipes。其中分布锁和队列有Java和C两个版本,选举只有Java版本。

2    在不知道 ZooKeeper 内部机制的情况下,很多源码是看不懂的

很多技术都依赖于zookeeper 动物管理员,而其他技术都有动物与之对应

做分布式移植性、高可用

案例1 基于zookeeper  rmi高可用

案例2 基于zookeeper  redis高可用  redis 3.0后有了自己的高可用

案例3 分布式锁的实现

3   大部分分布式应用都需要 1 主控 2 协调器(控制器)来管理分布的子进程(资源即存储--例如一般元数据

为了协调一致性,一般都放到zookeeper里,任务分配即计算)

keepalived是对lvs做高可用的,是前端的高可用。后台大部分用ZooKeeper做高可用

keepalived不同于zookeeper的最大的缺点是keepalived 可扩展性差

4    优点

1 最终一致性。

例如:有3台机器安装了zookeeper,每一个客户端登录时,看到的是同一个视图

当有其中一台数据被更新时,其他两台会定时的去同步数据,注意不是实时的,因此叫做最终一致性

如果需要最新的数据,应该在读取数据之前调用 sync()接口

2    各个客户端相互独立

3   原子性,对于整个集群来说(3台),要么全部更新成功,要么全部更新失败,不会有中间状态

4    顺序性,对于client端,先请求,先处理。因zk采用了递增的事务id号(zxid)来保证

5    zookeeper工作原理

1    zookeeper在启动时从磁盘加载到内存,为提高处理速度 每个server都存有一份数据

2    zookeeper启动时,将从实例中选举一个leader(主),其他的就变为了follower。怎么选举呢,paxos

3   leader负责数据的更新操作 由leader发起投票

4    当大多数server在内存中修改数据成功,才算操作成功

6    先说一下 Paxos

它是一个基于消息传递的致性算法,还被认为是 到目前止唯一的分布式致性算法,其他的算法也都是他基础上改进或简化

Paxos 所要注意的点

1 当提案的编号大于我手上的编号就默认同意,投赞成票

2 有一个议员发 了一个提议:将电费设定为 1元/度。

他会先看自己的记事本,嗯当前提议编号是0度。那么 我给我自己投一票,我的编号就修改为1了

编号就是 1,于是他给所有议员发消息,其他议员收到消息后,发现记录本上的数字为0,则赞成 回复给发消息的人,然后修改为1

注意,当发送提案的议员收到半数以上的回复时,它就会给所有人发通知,1号议案成立。其他人就会修改编号。

小岛--ZK Server Cluster   议员--zkServer     提议--ZNode(文件夹)增删改,注意 查看则不是提议

提议编号(PID)--Zxid(Zookeeper Transaction Id)自增 发起提议时会对应一个PID    正式法令--所有ZNode及数据 ,更新内存中的数据

7    Leader角色

解决冲突(两个PID相同,必然产生冲突)  例如 当两个人同时提出 1(PID)号提议时,由上面分析,只是生效了1个提议,而另一个人的提议就被拒绝了

那么,由于人人平等,这时就产生一个“活锁” (大家都没死都在动,但一直解决不了冲突问题)。必须有个总统leader

来提出

8    在选举Leader的时候,所有服务器都处于安全模式

9    paxos是zookeeper的灵魂,当然Zeekpeeper还有自己的东西:Session,Watcher,Version等

10    zookeeper的leader挂了后,它会自己选举出 leader,解决单点故障。自己对自己是高可用

当我有偶数台时,例如:

3台(LFF)(半数是1.5台) 也就说得保证有2台正常运行

4台(LFFF)(半数是两台),也就说得保证有3台正常运行

发现,当同样都是L挂掉后,从高可用角度分析2者可以实现样的效果,所以没必要多出一台

11    在zookeeper的配置文件 zoo.cfg 中

server.1=server1:2888:3888

server.A=B:C:D:

2888 表示的是这个服务器与集群中的Leader 服务器交换信息的端口;例如监控 flower的状态

3888 表示的是万一集群中的Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口

tickTime:发送心跳的间隔时间,tickTime=2000 单位:毫秒

dataDir:zookeeper保存数据的目录。启动时加载到内存,定期存储到磁盘 dataDir=/Users/zdandljb/zookeeper/data

clientPort:客户端连接Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。 clientPort=2181

initLimit:这个配置项是用来配置Zookeeper在初始化时去连接Follower,若发现隔了5*2000=10 秒秒了还没有收到Follower服务器心跳的心跳,那么我就认为连接失败。

syncLimit:这个配置项标识Leader 与Follower 之间发送消息,若在请求和应答时,过了2*2000=4 秒还没有收到,则认为Leader挂掉了。那么它就会去选举,但是这时

其他flower连接正常,那么其他flower事不会去选举的

12    查看zookeeper的角色  /home/zookeeper-3.4.6/bin zkServer.sh status

注意 谁是leader 谁先启动起来

zookeeper集群自己是高可用的

我们leader kill掉后,剩余两台,在这两台里谁先发现 leader挂掉后,它就会投票推举自己当 leader

13  zookeeper 的角色

1 Leader角色

2 follower 从

3 Observer 记者 ,不参与投票,Observer可以接受客户端的读取数据请求,增删改的请求要转发给leader,

若只通过增加follower的数量来水平扩展的话,虽然提高了读取速度,但增加了选举时间(因为当leader发起一个议案,要等

半数以上机器修改数据成功才算投票完成),所以zookeeper后来创建了observer这个角色

所以,zookeeper数量少的话可以不要 observer

同步leader状态,提高客户端读取速度,扩展系统功能。队列保持 client端的顺序性。

Observer是zookeeper的新特性,但用的不多

若一个集群里出现10台 zookeeper时,那么说明 及群里会有上千台服务节点来运算

集群里的服务器(不包括observer)要超过有效(不包括observer)服务器的半数 活着 这个集群正常

注意有3个角色,

leader里也会维护一个队列,所有的议案都会放到队列里,是否发出议案由 leader决定,每一个议案都有一个PID,

每一个PID对应一个 zxid 事物id(自增)

14    zookeeper 集群一般会独立存在,其他集群会 1用zookeeper来实现高可用 2 用zookeeper是存放元数据

(因为zookeeper本身也是高可用,而且又是分布式的,可以保持数据的最终一致性)

15  Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。

实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。

当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,

且大多数Server完成了和leader的状态同步以后,

恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。

paxos协议是为了实现选举,选举的目的是为了解决冲突,议案转为都由leader发出

zookeeper 的选主过程使用paxos,数据复制使用Zab

16    如果网络不段的情况下 leader去更新 follower中数据一般都会成功的

当被挂的机子重新起来的时候,会先去同步leader中的数据

17  为什么必须要有半数以上的机器把数据更新成功才算成功,因为它是为了保证,万一leader挂掉后,至少还有半数以上机器拥有最新的数据,

而新的leader的数据必须是最新的。如果拥有旧数据的人要求当leader的话,由于他的PID小,会被拒绝,也可以这么认为:就是说

拥有最新数据的机器多点,也就是候选人多。

18    zxid 是为了 在znode在增删改时事务。zookeeper里管每条数据为znode节点

ZooKeeper状态的每一次改变, 都对应着一个递增的Transaction id, 该id称为zxid.

由于zxid的递增性质, 如果如果事务1 zxid1和事务2 zxid2同时要求leader修改数据znode,且zxid1小于zxid2, 那么zxid1会先进行.

创建任意节点, 或者更新任意节点的数据,

或者删除任意节点, 都会导致Zookeeper状态发生改变, 从而导致zxid的值增加.

19  注意znode和目录的区别是 它本身也可以写数据

cli.sh   ls /     -h

create /20160422 helloword!!!

get /20160422

cZxid = 0x4900000002  create的时候,create这个事务的id    0x49表示leader

ctime = Fri Apr 22 11:33:59 CST 2016

mZxid = 0x4900000002  修改的事务id

mtime = Fri Apr 22 11:33:59 CST 2016

pZxid = 0x4900000002

cversion = 0

dataVersion = 0

aclVersion = 0

ephemeralOwner = 0x0

dataLength = 12

numChildren = 0

create /20160422/curry currycontent!!

get /20160422

set /20160422/curry currsafsa!!

cZxid = 0x4900000003  事务id加1

20  注意leader重新选择后 mZxid统统改成0

21  Znode有两种类型,短暂的(ephemeral)和持久的(persistent),默认是 persistent

创建节点时的两种类型  断开连接超过 设置的时间后,如果该节点是 ephemeral,则删除

Znode是zookeeper的一种数据节点类型

22  zookeeper的watcher会监控 zookeeper的znode节点,一个znode对应一个watcher

zkfc就相当于zookeeper的客户端,当namenode启动后,zkfc会在zookeeper中建立一个临时 znode节点,

当namenode挂掉后,zookeeper会删除这个临时节点,同时被watcher监控到zookeeper节点发生了变化,给其他namenode发送消息

23  yarn是mapreduce的资源调度框架。resourceManager和zkfc是zookeeper客户端

24  案例

用zookeeper对3个 基于RMI协议服务的高可用的底层实现。

思路:

把3个server的url地址存到zookeeper中

client 不去直接找server,它去找zookeeper,去里面去可用的url

client再去连 server

Dubbox里面无非就是封装了各种各样的协议,然后全帮做了一个高可用

zookeeper做分布式移植性

26    案例 zookeeper的分布式锁

假设有100服务器,user1 user2 两个用户。谁获得了分布式锁,谁就可以控制这个集群

用zookeeper来实现分布式锁

zookeeper作用

1  自己高可用

2  znode节点(4中类型)

3  在znode节点上提供一个watcher

4  提供了一个java类

zookeeper的选举只是自己leader的选举,而不是对其客户端的选举

对于分布式锁,zookeeper创建一个分布式锁,然后让客户端按顺序的来获取分布式锁

1  客户端要排队,首先应在zookeeper中创建一个节点,证明你来排队了

2  获取到这个队列,判断是否在第一个,是就得到锁,不是则监控排在自己前面的那个节点(也就是往它身上放个 watcher

然后就是等待watcher给你发消息)

watcher发送消息只会发一次,如果你想要一直检测则需要在发消息时再注册一次

时间: 2024-11-14 12:49:57

day09_zookeeper的相关文章