写流程 (Leader 可以读写,follower可以读),Zookeeper 实现CP,但是为了效率放弃全部同步再返回(只选择一般完成同步就可以进行下一步)
1. 客户端连接的是Leader节点进行写
Leader 写入事务文件,然后给自己一个ACK 信号,然后同步去Follower,Follower写入事务文件保存,给Leader 返回ACK
Leader收到半数以上的ACK,就会发送commit给follower,然后自己将数据写入内存中,follower收到commit同样将数据写入内存
2. 客户端连接的是Follower节点进行写
Follower会将请求转发给Leader, Leader再进行 #1的情况操作
3. Observer 观察者
只对外提供读功能,Leader 写的话,直接发送写入请求,Observer只会直接写内存不会进行两阶段提交
对于读数据再Follower上是会存在不一致性的,因为Follower不是全部同步了再返回,所以如果一定需要拿到最新的数据,就需要先用sync method,让接收请求的Follower先去和Leader主动同步,然后再get最新的数据
持久化过程
Zookeeper虽然是内存数据库,但为了保证高可靠性,其同时提供了持久化功能,通过快照和事务日志将数据保存在磁盘中.
dataDir :快照文件储存位置
dataLogDir: 事务日志储存位置
- 写入的时候先写一条记录入事务日志,当次数达到一定数量后(默认10W次),就会将内存数据库序列化一次,使其持久化保存到磁盘形成快照文件。持久化后,会创建新的事务日志文件。
- 为事务日志预先开辟磁盘空间。默认是64M。(10w次数据量如果不够64M也会写快照,生成新的日志文件,避免频繁的生成新的日志文件,可以分析每次写入的大小,然后缩写或是扩大这个磁盘默认空间值)
- 为了防止所有的ZooKeeper服务器节点同时生成快照(一般情况下,所有实例的配置文件是完全相同的),当某节点的先写事务数量在(snapCount/2+1,snapCount)范围内时(挑选一个随机值),这个值就是该节点拍快照的时机。
- 定期自动清理,默认保留最小三个快照和事务日志,默认不开启自动清理功能
ZK服务器启动过程
- 解析参数 zoo.cfg文件 和myId
- 过去快照删除 至少保留三个快照文件
- 通信初始化,初始化NIO服务socket绑定断开2181
- 启动ZK
服务器动态上下线过程
- 服务器注册服务 (临时节点)
- 客户端发现服务 (并监听watch)
- 服务器下线(临时节点,是会话节点,当一段时间大概十几秒到30秒左右,zookeeper和 服务器没消息连接,就会断开会话,节点也就自动删除)
- ZooKeeper 发送下线通知给客户端
- 客户端刷新服务列表继续监听