1

简介

zookeeper是分布式协调服务
可以在分布式系统中共享配置
可以用来实现分布式锁

zookeeper很像文件系统的目录,目录中的文件称为Znode
比如定义一个Znode: /canal/cluster
cluster里面可以定义

  • data:存储的数据
  • ACL:访问权限,即哪些用户/IP可以访问
  • stat:包含各种元数据,事务ID、版本号、时间戳、大小等
  • child:子节点

安装

这里使用docker安装zookeeper集群
新建文件stack.yml,这里定义了三个zookeeper节点,端口号分别是2181,2182,2183

version: '3.1'

services:
  zoo1:
    image: zookeeper
    restart: always
    hostname: zoo1
    ports:
      - 2181:2181
    environment:
      ZOO_MY_ID: 1
      ZOO_SERVERS: server.1=0.0.0.0:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181

  zoo2:
    image: zookeeper
    restart: always
    hostname: zoo2
    ports:
      - 2182:2181
    environment:
      ZOO_MY_ID: 2
      ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=0.0.0.0:2888:3888;2181 server.3=zoo3:2888:3888;2181

  zoo3:
    image: zookeeper
    restart: always
    hostname: zoo3
    ports:
      - 2183:2181
    environment:
      ZOO_MY_ID: 3
      ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=0.0.0.0:2888:3888;2181

执行命令docker-compose -f stack.yml up
可以发现已正常启动,并自动创建里一个zookeeper_default的network
image.png

docker-hub地址:https://hub.docker.com/_/zook...

ZK-Web

使用docker安装一个简单版的web

docker run -d \
  -p 8080:8080 \
  -e ZK_DEFAULT_NODE=192.168.0.100:2181/ \
  --name zk-web \
  -t tobilg/zookeeper-webui

访问localhost:80,即可看到znode节点信息
image.png

ZkCli

安装docker-cli执行环境,注意要设置network,可以使用docker network list等命令查看network信息

在docker安装ZkCli
docker run --network zookeeper_default -it --rm --link zookeeper_zoo1_1:zookeeper zookeeper zkCli.sh -server zookeeper

  • help:帮助命令
  • conect:连接zookeeper,host:port
  • ls:查看目录下znode列表
  • get:查看znode信息
  • set:设置znode值
  • create:创建znode -s代表创建顺序节点
  • delete:删除znode
  • stat:返回znode的详情信息
[zk: 192.168.101.92:2181,192.168.101.92:2182,192.168.101.92:2183(CONNECTED) 47] ls /
[otter, test, zookeeper]
[zk: 192.168.101.92:2181,192.168.101.92:2182,192.168.101.92:2183(CONNECTED) 48] create -s /test/req
Created /test/req0000000000
[zk: 192.168.101.92:2181,192.168.101.92:2182,192.168.101.92:2183(CONNECTED) 49] create -s /test/req
Created /test/req0000000001
[zk: 192.168.101.92:2181,192.168.101.92:2182,192.168.101.92:2183(CONNECTED) 50] create -s /test/req
Created /test/req0000000002
[zk: 192.168.101.92:2181,192.168.101.92:2182,192.168.101.92:2183(CONNECTED) 51] create -s /test/req
Created /test/req0000000003

zookeeper官方命令介绍:https://zookeeper.apache.org/...

原理

zookeeper是一主多从的架构,只有主可以写,从只能读
如果主挂掉了,则会自动选举出主节点,使用ZAB(Zookeeper Atomic Broadcast)协议保证数据的一致性

ZAB协议的状态

  • Looking:选举状态
  • Follwing:Follower节点的状态
  • Leading:Leader节点的状态

写Leader

  1. 客户端发送写请求到 Follower 节点
  2. Follower 节点将写入请求转发到 Leader 节点
  3. Leader 节点采用二阶段提交方法,先发送 Propose 广播给从节点
  4. 从节点接收到 Propose 消息,写入日志成功后,返回 ACK 消息给 Leader
  5. 主节点接收到过半以上的ACK,则广播Commit请求给从节点

读Leader/Follower

leader/follower都可以直接处理读请求,follower越多能处理的读请求量越大

基于TCP的FastLeaderElection选举算法

  • myid:集群中每台服务器的唯一id
  • zxid:类似事务ID,高32位是Leader的epoch,从1开始,每次选出新Leader,epoch+1,低32位是该epoch内的序号,每当epoch变化,会重置低32位

每个服务器在进行领导选举时,会发送如下关键信息:

  • logicClock 每个服务器会维护一个自增的整数,名为logicClock,它表示这是该服务器发起的第多少轮投票
  • state 当前服务器的状态
  • self_id 当前服务器的myid
  • self_zxid 当前服务器上所保存的数据的最大zxid
  • vote_id 被推举的服务器的myid
  • vote_zxid 被推举的服务器上所保存的数据的最大zxid

选举过程

  1. 自增选举轮次,对自己维护的logicClock  加 1
  2. 每个服务器最开始都是将票通过广播投给自己
  3. 接收外部投票,计入自己的投票箱,[2, 3]代表服务器2投票给了服务器3
  4. 先对比logicClock,若外部投票的LogicClock小于当前自己LogicClock,则忽略该投票,
  5. LogicClock一样,则对比zxid,投票给zxid大的服务器,并广播
  6. zxid一样,则对比myid,投票给myid大的,并广播
  7. 统计选票,如果过半服务器认可了自己的投票,则终止投票,更新自身状态为LEADING/FOLLOWING

查看服务器sid=3的选举日志
收到日志:n.sid:2, n.state:LOOKING, n.leader:2
state=LOOKING 代表正在选举,2投票给了2

收到日志:n.sid:2, n.state:LOOKING, n.leader:3
state=LOOKING 代表正在选举,2投票给了3 (因为初始情况下,LogicClock和zxid都一样,投给了sid最的3)

服务器2、服务器1都投票给了服务器3,所以服务器3成为LEADER

`2020-06-02 05:48:28,207 [myid:3] - INFO [ListenerHandler-/0.0.0.0:3888:QuorumCnxManager$Listener$ListenerHandler@1070] - Received connection request from /172.18.0.4:49944
2020-06-02 05:48:28,220 [myid:3] - INFO [WorkerReceiver[myid=3]:FastLeaderElection$Messenger$WorkerReceiver@389] - Notification: my state:LOOKING; n.sid:2, n.state:LOOKING, n.leader:2, n.round:0x1, n.peerEpoch:0x0, n.zxid:0x0, message format version:0x2, n.config version:0x0
2020-06-02 05:48:28,225 [myid:3] - INFO [WorkerReceiver[myid=3]:FastLeaderElection$Messenger$WorkerReceiver@389] - Notification: my state:LOOKING; n.sid:2, n.state:LOOKING, n.leader:3, n.round:0x1, n.peerEpoch:0x0, n.zxid:0x0, message format version:0x2, n.config version:0x0
2020-06-02 05:48:28,255 [myid:3] - INFO [ListenerHandler-/0.0.0.0:3888:QuorumCnxManager$Listener$ListenerHandler@1070] - Received connection request from /172.18.0.3:45270
2020-06-02 05:48:28,266 [myid:3] - INFO [WorkerReceiver[myid=3]:FastLeaderElection$Messenger$WorkerReceiver@389] - Notification: my state:LOOKING; n.sid:1, n.state:LOOKING, n.leader:1, n.round:0x1, n.peerEpoch:0x0, n.zxid:0x0, message format version:0x2, n.config version:0x0
2020-06-02 05:48:28,272 [myid:3] - INFO [WorkerReceiver[myid=3]:FastLeaderElection$Messenger$WorkerReceiver@389] - Notification: my state:LOOKING; n.sid:1, n.state:LOOKING, n.leader:3, n.round:0x1, n.peerEpoch:0x0, n.zxid:0x0, message format version:0x2, n.config version:0x0
2020-06-02 05:48:28,474 [myid:3] - INFO QuorumPeer[myid=3(secure=disabled):QuorumPeer@857] - Peer state changed: leading
2020-06-02 05:48:28,475 [myid:3] - INFO QuorumPeer[myid=3(secure=disabled):QuorumPeer@1465] - LEADING`

参考

https://dbaplus.cn/news-141-1...


小小的太阳
123 声望7 粉丝

reloading...