zookeeper作用和应用场景

1.zookeeper存储什么数据

1
2
3
4
5
6
存储的主要是一些配置信息,可以用于服务注册,服务发现等常见。
zookeeper的存储结构和Linux文件系统很相似,有多级目录。

和Linux的根文件系统和类似,分为目录和文件,zookeeper也类似,只不过没有文件和目录的区别,而是都称之为zookeeper node,简称znode。

znode不适合存储大量数据,一个znode默认最大存储2MB的数据。

2.zookeeper的应用场景

和kafka,hbase,HDFS,YARN,Dubbo,Solr等服务,提供了配置信息,注册中心等辅助功能。

ElasticStack架构升级–MQ

filebeat数据采集交给Kafka消息队列,logstash去拉取Kafka里的数据处理交给ES集群

ElasticStack_MQ

消息队列产品

1
2
3
4
Rocket MQ
Active MQ
Kafka
Rebbit MQ

zookeeper单点部署

这里仅为测试,可跳过步骤 4,5 直接部署集群,避免单点故障

官方版本选择:https://zookeeper.apache.org/releases.html

zookeeper集群的节点数量选择

当每秒请求量低于6w/s,读取数据占据70%,大多数是读的场景,官方测试数据建议选择3台集群。

1.下载zookeeper

1
[root@elk01:3 ~]# wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz

**2.解压软件包 **

1
2
3
4
[root@elk01:3 ~]# tar xf apache-zookeeper-3.8.4-bin.tar.gz -C /app/

#做软链接
[root@elk01:3 ~]# ln -s /app/apache-zookeeper-3.8.4-bin/ /app/zookeeper

3.配置环境变量

1
2
3
4
5
6
7
8
[root@elk01:3 ~]# cat /etc/profile.d/zk.sh
#!/bin/bash
export JAVA_HOME=/usr/share/elasticsearch/jdk
export ZK_HOME=/app/zookeeper
export PATH=$PATH:$ZK_HOME/bin:$JAVA_HOME/bin

#加载环境变量
[root@elk01:3 ~]# source /etc/profile.d/zk.sh

4.准备配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@elk01:3 ~]#  cp /app/zookeeper/conf/zoo{_sample,}.cfg 



#这里只是对配置文件的解读,未修改配置文件,复制出来默认即可
[root@elk01:3 ~]# cat /app/zookeeper/conf/zoo.cfg
# 指定最小的时间单位tick,默认单位是毫秒,此处最小单位是1 tick=2s
tickTime=2000
# 在集群初始化时的时间默认是10 tick,则表示20s
initLimit=10
# 数据同步时间5 tick,则表示10s
syncLimit=5
# 数据的存储目录
dataDir=/tmp/zookeeper
# 服务监听的端口
clientPort=2181

5.启动测试

注意,zookeeper启动会监听8080端口,启动失败注意查看端口冲突

1
2
3
#排错看日志
[root@elk01:3 ~]# ll /app/zookeeper/logs/
-rw-r--r-- 1 root root 16469 Oct 28 17:12 zookeeper-root-server-elk01.out
1
2
3
4
5
6
7
8
9
10
11
12
13
[root@elk01:3 ~]# zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /app/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

#查看状态
[root@elk01:3 ~]# zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /app/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: standalone

#standalone 单点状态

连接测试

1
2
3
4
5
6
7
8
9
10
11
[root@elk01:3 ~]# zkCli.sh      或者
[root@elk01:3 ~]# zkCli.sh -server 10.0.0.211

2024-10-28 17:06:31,811 [myid:localhost:2181] - INFO [main-SendThread(localhost:2181):o.a.z.ClientCnxn$SendThread@1453] - Session establishment complete on server localhost/127.0.0.1:2181, session id = 0x10001704a360000, negotiated timeout = 30000


WatchedEvent state:SyncConnected type:None path:null
[zk: localhost:2181(CONNECTED) 1] ls / #ls命令测试下
[zookeeper]

#出现它的session id 即为部署成功

zookeeper集群部署

如果zookeeper单点未做,步骤1,3可跳过

1. 停止服务

1
2
3
4
[root@elk01:3 ~]# zkServer.sh stop
ZooKeeper JMX enabled by default
Using config: /app/zookeeper/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED

2.修改配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[root@elk01 ~]# cat /app/zookeeper/conf/zoo.cfg 
# 定义最小单元的时间范围tick。
tickTime=2000
# 启动时最长等待tick数量。
initLimit=5
# 数据同步时最长等待的tick时间进行响应ACK
syncLimit=2
# 指定数据目录
dataDir=/app/data/zk
# 监听端口
clientPort=2181
# 开启四字命令允许所有的节点访问。
4lw.commands.whitelist=*
# server.ID=A:B:C[:D]
# ID:
# zk的唯一编号。
# A:
# zk的主机地址。
# B:
# leader的选举端口,是谁leader角色,就会监听该端口。
# C:
# 数据通信端口。
# D:
# 可选配置,指定角色。
server.91=10.0.0.211:2888:3888
server.92=10.0.0.212:2888:3888
server.93=10.0.0.213:2888:3888

## Metrics Providers
#
# https://prometheus.io Metrics Exporter
#metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
#metricsProvider.httpHost=0.0.0.0
#metricsProvider.httpPort=7000
#metricsProvider.exportJvmInfo=true

3.恢复原环境

1
2
[root@elk01:3 ~]# rm -fr /app/zookeeper/logs/*
[root@elk01:3 ~]# rm -fr tmp/zookeeper/*

4. 同步数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#拷贝环境变量文件
[root@elk01 ~]# scp /etc/profile.d/zk.sh 10.0.0.212:/etc/profile.d/
[root@elk01 ~]# scp /etc/profile.d/zk.sh 10.0.0.213:/etc/profile.d/

#拷贝zookeeper文件
[root@elk01 ~]# scp apache-zookeeper-3.8.4-bin.tar.gz 10.0.0.212:/root
[root@elk01 ~]# scp apache-zookeeper-3.8.4-bin.tar.gz 10.0.0.213:/root

#在对端解压zookeeper,做软链接(两个节点同步操做)
[root@elk02 ~]# tar xf apache-zookeeper-3.8.4-bin.tar.gz -C /app/

[root@elk02 ~]# ln -s /app/apache-zookeeper-3.8.4-bin/ /app/zookeeper


#拷贝zookeeper配置文件
[root@elk01 ~]# scp /app/zookeeper/conf/zoo.cfg 10.0.0.212:/app/zookeeper/conf/
[root@elk01 ~]# scp /app/zookeeper/conf/zoo.cfg 10.0.0.213:/app/zookeeper/conf/

5.生成myid文件

1
2
3
4
5
6
7
8
9
#创建数据目录(配置文件里声明的目录)  
`这里使用循环是因为三台机器我已两两做了免密,另外两个节点也可使用命令 mkdir /app/data/zk -p`
[root@elk01:3 ~]# for i in `seq 211 213` ;do ssh 10.0.0.$i mkdir /app/data/zk -p ;done

#生成myid文件
[root@elk01:3 ~]# for n in `seq 211 213` ;do ssh 10.0.0.$n "echo $n > /app/data/zk/myid";done

#myid文件作用
如果首次启动时候没有事务文件,则会比较myid文件里,谁最大谁就是master

6.启动服务

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@elk01 ~]# zkServer.sh start
[root@elk02 ~]# zkServer.sh start
[root@elk03 ~]# zkServer.sh start

#如果报错找不到命令,可能是配置的环境变量没有生效,执行如下
[root@elk03 ~]# source /etc/profile.d/zk.sh

#查看状态
[root@elk03:1 ~]# zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /app/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: leader

7.避坑指南

1
2
3
我所遇到的坑:
1.如果做集群,三个节点的配置文件一样,否则会有zookeeper起不来情况
2.删除如果你想清空环境重新启动zookeeper,记得日志和数据目录一起清除,否则服务起不来

验证zookeeper集群高可用

1.连接测试

1
2
3
4
[root@elk01 ~]# zkCli.sh -server 10.0.0.212:2181
[root@elk01 ~]# zkCli.sh -server 10.0.0.213:2181
···
ablishment complete on server elk03/10.0.0.213:2181, session id = 0xd40001f2a52b0000, negotiated timeout = 30000

2. 将leader节点挂掉,集群会自动选举出新的leader,集群正常对外提供服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#当前leader节点是elk03
[root@elk03 ~]# zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /app/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: leader

#停止elk03的zookeeper
[root@elk03 ~]# zkServer.sh stop
ZooKeeper JMX enabled by default
Using config: /app/zookeeper/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED

#经查看leader在elk02节点上
[root@elk02 ~]# zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /app/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: leader

#如果此时再次停止leader节点,那还会不会再选举?
`经测试,停掉elk02节点的zookeeper时候,elk01节点不会选举为leader,而是会停止zookeeper服务`
这也是我前面猜的坑,只有一台zookeeper时候是起不来服务的

#恢复 两个节点停止的服务重新启用即可

总结:

1.zookeeper分布式集群的特点,半数以上节点存活才能对外提供服务;
2.zookeeper一个集群中仅有一个leader和多个follower;
3.如果一个zookeeper集群想要容忍N台故障,该集群最少要有2N+1个节点

zookeeper基础命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#连接zookeeper
[root@elk02:1 ~]# zkCli.sh
WatchedEvent state:SyncConnected type:None path:null

#1. 查看znode列表
[zk: localhost:2181(CONNECTED) 1] ls /
[zookeeper]

#2. 创建znode
[zk: localhost:2181(CONNECTED) 2] create /luay
Created /luay
[zk: localhost:2181(CONNECTED) 3] ls /
[luay, zookeeper]

#3. 创建znode时指定数据
[zk: localhost:2181(CONNECTED) 4] create /test abc
Created /test

#4. 查看znode的数据
[zk: localhost:2181(CONNECTED) 5] get /test
abc

#5. 修改znode的值
[zk: localhost:2181(CONNECTED) 7] get /luay
null
[zk: localhost:2181(CONNECTED) 8] set /luay new
[zk: localhost:2181(CONNECTED) 9] get /luay
new

#6. 创建子znode
[zk: localhost:2181(CONNECTED) 10] ls /luay
[]
[zk: localhost:2181(CONNECTED) 11] create /luay/happy xixi
Created /luay/happy
[zk: localhost:2181(CONNECTED) 12] get /luay/happy
xixi

#7. 删除znode,前提是该znode没有子节点
[zk: localhost:2181(CONNECTED) 13] ls /test
[]
[zk: localhost:2181(CONNECTED) 14] delete /test
[zk: localhost:2181(CONNECTED) 15] ls /test
Node does not exist: /test
[zk: localhost:2181(CONNECTED) 16] ls /
[luay, zookeeper]

#8. 删除非空znode,该znode有子节点,会报错
[zk: localhost:2181(CONNECTED) 17] delete /luay
Node not empty: /luay
[zk: localhost:2181(CONNECTED) 18]

你会发现我连接zookeeper时候是还有本地连接方式,当我使用远程方式连接elk01时候也会有数据,因为zookeeper做了集群

1
2
3
4
[root@elk03 ~]# zkCli.sh -server 10.0.0.211:2181

[zk: localhost:2181(CONNECTED) 3] ls /
[luay, zookeeper]

zookeeper的watch机制(了解)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
开两个终端,其中一个终端使用watch,另一个终端创建子znode

#1. 监控一个znode下子节点的变化
[zk: 10.0.0.211:2181(CONNECTED) 0] ls -w /luay
[]


#发起创建动作
[zk: 10.0.0.211:2181(CONNECTED) 11] create /luay/abc
Created /luay/abc

#监控终端则输出
[zk: 10.0.0.211:2181(CONNECTED) 1]
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/luay



# 2. 监控znode的数据是否发生变化 (另一个终端只需要修改znode值即可监控到)
[zk: 10.0.0.211:2181(CONNECTED) 0] get -w /luay
[]


# 注意:
- 1.watch事件是一次性的,只记录第一次创建或者修改动作;
- 2.watch事件一旦触发,就会通知监控者程序,由该程序去负责相应的逻辑处理;