Zookeeper集群的搭建与部署

zookeeper安装
wget linux mac都可以用 brew只有mac可以用

1.使用wget 去官网(https://archive.apache.org/dist/zookeeper较慢)或其他(http://mirror.bit.edu.cn/apache/zookeeper)找tar包 并wget下来解压
2.brew install zookeeper,之后会自动下载并安装到/usr/local/Cellar目录下,同时也会做个快捷键放到/usr/local/opt这里

配置文件 (data port配置)
修改配置文件位置 zookeeper/conf/zoo.cfg

启动脚本目录 zookeeper/bin (该目录包括服务端启动脚本和客户端启动脚本 )
./zkServer status/start/stop
./zkCli -server 127.0.0.1:2180

./zkServer.sh start-foreground (启动并打印日志, 对启动失败的情况很好用)

启动之后查看该服务的配置信息,客户端连接个数等 安装nc(yum install nc.x86_64)
echo cons | nc localhost 2181
envi: 列出所有的环境参数
cons: 列出所有的客户端会话链接
crst: 重置所有的客户端连接
dump: 打印集群的所有会话信息,包括ID,以及临时节点等信息。用在Leader节点上才有效果。
ruok: "谐音为Are you ok"。检查当前服务器是否正在运行。
stat: 获取ZooKeeper服务器运行时的状态信息,包括版本,运行时角色,集群节点个数等信息。
srst: 重置服务器统计信息
srvr: 和stat输出信息一样,只不过少了客户端连接信息。
wchs: 输出当前服务器上管理的Watcher概要信息
wchc: 输出当前服务器上管理的Watcher的详细信息,以session为单位进行归组
wchp: 和wchc非常相似,但是以节点路径进行归组
mntr: 输出比stat更为详细的服务器统计信息

分布式锁的实现
准备步骤
首先开启三个客户端
任何一个客户端创建一个节点 /zklock (create /zklock 1)
开始加锁
客户端A: create -s -e /zklock/nodelock 1
客户端B: create -s -e /zklock/nodelock 1
客户端C: create -s -e /zklock/nodelock 1
假设客户端B 网络延迟最低,则抢先创建了节点.则这个节点就是nodelock0000000000
假设客户端A 其次,创建了节点nodelock0000000001
假设客户端C 其次,创建了节点nodelock0000000002
这样在一个非临时节点 /zklock 下面有个三个临时有序节点,分别由三个客户端创建
/zklock/nodelock0000000000 /zklock/nodelock0000000001 /zklock/nodelock0000000002
如果任何一个客户端掉线,那么他创建的临时节点就会自动删除.
我们获取 /zklock 节点下的左右子节点,然后根据节点名字 排一下序, 找出最小节点
nodelock0000000000 < nodelock0000000001 < nodelock0000000002
那么我们认为客户端B就已经获得了锁
然后nodelock0000000001(客户端A) 需要监听nodelock0000000000(客户端B)
nodelock0000000002(客户端C) 需要监听nodelock0000000001(客户端A)
客户端A 监听 客户端B
客户端B 执行 get /zklock/nodelock0000000000 watch
客户端C 监听 客户端A
客户端C 执行 get /zklock/nodelock0000000001 watch
然后 客户端B执行完任务 执行命令 delete /zklock/nodelock0000000000
则 客户端A马上会被通知到, 则客户端A开始执行任务
然后 客户端A执行完任务 执行命令 delete /zklock/nodelock0000000001
则 客户端C马上会被通知到, 则客户端C开始执行任务
这就是分布式锁

./zkServer status 输出standalone这个代表是单机模式(单个服务)
下面来开始搭建集群(集群内的服务一定要保证是奇数!!!)

在三台机器上的zk 配置文件里添加如下同样的

dataDir=/usr/local/zookeeper-3.4.14/data
server.0=172.26.206.88:2888:3888
server.1=172.26.206.87:2888:3888
server.2=172.26.206.86:2888:3888

并在172.26.206.88的/usr/local/zookeeper-3.4.14/data 里面新建myid 文件并写入0
并在172.26.206.87的/usr/local/zookeeper-3.4.14/data 里面新建myid 文件并写入1
并在172.26.206.86的/usr/local/zookeeper-3.4.14/data 里面新建myid 文件并写入2

分别重启三个zk, 则可以./zkServer.sh status 观察 一台leader 两台follower

客户端zkCli -server 47.92.139.196:2181 连接哪个节点都可以,但是如果这个节点挂了的话,该客户端同样会挂(但是在代码里的话 我们肯定是配置多个节点,所以挂了一个客户端会去尝试其他节点)

https://www.lagou.com/lgeduarticle/9166.html

zookeeper 在有大于半数的节点回应后就算作commit,那么如果剩下的节点写入失败,那连接在该节点会不会一直保持连接,而读到的是旧的数据呢?

结论: Zookeeper并不保证读取的是最新数据即不保证强一致性,所以剩下节点得到的数据可能为旧,这是zk cap设计中舍弃的,强一致性的数据可以从leader那里拿

  1. zookeeper 使用ZAB协议,是介于AP和CP之间的,ZAB协议中多次用到“过半”设计策略 ,该策略是zk在A(可用性)与C(一致性)间做的取舍,也是zk具有高容错特性的本质。相较分布式事务中的2PC(二阶段提交协议)的“全量通过”,ZAB协议可用性更高(牺牲了部分一致性),能在集群半数以下服务宕机时正常对外提供服务。

说法1: 事实上当Leader发送给Follower数据失败时,会关闭Leader和Follower的sync连接,此时触发Follower异常,会关闭当前所有的客户端连接并将服务器状态更改为LOOKING,重新选举

说法2: 还有两个时机会触发写数据重试:1、leader和follower进行ping交互的时候 2、下一次commit请求执行的时候 因为TCP的超时重传机制保证,下一个包发送成功的时候,之前的包一定能发送成功

说法3: 节点会记录它见过的最大的 zxid (比如第一次写数据或者第二次提交数据时候带过来的zxid),读取的时候,如果节点发现这条 zxid 比 自己的最大zxid大,则拒绝,client 会自动重连到其他server(还在同一个 session) —— 最终会落到有新数据的 server 上,因为半数已经同意;

你可能感兴趣的:(Zookeeper集群的搭建与部署)