环境:
- 拥有三台服务器,假设三台服务器的Ip地址为 172.18.19.143,172.18.19.15,172.18.19.129
- 开放三台服务器的2287,3387端口
集群搭建步骤:
1. 修改zookeeper服务器对应的配置文件:添加
server.1=172.18.19.143:2287:3387 server.2=172.18.19.15:2287:3387 server.3=172.18.19.129:2287:3387
说明:
#集群配置信息 #server.A=B:C:D # A:是一个数字,表示这个是服务器编号 # B:是这个服务器的ip地址 # C:zk服务器之间的通信端口 # D:Leader选举的端口
2. 在zk的新建的data目录下新建文件myid,将步骤1中的数字A添加到文件中
3. 使用./zkCli.sh -server 172.18.19.143:2181 登录指定的服务器
至此,集群已搭建完成。
zookeeper一致性协议:
zab协议全称为Zookeeper Atomic Broadcat(zk原子广播)。zk是通过zab协议来保证分布式事务的最终一致性。
基于zab协议,zk集群中的角色主要有以下三类:
- Leader: 领导者负责进行投票的发起和决议,更新系统状态。
- Learner:
- Follower: Follower用于接收客户请求并向客户端返回结果,在选举过程中参与投票
- Observer: Observer可以接收客户端连接,将写请求转发给leader节点。但Observer不参与投票过程,只同步leader的状态。Observer的目的是为了扩展系统,以提高读取速度。
- Client:请求发起方
写请求保持一致性过程:
- leader从客户端收到一个写请求
- leader生成一个新的事务并为这个事务生成一个唯一的ZXID
- leader将这个事务提议(propose)发送给所有的follows节点
- follower节点将收到的事务请求加入到历史队列(history queue)中,并发送ack给leader
- 当leader收到大多数follower(半数以上节点)的ack消息,leader会发送commit请求
- 当follower收到commit请求时,从历史队列中将事务请求commit
zookeeper的leader选举:
服务器状态:
- looking:寻找leader状态。当服务器处于该状态时,它会认为当前集群没有leader,因此需要进入leader选举状态。
- leading:领导者状态。表明当前服务器角色是leader.
- following: 跟随者状态。表明当前服务器角色是follower。
- observing: 观察者状态。表明当前服务器角色是Observer。
服务器启动时期的leader选举:
在集群初始化阶段,当有一台服务器server1启动时,其单独无法进行和完成leader选举,当第二台服务器server2启动时,此时两台机器可以相互通信,每台机器都试图找到leader,于是进入leader选举过程。选举过程如下:
- 每个server发出一个投票。由于是初始情况,server1和server2都会将自己作为leader服务器来进行投票,每次投票会包含所推举的服务器的myid和zxid,使用(myid,zxid)来表示,此时server1的投票为(1,0),server2的投票为(2,0),然后各自将这个投票发给集群中的其它机器。
- 集群中的每台服务器接收来自集群中各个服务器的投票。
- 处理投票。针对每一个投票,服务器都需要将别人的投票和自己的投票进行Pk,pk规则如下:
- 优先检查zxid。zxid比较大的服务器优先作为leader。
- 如果zxid相同,那么就比较myid。myid较大的服务器作为leader服务器。
- 对于server1而言,它的投票是(1,0),接收server2的投票为(2,0),首先会比较两者的zxid,均为0,再比较myid,此时server2的myid最大,于是更新自己的投票为(2,0),然后重新投票;对于server2而言,其无需更新自己的投票,只是再次向集群中所有机器发出上一次投票信息即可
- 统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接收到相同的投票信息,对于server1、server2而言,都统计出集群中已经有两台机器接收了(2,0)的投票信息,此时便认为已经选举出了leader。
- 改变服务器状态。一旦确定了leader,每个服务器就会更新自己的状态,如果是follower,那么就变更为following,如果是leader,就会变更为leading。
服务器运行时期的Leader选举:
在zk运行期间,leader与非leader服务器各司其职,即便当有非leader服务器宕机或者新加入,此时也不会影响leader,但是一旦leader服务器宕机了,那么整个集群将会暂停对外服务,进入新一轮leader选举,其过程和启动时期的Leader选举过程基本一致。
假设正在运行的有server1,server2,server3三台服务器,当前leader是server2,若某一时刻leader挂了,此时便开始leader选举。选举过程如下:
- 变更状态。leader挂后,余下的服务器会将自己的服务器状态变更为looking,然后开始进入leader选举过程。
- 每个server会发出一个投票。在运行期间,每个服务器上的zxid可能不同,此时假定server1的zxid为122,server3的zxid为122,在第一轮投票中,server1和server3都会投自己,产生投票(1,122),(3,122),然后各自将自己的投票发送给集群中的所有机器。
- 接收来自各个服务器的投票.与启动过程相同。
- 处理投票。与启动过程相同。此时,server3将会成为leader.
- 统计投票。与启动时过程相同。
- 改变服务器的状态。与启动时过程相同。
observer角色及其配置:
observer角色特点:
- 不参与集群的leader选举
- 不参与集群中写数据时的ack反馈
配置步骤:
- 为了使用observer角色,在任何想编程observer角色的配置文件中加入如下配置:
-
peerType=observer
-
在所有server的配置文件中,配置成observer模式的server的那行配置追加:observer,例如:
server.3=192.168.60.130:2289:3389:observer
-