zookeeper 分布式系统中面临的很多问题, 如分布式锁, 统一的命名服务, 配置中心, 集群的管理 Leader 的选举等
环境准备
分布式系统中各个节点之间通信, Zookeeper 保证了这个过程中 数据的唯一性, 安全可靠
官网下载地址 http://mirror.bit.edu.cn/apache/zookeeper/
修改配置文件
将 / conf/zoo_sample.cfg 修改成 zoo.cfg
配置文件解读
- # zookeeper 服务器和客户端之间维持心跳的时间间隔, 即每个 ticktime 发送一个心跳包, 单位是毫秒
- # zookeeper 中 session 过期的时间是 ticktime*2
- tickTime=2000
- # Leader 允许 Follower 在 initLimit 时间内完成从 Leader 身上同步全部数据的工作, 随机集群的不断扩大, Follower 从 Leader 上同步数据的时间就会变成, 此时有必要, 默认是 0
- initLimit=10
- # Leader 会和集群中的其他机器进行通信, 在 syncLimit 时间内, 都没有从 Follower 上获取返回数据, 就认为这个节点挂了
- syncLimit=5
- # 存储快照文件的目录, 默认情况下事务日志也在这里了, 下面单独配置, 因为因为日志的写性能影响 zookeeper 的性能
- dataDir=E:\\zookeeper\\zookeeper-3.4.14\\data
- dataLogDir=E:\\zookeeper\\zookeeper-3.4.14\\log
- # the port at which the clients will connect
- # 客户端连接的端口
- clientPort=2181
- # the maximum number of client connections.
- # increase this if you need to handle more clients
- #maxClientCnxns=60
- #
- # Be sure to read the maintenance section of the
- # administrator guide before turning on autopurge.
- #
- # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
- #
- # The number of snapshots to retain in dataDir
- #autopurge.snapRetainCount=3
- # Purge task interval in hours
- # Set to "0" to disable auto purge feature
- #autopurge.purgeInterval=1
启动
启动的脚本在 /bin / 目录下
Linux 启动 ./zkCli.sh -server localhost:2181
****
启动成功, 进入客户端控制台
- # 默认的节点叫 zookeeper
- [zk: localhost:2181(CONNECTED) 1] ls /
- [zookeeper]
- # 创建一个节点
- [zk: localhost:2181(CONNECTED) 11] create /changwu1 "num1"
- Created /changwu1
- # 重新查看
- [zk: localhost:2181(CONNECTED) 14] ls /
- [zookeeper, changwu1]
- # 获取节点的内容
- [zk: localhost:2181(CONNECTED) 17] get /changwu1
- num1
- cZxid = 0x2
- ctime = Mon Sep 16 15:56:27 CST 2019
- mZxid = 0x2
- mtime = Mon Sep 16 15:56:27 CST 2019
- pZxid = 0x2
- cversion = 0
- dataVersion = 0
- aclVersion = 0
- ephemeralOwner = 0x0
- dataLength = 4
- numChildren = 0
- # 退出
- quit
- # 删除一个节点
- [zk: localhost:2181(CONNECTED) 32] delete /changwu1
- [zk: localhost:2181(CONNECTED) 33] ls /
- [zookeeper]
- # 递归删除节点
- rmr /path1/path2
这个 path1 和 path2 其实是两个节点
- # 修改节点数据
- set /path "value"
- # 节点的状态
- [zk: localhost:2181(CONNECTED) 50] stat /z1
- cZxid = 0x5
- ctime = Mon Sep 16 16:04:35 CST 2019
- mZxid = 0x7
- mtime = Mon Sep 16 16:06:31 CST 2019
- pZxid = 0x6
- cversion = 1
- dataVersion = 1
- aclVersion = 0
- ephemeralOwner = 0x0
- dataLength = 8
- numChildren = 1
- # 创建永久有序节点
- create -s /path
创建节点的形式, 和我们 mkdir, 创建一个目录结构是相似的
集群搭建
将 zoo.cfg 复制三份, 并修改配置文件
第二个端口 2887, 用来同步 Leader 和 Follower 之间的数据, 第三个端口选举新的 Leader 使用
在 tmp 目录创建六个目录 分别是 zoo_data_1-3 zoo_logs_1-3
创建 myid 文件
- [root@139 tmp]# echo 1> zoo_data_1/myid
- [root@139 tmp]# echo 2> zoo_data_2/myid
- [root@139 tmp]# echo 3> zoo_data_3/myid
启动集群服务端
- [root@139 bin]# ./zkServer.sh start ../conf/zoo1.cfg
- ZooKeeper JMX enabled by default
- Using config: ../conf/zoo1.cfg
- Starting zookeeper ... STARTED
- [root@139 bin]# ./zkServer.sh start ../conf/zoo2.cfg
- ZooKeeper JMX enabled by default
- Using config: ../conf/zoo2.cfg
- Starting zookeeper ... STARTED
- [root@139 bin]# ./zkServer.sh start ../conf/zoo3.cfg
- ZooKeeper JMX enabled by default
- Using config: ../conf/zoo3.cfg
- Starting zookeeper ... STARTED
分别查看各个节点的状态
- [root@139 bin]# ./zkServer.sh status ../conf/zoo3.cfg
- ZooKeeper JMX enabled by default
- Using config: ../conf/zoo3.cfg
- Mode: follower
- [root@139 bin]# ./zkServer.sh status ../conf/zoo1.cfg
- ZooKeeper JMX enabled by default
- Using config: ../conf/zoo1.cfg
- Mode: leader
- [root@139 bin]# ./zkServer.sh status ../conf/zoo2.cfg
- ZooKeeper JMX enabled by default
- Using config: ../conf/zoo2.cfg
- Mode: follower
连接客户端
./zkCli -server localhost: 服务端的端口号
- zkCli.sh -server localhost:2181
- zkCli.sh -server localhost:2182
- zkCli.sh -server localhost:2183
添加观察者
和前三个一样, 在 tmp 目录创建哨兵使用的目录 分别是 zoo_data_4 zoo_logs_4
在 zoo_data_4 目录下创建它 myid 文件, 写入 4
更改前三个节点的配置文件
- tickTime=2000
- initLimit=10
- syncLimit=5
- dataDir=/tmp/zoo_data_1
- dataLogDir=/tmp/zoo_logs_1
- clientPort=2181
- # 第一个端用于 Leader 和 Leanner 之间同步, 第二个端口, 用户选举过程中的投票通信
- server.1=localhost:2887:3887
- server.2=localhost:2888:3888
- server.3=localhost:2889:3889
- server.4=localhost:2890:3890:observer
添加观察者的配置文件
- tickTime=2000
- initLimit=10
- syncLimit=5
- dataDir=/tmp/zoo_data_4
- dataLogDir=/tmp/zoo_logs_4
- # 观察者的配置
- peerType=observer
- clientPort=2184
- # 第一个端用于 Leader 和 Leanner 之间同步, 第二个端口, 用户选举过程中的投票通信
- server.1=localhost:2887:3887
- server.2=localhost:2888:3888
- server.3=localhost:2889:3889
- server.4=localhost:2890:3890:observer
集群中的角色
Leader
发起投票和决议, 已经更新最终状态
Follower
接收处理客户端的请求, 参与 Leader 发起的决议
Observer
接受客户端的连接, 将请求转发给 Leader 字节, 但是它不参加投票, 而仅仅同步 Leader 的状态, 它的 zookeeper 拓展的方式
为什么会添加 Observer 呢? 这和 zookeeper 的工作方式息息相关:
一个 zookeeper 集群由多个 Server 组成, 每一个 Server 都可以去处理多个 client 的请求, 如果是读请求, 用当前的 Server 的本地数据库分本直接相应, 但是, 如果请求是改变 zookeeper 状态的写请求, 就变得麻烦起来, zookeeper 的 leader 节点会发起投票这个机制就是 zab 协议, 超过半数的节点同意时, 才会把这个操作加载到内存中, 并对 client 进行回复
在这个过程中, zookeeper 担任两个职能, 一方面接受客户端的连接, 另一方面又得去发起投票决议, 这两个功能限制了 zookeeper 的扩展想支持更多的客户端连接, 就得添加 server, 但是 server 越来越多每次发起投票就变的沉重, 于是 Observer 应运而生
Observer, 不会参加投票, 在其他节点处于投票阶段时, Observer 接收 client 的连接, 把连接转发的 leader, 而且, 它还会收到投票的处理结果, 从而大大提高系统的吞吐量
Leaner
和 Leader 一起同步状态的节点的统称, Observer 和 Follower 统称为 Leaner
Zookeeper 的 CPA
CP: 当集群中的节点仅仅剩下 Leader Follower 时, Leader 挂了, 就得重新选举, 选举的过程中系统不可用
AP: Leader Follower Observer , 这三者组成的就群, 实现了 AP, 当 Leader 挂了, 同样进行选举, 但是 Observer 可以继续接受 client 的请求, 只不过 Observer 中的数据可能不是最新的数据
来源: https://www.cnblogs.com/ZhuChangwu/p/11529117.html