Zookeeper是什么
- Zookeeper是一个高性能分布式应用协调服务
- Naming Service【命名服务】
- 配置管理【分布式配置管理,或者集中式配置管理】
- Leader Election 【领导选举】
- 服务发现
- 同步
- Group Service
- Barrier【栅栏】
- 分布式队列【使用ZooKeeper不太好】
- 两阶段提交
ZooKeeper工作方式
- Zookeeper集群包含1个Leader,多个Follower。
- 所有的Follower都可提供读服务
- 所有的写操作都会被forward到Leader【也就是说,只有Leader才能写操作】
- Client与Server通过NIO通信【同步非阻塞式IO】。
- 全局串行化所有的写操作【写操作的执行顺序,根据用户发送的顺序去执行,因为这里使用了TCP的FIFO,英文First In First Out 的缩写,是一种先进先出的数据缓存器,保证了接收与发送的顺序相同】
- 保证同一客户端的指令被FIFO执行
- 保证消息通知的FIFO
- 所有的写操作,通过Follower的方式通过Leader;所有的读操作,都可以通过Follower也可以通过Leader
Zab协议 – 广播模式
- Zab:【Zookeeper Atomic Broadcast】Zookeeper原子消息广播协议
- Leader将所有更新(称为proposal【每个跟新称为提议】),顺序发送给Follower
- 当Leader收到半数以上的Follower对此proposal的ACK时,即向所有Follower发送commit消息,并在本地commit该消息。注意:发送commit的条件是超过半数以上的Follower都发送了ACK
- Follower收到Proposal后即将该Proposal写入磁盘,写入成功即返回ACK给Leader。
- 每个Proposal都有一个唯一的单调递增的proposal ID,即zxid
- 读操作:直接读request、reponse
- 写操作:首先request到Follower,Follower在request到Leader,然后Leader将这个请求广播给所有的Follower,之后Follower会给Leader发送一个ACK【半数以上即可】,然后Leader会向所有的Follower发送一个commit,Follower都会被写操作写入,然后返回
Zab协议 – 恢复模式
- 进入恢复模式 当Leader宕机或者丢失大多数Follower后,即进入恢复模式
- 结束恢复模式 新领导被选举出来,且大多数Follower完成了与Leader的状态同步后,恢复模式即结束,从
而进入广播模式- 恢复模式的意义
- 发现集群中被commit的proposal的最大zxid
- 建立新的epoch【纪元】,从而保证之前的Leader不能再commit新的Proposal
- 集群中大部分节点都commit过前一个Leader commit过的消息,而新的Leader是被大部分节点所支持的,所以被之前Leader commit过的Proposal不会丢失,至少被一个节点所保存
- 新Leader会与所有Follower通信,从而保证大部分节点都拥有最新的
- 恢复阶段的保证
- 若一条消息在一台机器上被deliver也就是commit,那么该消息必须将在每台机器上deliver也就是commit,即使那台机器故障了
- 一个被skip【跳过】的消息,必须仍然需要被skip
-
- 例如:
- Server1是Leader,它发送p1 p2给Server2、Server3,然后commit1,又发送p3,之后commit2,然后Leader挂掉了,可能Server2和Server3没有收到,但是对于Server1而言,他已经commit1和commit2,所以即使Server2和Server3没有收到commit1和commit2的这条消息,新Leader上任之后,也要保证p1和p2能被commit
- 在Server1中,p3没有commit,也就是没有被广播出去,这个时候Server1挂了,当重新选出Leader这条消息直接被跳过。当Server1恢复过来,并且成为了新的Leader,Server1的p3应该要广播出去,这是Server2和Server3中已经被commit过的消息的zxid比p3的大,那我就拒绝p3的proposal,所以Server2和Server3都不会给Server1关于p3的ACK
Zookeeper一致性保证
- 顺序一致性 从一个客户端发出的更新操作会按发送顺序被顺序执行
- 原子性 更新操作要么成功要么失败,无中间状态
- 单一系统镜像 一个客户端只会看到同一个view,无论它连到哪台服务器
- 可靠性
- 一旦一个更新被应用,该更新将被持久化,直到有客户端更新该结果
- 如果一个客户端得到更新成功的状态码,则该更新一定已经生效
- 任何一个被客户端通过读或者更新“看到”的结果,将不会被回滚,即使是从失败中恢复
- 实时性 保证客户端可在一定时间(通常是几十秒)内看到最新的视图【可能另外的客户端使用的是没有给Leader发送ACK的Follower】
ZooKeeper使用注意事项
- 只保证同一客户端的单一系统镜像,并不保证多个不同客户端在同一时刻一定看到同一系统镜像,如果要实现这种效果,需要在读取数据之前调用sync操作
- Zookeeper读性能好于写性能,因为任何Server均可提供读服务,而只有Leader可提供写服务【适用于读多写少的场景】
- 为了保证Zookeeper本身的Leader Election顺利进行,通常将Server设置为奇数
- 若需容忍f个Server的失败,必须保证有2f+1个以上的Server
Kafka如何使用Zookeeper
- 配置管理【集群】
- Leader Election【领导选举】
- 服务发现【dubbo】