1. 概述

这里是 Docker 实战系列第四篇。主要介绍分布式系统中的元老级组件 Zookeeper。

ZooKeeper 是一个开源的分布式协调服务,是 Hadoop,HBase 和其他分布式框架使用的有组织服务的标准。

分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。

读过 Docker 实战之 Consul 集群 的小伙伴应该有印象,里边有一张一致性算法的对比图。所有的分布式系统都面临着 CAP 理论的抉择,都需要一致性算法的保障。这里先放上一个简单的总结,用于大家借鉴那些顶级开源软件在分布式上的思路。

分布式组件 算法/协议 服务
Redis Cluster Gossip master 提供读写,slave 只备份
Zookeeper ZAB Leader 提供读写,Follower 只读,遇到写请求转发给 Leader
Kafka ZK 临时节点 只有 leader 提供读写服务

2. 应用场景

大致来说,zookeeper 的使用场景如下:

  • 分布式协调
  • 分布式锁
  • 元数据/配置信息管理
  • HA 高可用性
  • 发布/订阅
  • 负载均衡
  • Master 选举

这里引用中华石杉老师的例子

2.1 分布式协调

这个其实是 zookeeper 很经典的一个用法,简单来说,就好比,你 A 系统发送个请求到 mq,然后 B 系统消息消费之后处理了。那 A 系统如何知道 B 系统的处理结果?用 zookeeper 就可以实现分布式系统之间的协调工作。A 系统发送请求之后可以在 zookeeper 上对某个节点的值注册个监听器,一旦 B 系统处理完了就修改 zookeeper 那个节点的值,A 系统立马就可以收到通知,完美解决。

2.2 分布式锁

举个栗子。对某一个数据连续发出两个修改操作,两台机器同时收到了请求,但是只能一台机器先执行完另外一个机器再执行。那么此时就可以使用 zookeeper 分布式锁,一个机器接收到了请求之后先获取 zookeeper 上的一把分布式锁,就是可以去创建一个 znode,接着执行操作;然后另外一个机器也尝试去创建那个 znode,结果发现自己创建不了,因为被别人创建了,那只能等着,等第一个机器执行完了自己再执行。

2.3 元数据/配置信息管理

zookeeper 可以用作很多系统的配置信息的管理,比如 kafka、storm 等等很多分布式系统都会选用 zookeeper 来做一些元数据、配置信息的管理,包括 dubbo 注册中心不也支持 zookeeper 么?

2.4 HA 高可用性

这个应该是很常见的,比如 hadoop、hdfs、yarn 等很多大数据系统,都选择基于 zookeeper 来开发 HA 高可用机制,就是一个重要进程一般会做主备两个,主进程挂了立马通过 zookeeper 感知到切换到备用进程。

3. Docker 配置

docker-compose-zookeeper-cluster.yml

version: '3.7'

networks:
docker_net:
external: true services:
zoo1:
image: zookeeper
restart: unless-stopped
hostname: zoo1
container_name: zoo1
ports:
- 2182: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
volumes:
- ./zookeeper/zoo1/data:/data
- ./zookeeper/zoo1/datalog:/datalog
networks:
- docker_net zoo2:
image: zookeeper
restart: unless-stopped
hostname: zoo2
container_name: zoo2
ports:
- 2183: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
volumes:
- ./zookeeper/zoo2/data:/data
- ./zookeeper/zoo2/datalog:/datalog
networks:
- docker_net zoo3:
image: zookeeper
restart: unless-stopped
hostname: zoo3
container_name: zoo3
ports:
- 2184: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
volumes:
- ./zookeeper/zoo3/data:/data
- ./zookeeper/zoo3/datalog:/datalog
networks:
- docker_net

启动集群

docker-compose -f docker-compose-zookeeper-cluster.yml up -d

4. 集群初认识

在 ZAB 算法中,存在 Leader、Follower、Observer 三种角色,现在我们就来认识下它们。

  • 查看 zoo1 角色
➜  docker docker exec -it zoo1 /bin/sh
# zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower

由上结果可知,zoo1 是 follower

  • 查看 zoo2 角色
➜  docker docker exec -it zoo2 /bin/sh
# zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower

由上结果可知,zoo2 是 follower

  • 查看 zoo3 角色
➜  docker docker exec -it zoo3 /bin/sh
# zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: leader

由上结果可知,zoo3 是 leader。负责集群的读写。

  • 查看 zoo3 选举数据
➜  docker echo srvr | nc localhost 2184
Zookeeper version: 3.5.6-c11b7e26bc554b8523dc929761dd28808913f091, built on 10/08/2019 20:18 GMT
Latency min/avg/max: 0/0/0
Received: 2
Sent: 1
Connections: 1
Outstanding: 0
Zxid: 0x100000000
Mode: leader
Node count: 5
Proposal sizes last/min/max: -1/-1/-1
  • 查看映射数据

如果实践了上述操作的小伙伴一定会发现,映射路径下的文件夹多了好多东西,感兴趣的小伙伴可以打开看一下,了解下 ZAB 的选举算法(没错,里边记录的就是选举相关的数据)。

➜  zookeeper cd zoo1
➜ zoo1 tree
.
├── data
│   ├── myid
│   └── version-2
│   ├── acceptedEpoch
│   ├── currentEpoch
│   └── snapshot.0
└── datalog
└── version-2

注意:留意 currentEpoch 中的数值

5. 选举演练

5.1 模拟 Leader 掉线

➜  zoo1 docker stop zoo3
zoo3

查看此时的选举结果(操作同查看角色操作步骤)。可以看到 Zookeeper 集群重新选举结果: zoo2 被选为 leader

5.2 zoo3 节点重新上线

➜  zoo1 docker start zoo3
zoo3

查看 zoo3 角色,发现 zoo3 自动作为 follower 加入集群。

注意:查看 currentEpoch 中的数值,存储值为 2,代表经过了 2 次选举。第一次为刚启动时触发选举,第二次为 leader 宕机后重新选举

6. 常用操作

6.1 查看文件目录

笔者本地有安装的 Zookeeper 环境,所以这里用本地的 zkCli 进行测试。

zkCli -server localhost:2182,localhost:2183,localhost:2184
Connecting to localhost:2182,localhost:2183,localhost:2184
Welcome to ZooKeeper!
JLine support is enabled WATCHER:: WatchedEvent state:SyncConnected type:None path:null
[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 0] ls /
[zookeeper]

6.2 创建顺序节点

顺序节点保证 znode 路径将是唯一的。

[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 1] create -s /zk-test 123
Created /zk-test0000000000
[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 2] ls /
[zk-test0000000000, zookeeper]

6.3 创建临时节点

当会话过期或客户端断开连接时,临时节点将被自动删除

[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 3] create -e /zk-temp 123
Created /zk-temp
[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 4] ls /
[zk-test0000000000, zookeeper, zk-temp]

临时节点在客户端会话结束后就会自动删除,下面使用 quit 命令行退出客户端,再次连接后即可验证。

[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 5] quit
Quitting...
➜ docker zkCli -server localhost:2182,localhost:2183,localhost:2184
Connecting to localhost:2182,localhost:2183,localhost:2184
Welcome to ZooKeeper!
JLine support is enabled WATCHER:: WatchedEvent state:SyncConnected type:None path:null
[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 0] ls /
[zk-test0000000000, zookeeper]

6.4 创建永久节点

[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 1] create /zk-permanent 123
Created /zk-permanent
[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 2] ls /
[zk-permanent, zk-test0000000000, zookeeper]

6.5 读取节点

[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 3] get /

cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x400000008
cversion = 3
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 3
[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 4] ls2 /
[zk-permanent, zk-test0000000000, zookeeper]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x400000008
cversion = 3
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 3

使用 ls2 命令来查看某个目录包含的所有文件,与 ls 不同的是它查看到 time、version 等信息

6.6 更新节点

[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 5] set /zk-permanent 456
cZxid = 0x400000008
ctime = Tue Mar 03 21:35:20 CST 2020
mZxid = 0x400000009
mtime = Tue Mar 03 21:40:11 CST 2020
pZxid = 0x400000008
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0

6.7 检查状态

[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 6] stat /zk-permanent
cZxid = 0x400000008
ctime = Tue Mar 03 21:35:20 CST 2020
mZxid = 0x400000009
mtime = Tue Mar 03 21:40:11 CST 2020
pZxid = 0x400000008
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0

6.8 删除节点

[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 7] rmr /zk-permanent
[zk: localhost:2182,localhost:2183,localhost:2184(CONNECTED) 8] ls /
[zk-test0000000000, zookeeper]

7. AD

公众号【当我遇上你】, 每天带给你不一样的内容

Docker实战之Zookeeper集群的更多相关文章

  1. Docker实战之Consul集群

    前言 最近参加了几场 Java 面试,发现大多数的微服务实践还是 Eureka 偏多,鉴于笔者的单位选型 Consul,这里对 Consul 做简单总结. 该篇是 Docker 实战系列的第三篇.传送 ...

  2. Docker中搭建zookeeper集群

    1.获取官方镜像 从dockerhub获取官方的zookeeper镜像: docker pull zookeeper 2.了解镜像内容 拉取完镜像后,通过 docker inspect zookeep ...

  3. Docker实战之Redis-Cluster集群

    概述 接上一篇Docker实战之MySQL主从复制, 这里是Docker实战系列的第二篇,主要进行Redis-Cluster集群环境的快速搭建.Redis作为基于键值对的NoSQL数据库,具有高性能. ...

  4. Docker实战之Kafka集群

    1. 概述 Apache Kafka 是一个快速.可扩展的.高吞吐.可容错的分布式发布订阅消息系统.其具有高吞吐量.内置分区.支持数据副本和容错的特性,适合在大规模消息处理场景中使用. 笔者之前在物联 ...

  5. Zookeeper集群搭建(多节点,单机伪集群,Docker集群)

    Zookeeper介绍 原理简介 ZooKeeper是一个分布式的.开源的分布式应用程序协调服务.它公开了一组简单的原语,分布式应用程序可以在此基础上实现更高级别的同步.配置维护.组和命名服务.它的设 ...

  6. docker环境下solrcloud+zookeeper集群部署教程

    前言:两个月前的16年11月份完成的配置,使用的solr6.1和zookeeper3.4,刚刚写成blog,目前版本可能有小版本的变化. 本例完成结果为:在docker环境下部署solrcloud集群 ...

  7. 原创:centos7.1下 ZooKeeper 集群安装配置+Python实战范例

    centos7.1下 ZooKeeper 集群安装配置+Python实战范例 下载:http://apache.fayea.com/zookeeper/zookeeper-3.4.9/zookeepe ...

  8. Docker应用系列(二)| 构建Zookeeper集群

    本示例基于Centos 7,在阿里云的三台机器上部署zookeeper集群,假设目前使用的账号为release,拥有sudo权限. 由于Docker官方镜像下载较慢,可以开启阿里云的Docker镜像下 ...

  9. Zookeeper实战之嵌入式执行Zookeeper集群模式

    非常多使用Zookeeper的情景是须要我们嵌入Zookeeper作为自己的分布式应用系统的一部分来提供分布式服务.此时我们须要通过程序的方式来启动Zookeeper.此时能够通过Zookeeper ...

随机推荐

  1. Opencv笔记(十七)——轮廓性质

    边界矩形的宽高比 x,y,w,h = cv2.boundingRect(cnt) aspect_ratio = float(w)/h Extent Extent就是轮廓面积与边界矩形面积的比. are ...

  2. Flink(二) —— 部署与任务提交

    一.下载&启动 官网上下载安装包,执行下列命令即启动完成. ./bin/start-cluster.sh 效果图 Flink部署模式 Standalone模式 Yarn模式 k8s部署 二.配 ...

  3. Python 语言基础

    Python 语言基础 Python 开发环境 计算机组成 编程语言(计算机语言)是人们为了控制计算机,而设计的一种符号和文字的组合,从而实现向计算机发出指令. 形式是符号和文字的组合 目的是为了控制 ...

  4. redis数据库写入数据时提示redis.exceptions.ResponseError错误

    今天运行Django项目在redis数据库写入数据时提示如下错误: ERROR log 228 Internal Server Error: /image_code/cf9ccd75-d274-45c ...

  5. 十八、linux系统分区

    一.磁盘存储结构图:这里注意下,分区标有64字节,则每个分区有16字节,MBR引导分区有446字节,共有510字节,一个扇区有512字节,还有俩个字节是分区结束标识.比如隐藏文件等标识,都是这2个字节 ...

  6. 树分治(挑战p360)

    poj1741 题:http://poj.org/problem?id=1741 #include<iostream> #include<algorithm> #include ...

  7. jquery JavaScript如何监听button事件

    下面的html页面中有两个按钮 <div class="layui-tab-item layui-show"> <form class="layui-f ...

  8. F5 BIG-IPLTM串联组网连接模式

  9. css3动画贝塞尔曲线cubic-bezier,css3动画的五种情况

    当大家开始做css3动画的时候,了解贝塞尔曲线就成了不可或缺的.“贝赛尔曲线”是由法国数学家Pierre Bézier所发明,由此为计算机矢量图形学奠定了基础.它的主要意义在于无论是直线或曲线都能在数 ...

  10. kafka + spark Streaming + Tranquility Server发送数据到druid

    花了很长时间尝试druid官网上说的Tranquility嵌入代码进行实时发送数据到druid,结果失败了,各种各样的原因造成了失败,现在还没有找到原因,在IDEA中可以跑起,放到线上就死活不行,有成 ...