Zookeeper
2021-08-24 22:57:18 0 举报
AI智能生成
zk总结
作者其他创作
大纲/内容
来个总结吧
集群模式部署
分支主题
一般奇数节点,因为你5台机器可以挂2台,6台机器也是挂2台,不能超过一半的机器挂掉,所以5台和6台效果一致,那奇数节点可以减少机器开销,小集群部署,读多写少
分支主题
主从架构:Leader、Follower、Observer(一般刚开始没必要用)
分支主题
内存数据模型:znode,多种节点类型
分支主题
客户端跟zk进行长连接,TCP,心跳,维持session
分支主题
zxid,高32位,低32位
分支主题
ZAB协议,2PC,过半ack + 磁盘日志写,commit + 写内存数据结构
分支主题
支持Watcher机制,监听回调通知
分支主题
顺序一致性:消息按顺序同步,但是最终才会一致,不是强一致
分支主题
高性能,2PC中的过半写机制,纯内存的数据结构,znode
分支主题
高可用,follower宕机没影响,leader宕机有数据不一致问题,新选举的leader会自动处理,正常运行,但是在恢复模式期间,可能有一小段时间是没法写入zk的
分支主题
高并发,单机leader写,Observer可以线性扩展读QPS
应用场景
分布式锁
运用于Java分布式业务系统中
Curator
元数据管理
Kafka、Canal,本身都是分布式架构,分布式集群在运行,本身他需要一个地方集中式的存储和管理分布式集群的核心元数据,所以他们都选择把核心元数据放在zookeeper中的
分布式协调
监听并作出响应,比如有一个数据,一个broker注册了一个数据,其他broker监听这个数据
Master选举
HA架构
总结:
分布式协调系统,封装了分布式架构中所有核心和主流的需求和功能,分布式锁、分布式集群的集中式元数据存储、Master选举、分布式协调和通知
特点
集群部署:3~5台机器组成一个集群
每台机器都在内存保存了zk的全部数据,机器之间互相通信同步数据,客户端连接任何一台机器都可以
树形结构的数据模型:znode,树形结构,数据模型简单,纯内存保存
顺序一致性:集群中只有一台机器可以写,所有机器都可以读,所有写请求都会分配一个zk集群全局的唯一递增编号
zxid,保证各种客户端发起的写请求都是有顺序的
原子性:要么全部机器都成功,要么全部机器都别成功
数据一致性:任何一台zk机器收到了写请求之后都会同步给其他机器,保证数据的强一致,你连接到任何一台zk机器看到的数据都是一致的
高可用:哪怕集群中挂掉不超过一半的机器,都能保证可用,数据不会丢失
3台机器可以挂1台,5台机器可以挂2台
高性能:每台zk机器都在内存维护数据,所以zk集群绝对是高并发高性能的
如果你让zk部署在高配置物理机上,一个3台机器的zk集群抗下每秒几万请求没有问题
高并发:高性能决定的,只要基于纯内存数据结构来处理,并发能力是很高的
只有一台机器进行写,但是高配置的物理机,比如16核32G,写入几万QPS
读,所有机器都可以读,3台机器的话,起码可以支撑十几万QPS
实时性:一旦数据发生变更,其他人要实时感知到
watcher监听机制
集群架构
角色划分
Leader
可读写
Follower
只读,写请求转发到Leader
可参与选举
Observer
只读,写请求转发到Leader
不参与选举
也不参与ZAB返回ack那个环节,只接受数据,可能存在数据不一致的问题
客户端通信
通过TCP建立长连接,维护session
定时发送心跳
客户端宕机时,在sessionTimeout时间内重新发送心跳会继续维持长连接
内存数据模型
znode
持久节点
客户端宕机依旧存在
临时节点
客户端宕机就没了
顺序节点
创建节点时的时候递增全局自增的序号
Watcher监听机制
客户端对zookeeper znode节点进行监听,然后改变的时候通知客户端
监听数据变化,更新数据,反向通知
ZAB协议
Zookeeper Atomic Broadcast
即zookeeper原子广播协议
角色划分
划分集群角色,主从架构,分为Leader和Follower ,只有leader接受写入请求
2PC(两阶段提交)
Leader接收到写请求,先写入磁盘文件,并向Follower发送事务proposal的广播
Follower接到proposal写入磁盘文件,然后向Leader返回ACK
等待Leader发送commit写入znode
过半写
超过半数的Follower返回ACK消息,Leader将数据写入znode,并发送commit消息通知Follower写入
commit之后这个数据就能被读到了
顺序性保证
在发起一个事务proposal之前,会生成一个自增的全局zxid,通过这个保证顺序性
Leader会为没给Follower创建一个队列,里面放要发送的事务proposal,保证了同步的顺序性
启动与崩溃恢复
启动
恢复模式
选举出一个Leader (过半Follower认可即成为Leader)
跟Follower进行数据同步
完成后退出恢复模式,进入消息广播模式
对外提供服务
消息写入
消息广播机制 + Leader采用2PC模式的过半写机制,给Follower进行同步
崩溃恢复
恢复模式
Leader/Follower宕机
只要集群宕机的机器不超过一半
就可以重新进行选举出Leader,进行数据同步
强一致性or最终一致性?
强一致性:
只要写入一条消息,立马无论从那个zk节点都可以查到数据
写入操作卡主,知道所有的follower返回ack,leader执行commit之后,从所有节点都能读到数据
很明显,根据ZAB协议,zk不是强一致性
最终一致性:
写入一条消息,方法返回,告诉你写入成功了
短暂时间内从其他节点可能查不到数据,不过等一会同步完成,肯定能查到数据
研究过ZAB协议就能发现,follower半数以上返回ack,然后leader发送commit以后就能读到数据了
那么就有一种可能,有的follower接收到commit了,可以读到,有的没接到commit,读不到
不过最后还是能读到的
zk官方自己的定义是:顺序一致性
它比最终一致性好些,因为leader可以保证所有的follower事务proposal都是按照顺序执行的,能保证顺序性
但是全部follower的数据一致确实是最终才能实现一致的
出去说要说是顺序一致性
如果要求强一致性,可以手动调用zk的sync()操作
ZAB协议下的一种可能存在的数据一致性问题
Leader自己commit了,还没给其他Follower发送commit消息就挂了
Follower重新选举出Leader
挑选已经收到zxid最大的那个Follower作为新的Leader
zxid大说明最近跟leader进行了数据同步
新的Leader发现自己有一条proposal没有commit,其他follower也有这个proposal,并且数量过半
会重新发送commit给其他Follower进行数据同步
确保数据不会丢失
Leader接收到写入请求,写入磁盘日志文件了,还没来得及个其他Follower发送事务proposal就挂了
它重新启动后跟Leader进行数据同步时,发现自己有一条没有commit的事务proposal
zxid是64位的,高32位存放leader的版本号epoch,低32位主键自增
新的leader的epoch 自增
Leader没有,说明是它自己宕机前的脏数据
直接丢弃掉,从新Leader同步最新的数据
所谓commit就是把这条数据加到内存的znode树上去,然后就对外可见了,也会通知一些监听这个znode的人
读写性能分析
写请求
无论zookeeper集群多少台机器,只有leader能进行写入操作,单机写入最多每秒上万的QPS,这是没办法拓展的
所以zk适用于写少的场景
读请求
一般2台、4台follower,可以支撑每秒几万的读QPS,还可以通过follower、observer进行拓展
但是一般不建议加太多的follower,写入的时候会向follower发送proposal,并且等待过半的follower返回ack
follower太多会影响性能,可以多加observer,因为它不参与选举以及proposal的ack返回
图解
0 条评论
下一页