🍅程序员小王的博客:程序员小王的博客
🍅 欢迎点赞 👍 收藏 ⭐留言 📝
🍅 如有编辑错误联系作者,如果有比较好的文章欢迎分享给我,我会取其精华去其糟粕
一、搭建zookper集群前的准备
1、准备三台linux并实现三台机器机器免密码登录
-
为什么要免密登录
-
Hadoop 节点众多, 所以一般在主节点启动从节点, 这个时候就需要程序自动在主节点登录到从节点中, 如果不能免密就每次都要输入密码, 非常麻烦
-
-
免密 SSH 登录的原理
-
需要先在 B节点 配置 A节点 的公钥
-
A节点 请求 B节点 要求登录
-
B节点 使用 A节点 的公钥, 加密一段随机文本
-
A节点 使用私钥解密, 并发回给 B节点
-
B节点 验证文本是否正确
-
(1)三台机器生成公钥与私钥
-
在三台机器执行以下命令,生成公钥与私钥
ssh-keygen -t rsa
执行该命令之后,按下三个回车即可
(2)拷贝公钥到同一台机器
三台机器将拷贝公钥到第一台机器
-
三台机器执行命令:
ssh-copy-id node1
-
如果报错及解决办法
/usr/bin/ssh-copy-id: ERROR: ssh: Could not resolve hostname node1:
Name or service not known
-
解决办法:在集群上的所有机器上执行vi /etc/hosts
192.168.43.129 node1
192.168.43.130 node2
192.168.43.131 node3
(3)复制第一台机器的认证到其他机器
将第一台机器的公钥拷贝到其他机器上
在第一台机器上面指向以下命令
scp /root/.ssh/authorized_keys node2:/root/.ssh
scp /root/.ssh/authorized_keys node3:/root/.ssh
2、三台机器时钟同步
-
为什么需要时间同步
-
因为很多分布式系统是有状态的, 比如说存储一个数据, A节点 记录的时间是 1, B节点 记录的时间是 2, 就会出问题
-
## 安装
yum install -y ntp
## 启动定时任务
crontab -e
随后在输入界面键入
*/1 * * * * /usr/sbin/ntpdate ntp4.aliyun.com;
二、Zookeeper简单介绍
1、什么是Zookeeper
-
Zookeeper 是一个开源的分布式协调服务框架 ,主要用来解决分布式集群中 应用系统的一致性问题
-
Zookeeper 是 Google Chubby 思想的一个开源实现
-
Zookeeper 本质上是一个分布式文件系统, 适合存放小文件, 通过文件系统来实现分布式协调
2、什么是分布式文件系统?
参考博客:https://blog.csdn.net/qq\_37862148/article/details/113999206
(1)一般文件系统
在我们日常生活工作中,自己使用的电脑上都会安装操作系统,比如Windows。我们经常进行的操作如新建文件夹、新建文件、删除文件等等,都是文件系统在帮助我们工作,Windows文
件系统有FATFS、VFATFS、NTFS等。除了Windows外,Linux也有ext、vfs等等文件系统,像这种一台计算机,单个存储节点、一个操作系统,一个具体的文件系统的场景称之为一般文件系统。
(2)分布式文件系统
分布式文件系统中的数据存储在多台机器上,这些专门用来存储数据的机器称之为存储节点,由多个节点构成分布式集群,节点上的小的分布式文件系统组合成总的分布式文件系统,由主服务器对总的文件系统进行管理。用户任意访问某一台主机,都能获取到自己想要的目标文件。
(3)一般文件系统和分布式文件系统的对比
(4)Zookeeper的分布式文件系统
-
在上图左侧, Zookeeper 中存储的其实是一个又一个 Znode, Znode 是 Zookeeper 中的节点
-
Znode 是有路径的, 例如
/servers/host1
,/``servers``/host2
, 这个路径也可以理解为是 Znode 的 Name -
Znode 也可以携带数据, 例如说某个 Znode 的路径是
/data/host1
, 其值是一个字符串"192.168.0.1"
-
-
正因为 Znode 的特性, 所以 Zookeeper 可以对外提供出一个类似于文件系统的视图(前端), 可以通过操作文件系统的方式操作 Zookeeper
-
使用路径获取 Znode
-
获取 Znode 携带的数据
-
修改 Znode 携带的数据
-
删除 Znode
-
添加 Znode
-
等等...
-
3、Zookeeper是分布式的
-
首先呢, Zookeeper 是分为服务端和客户端的, 客户端有 Java 的客户端, 有 Shell 命令行的客户端等, 客户端通过一个类似于文件系统的 API 来访问 Zookeeper 集群
-
但是事实上, 客户端最终是直接访问 Zookeeper 集群, 集群中有两大类角色, 一类是 Leader, 一类是 Follower, 其实就是主从, Leader 负责读和写, Follower 只能读, 遇到会产生修改的请求会转发给 Leader 处理, 这是因为 Zookeeper 本质上就是为了在分布式环境中对消息的一致性的支持, 而 Zookeeper 所基于的 ZAB 协议是 Paxos 协议的一个变种, ZAB 协议中是有一个全局的事务生成者, 就是 Leader, 修改设计到在分布式环境下对事务达成一致, 必须由 Leader 发起
-
例子
比如说一个常见的分布式主从系统, 如果有 ZK 在的话, 主节点不需要和每个从节点保持连接, 只需要监听从节点创建的 Znode, 便可以知道谁在线
4、Zookeeper 能做什么?
-
发布订阅
-
命名服务
-
分布式锁
-
分布式协调
三、Zookeeper集群部署
1、集群部署服务器规划
服务器IP | 主机名 | myid的值 |
---|---|---|
192.168.43.129 | node1 | 1 |
192.168.43.130 | node2 | 2 |
192.168.43.131 | node3 | 3 |
2、下载Zookeeper的压缩包
-
我们在这个网址下载我们使用的zk版本为3.4.9,下载完成之后,上传到我们的linux的/usr/apps路径下准备进行安装
3、解压
#1.到达/usr/apps
cd /usr/apps
#2.解压
tar -zxvf zookeeper-3.4.9.tar.gz
#将zookeeper改名
mv zookeeper-3.4.9 zookeeper
-
zookeeper结构
4、修改配置文件
-
第一台机器修改及配置
cd /usr/apps/zookeeper/conf/
# 复制一份并改名
cp zoo_sample.cfg zoo.cfg
#创建数据存储文件
mkdir -p /usr/apps/zookeeper/zkdatas/
-
修改zoo.cfg
# example sakes.
dataDir=/usr/apps/zookeeper/zkdatas
# 保留多少个快照
autopurge.snapRetainCount=3
# 日志多少小时清理一次
autopurge.purgeInterval=1
# 集群中服务器地址
server.1=node1:2888:3888
server.2=node2:2888:3888
server.3=node3:2888:3888
5、添加myid配置
-
第一台机器(node1)上/usr/apps/zookeeper/zkdatas/这个路径下面创建文件,文件名为myid,文件内容为:
echo 1 > /usr/apps/zookeeper/zkdatas/myid
6、安装包分发
(1)安装包分发到其他机器
-
第一台机器上面执行以下两个命令,将zookeeper文件转发到另外两个节点
scp -r /usr/apps/zookeeper/ node2:/usr/apps/zookeeper/
scp -r /usr/apps/zookeeper/ node3:/usr/apps/zookeeper/
-
第二台机器上修改myid的值为2·
echo 2> /usr/apps/zookeeper/zkdatas/myid
-
第三台机器上修改myid的值为3
echo 3> /usr/apps/zookeeper/zkdatas/myid
7、三台机器启动zookeeper服务
-
三台机器启动zookeeper服务(这个命令三台机器都要执行)
/usr/apps/zookeeper/bin/zkServer.sh start
-
查看启动状态
/usr/apps/zookeeper/bin/zkServer.sh status
四、Zookeeper的Shell客户端操作
1、Zookeeper服务命令
ZooKeeper服务命令: | |
---|---|
启动ZK服务: | bin/zkServer.sh start |
查看ZK服务状态: | bin/zkServer.sh status |
停止ZK服务: | bin/zkServer.sh stop |
重启ZK服务: | bin/zkServer.sh restart |
2、Zookeeper常用命令
命令 | 说明 | 参数 |
---|---|---|
create [-s] [-e] path data acl | 创建Znode | -s 指定是顺序节点 -e 指定是临时节点 |
ls path [watch] | 列出Path下所有子Znode | |
get path [watch] | 获取Path对应的Znode的数据和属性 | |
ls2 path [watch] | 查看Path下所有子Znode以及子Znode的属性 | |
set path data [version] | 更新节点 | version 数据版本 |
delete path [version] | 删除节点, 如果要删除的节点有子Znode则无法删除 | version 数据版本 |
rmr path | 删除节点, 如果有子Znode则递归删除 | |
setquota -n|-b val path | 修改Znode配额 | -n 设置子节点最大个数 -b 设置节点数据最大长度 |
history | 列出历史记录 |
-
连接Zookeeper服务
zkCli.sh -server node1:2181
显示welcome to zookeeper极为成功
-
创建普通节点
create /app1 hello
-
创建顺序节点
create -s /app2 world
-
创建临时节点
create -s /tempnode0 world
-
创建顺序的临时节点
create -s -e /tempnode1 aaa
-
获取节点数据
get /app1
-
修改节点数据
set /app1 helloWhj
-
删除节点
#删除的节点不能有子节点
delete /app1
# 递归删除
rmr /app1
3、Znode的特点和类型,属性,通知类型,会话等概念
(1)Znode 的特点
-
文件系统的核心是
Znode
-
如果想要选取一个
Znode
, 需要使用路径的形式, 例如/test1/test11
-
Znode 本身并不是文件, 也不是文件夹, Znode 因为具有一个类似于 Name 的路径, 所以可以从逻辑上实现一个树状文件系统
-
ZK 保证 Znode 访问的原子性, 不会出现部分 ZK 节点更新成功, 部分 ZK 节点更新失败的问题
-
Znode
中数据是有大小限制的, 最大只能为1M
-
Znode
是由三个部分构成-
stat
: 状态, Znode的权限信息, 版本等 -
data
: 数据, 每个Znode都是可以携带数据的, 无论是否有子节点 -
children
: 子节点列表
-
(2)Znode 的类型
-
每个
Znode
有两大特性, 可以构成四种不同类型的Znode
-
持久性(-e)
-
持久
客户端断开时, 不会删除持有的Znode -
临时
客户端断开时, 删除所有持有的Znode, 临时Znode不允许有子Znode
-
-
顺序性(-s)
-
有序
创建的Znode有先后顺序, 顺序就是在后面追加一个序列号, 序列号是由父节点管理的自增 -
无序
创建的Znode没有先后顺序
-
-
(3)Znode的属性
-
dataVersion
数据版本, 每次当Znode
中的数据发生变化的时候,dataVersion
都会自增一下 -
cversion
节点版本, 每次当Znode
的节点发生变化的时候,cversion
都会自增 -
aclVersion
ACL(Access Control List)
的版本号, 当Znode
的权限信息发生变化的时候aclVersion会自增 -
zxid
事务ID -
ctime
创建时间 -
mtime
最近一次更新的时间 -
ephemeralOwner
如果Znode
为临时节点,ephemeralOwner
表示与该节点关联的SessionId
(4)通知机制
-
通知类似于数据库中的触发器, 对某个Znode设置
Watcher
, 当Znode发生变化的时候,WatchManager
会调用对应的Watcher
-
当Znode发生删除, 修改, 创建, 子节点修改的时候, 对应的
Watcher
会得到通知 -
Watcher
的特点-
一次性触发 一个
Watcher
只会被触发一次, 如果需要继续监听, 则需要再次添加Watcher
-
事件封装:
Watcher
得到的事件是被封装过的, 包括三个内容keeperState, eventType, path
-
KeeperState | EventType | 触发条件 | 说明 |
---|---|---|---|
None | 连接成功 | ||
SyncConnected | NodeCreated | Znode被创建 | 此时处于连接状态 |
SyncConnected | NodeDeleted | Znode被删除 | 此时处于连接状态 |
SyncConnected | NodeDataChanged | Znode数据被改变 | 此时处于连接状态 |
SyncConnected | NodeChildChanged | Znode的子Znode数据被改变 | 此时处于连接状态 |
Disconnected | None | 客户端和服务端断开连接 | 此时客户端和服务器处于断开连接状态 |
Expired | None | 会话超时 | 会收到一个SessionExpiredException |
AuthFailed | None | 权限验证失败 | 会收到一个AuthFailedException |
(5)会话
-
在ZK中所有的客户端和服务器的交互都是在某一个
Session
中的, 客户端和服务器创建一个连接的时候同时也会创建一个Session
-
Session
会在不同的状态之间进行切换:CONNECTING
,CONNECTED
,RECONNECTING
,RECONNECTED
,CLOSED
-
ZK中的会话两端也需要进行心跳检测, 服务端会检测如果超过超时时间没收到客户端的心跳, 则会关闭连接, 释放资源, 关闭会话