一个虚拟机内搭建Zookeeper集群很简单
复制配置文件
cd {zookeeperurl}/conf/
> cp zoo.cfg zoo1.cfg
> cp zoo.cfg zoo2.cfg
> cp zoo.cfg zoo3.cfg
{zookeeperurl}表示zookeeper的安装路径
创建数据以及日志文件目录
> mkdir -p /zookeeper/data_1
> mkdir -p /zookeeper/data_2
> mkdir -p /zookeeper/data_3
> mkdir -p /zookeeper/logs_1
> mkdir -p /zookeeper/logs_2
> mkdir -p /zookeeper/logs_3
创建myid文件{一定要正确 仔细点}
> echo "1" > /zookeeper/data_1/myid
> echo "2" > /zookeeper/data_2/myid
> echo "3" > /zookeeper/data_3/myid
说明下zoo.cfg配置文件搭建集群需要修改地方
zoo1.cfg
dataDir=/tmp/zookeeper/data_1
dataLogDir=/tmp/zookeeper/logs_1
# the port at which the clients will connect
clientPort=2181
#jetty要占用的端口 默认8080
admin.serverPort=18080
server.1=192.168.198.129:2887:3887
server.2=192.168.198.129:2888:3888
server.3=192.168.198.129:2889:3889
zoo2.cfg
dataDir=/tmp/zookeeper/data_2
dataLogDir=/tmp/zookeeper/logs_2
# the port at which the clients will connect
clientPort=2182
#jetty要占用的端口 默认8080
admin.serverPort=18081
server.1=192.168.198.129:2887:3887
server.2=192.168.198.129:2888:3888
server.3=192.168.198.129:2889:3889
zoo3.cfg
dataDir=/tmp/zookeeper/data_3
dataLogDir=/tmp/zookeeper/logs_3
# the port at which the clients will connect
clientPort=2183
#jetty要占用的端口 默认8080
admin.serverPort=18082
server.1=192.168.198.129:2887:3887
server.2=192.168.198.129:2888:3888
server.3=192.168.198.129:2889:3889
启动 zkServer.sh start zoo3.cfg
查看状态 zkServer.sh status zoo3.cfg
接下来就是zookeeper的 ZAB协议
1 leader: 领导者选举机制
zk1 zk2 zk3
myid=1 myid=2 myid=3
zxid=100 zxid=100 zxid=100
myid 可以配置
zxid 就是读磁盘 (更新删除新增操作)的id
选举 就是选择最强(数据越新 能力越强) 首先对比的就是 zxid 如果一致就对比 zxid
选好了leader 后就不会变
除非 leader挂了 下面的follower重新选举 然后新加入的zk 从leader 变 follower
选举就2种
1 启动集群的时候 选举
2 leader挂了 重新选举
2 二阶段提交
a 预提交
b 收到ack
c 提交
zkclied ---->zkServer
每接受到一个请求 ---生成日志 ---zxid +1 持久化
实际上
从leader的角色 客户端写请求过来
1 zxid+1
2 持久化日志
3 预提交
日志同步给follower
4 等待ack(阻塞ing) (过半机制)
[看其他follower日志是否持久化ok ] ---------------------------------------> follower
5 收到了一半的ack 就会提交 1接受到日志
a 本地提交 更新内存数据 2 持久化日志 然后ack给 leader(没ack可能磁盘满了等问题)
b 发送commit命令(向follower) 3 接受到 leader发过来的 commit命令 ,立马更新内存里面的内容
6 响应客户端
如果是follower或者observe 角色 客户端写请求
就把请求转发给 leader 就这一步 交给 leader处理
3 过半机制
就是上述的 二阶段里面的 等待ack 其中就只要有一半的ack回调 leader就会提交
4 数据同步机制 (补偿 保证数据一致性)
就是 leader 接收到很多请求 zxid++ 日志持久化
更新内存 就是操作dataTree对象 当每定时过一段时间 就把dateTree持久化 --》快照(定时) --》 快照给follower(提高同步数据效率)
follower 先同步最近的快照 然后在同步快照后的日志
以上的 1234 就是ZAB协议
其他事项
当 网络问题 如果zk follower 和 zkleader断掉了
那么 zk follower会自杀 然后去选举 等待 其他zk连
角色
其实无论是 leader 领导者
还是 follower 跟随者
还是observe 观察者
都是确认好角色 然后去数据同步
脑裂
zookeeper解决了脑裂问题 因为过半机制解决的
观察者observe的意义
实际上当zk节点多了 读性能提升 (负载均衡)但写性能降低 同步数据的节点多了
leader就一台 为了解决这个性能问题 用observe 就在最后提交的时候 给observe 发送info请求
observe 接收到info请求后
1 持久化磁盘文件
2 更新内存数据
这样比加follower节点好一些