定义&特点#
定义:分布式协调服务。中心化的服务,维护配置信息,命名服务,分布式同步器(锁、屏障、队列等),分组服务(组成员检测)。
抽象一下,即分布式协调服务。自己本身没有太大意义,用来协调分布式应用,类比一种进程间通信方式。
特点:纯内存结构,吞吐高,单机 1w 写qps,4w读 qps。(参考值,和配置相关)
总结: 在粗粒度分布式锁,分布式选主,主备高可用切换等不需要高 TPS 支持的场景下有不可替代的作用
数据模型#
树形结构,类文件系统。每个树节点znode,每个节点即是文件,也是文件夹,修改操作只能整体 set,不支持部分修改。
ephemeral znode. 临时节点,和 session 生命周期一致,可以用来检测机器在线状态。
sequence znode. 顺序节点,自动编号,可以用来实现统一命名。(redis incr 也可以做到)
watch 机制。znode 新增、删除、修改、子节点变更及时通知 client。
分布式实现方式#
zk 使用 replication,统一收口写,读水平扩展。适用于读多写少场景。
zk选主#
zab协议:ZooKeeper atomic broadcast,zk原子广播协议。论文
规则是 majority vote,超过半数认可的 server 成为 leader。FastLeaderElection。
大致过程,每台 server 初始广播 (serverEpoch, zxid, serverId),默认选择自己为 leader。判断逻辑先比较 epoch 最大,再比较 zxid 最大,最后比较 serverId 最大。
初始第一次很快是 serverId 最大的成为 leader(没有出现断网断电等异常情况时)
zk主从同步#
leader 连接所有的 follower,发送操作指令,2阶段提交,先 proposal 再 commit,超过半数 proposal 就进行 commit。commit 失败怎么办?2阶段提交都有的问题,概率小不做考虑。
同样会有主从延迟问题,一致性保证客户端看到的数据视图一致性,变更顺序一致性,并且在有限时间内保证 server 数据达到最新状态。
zk性能瓶颈#
单机处理写请求
majority vote 要求超过一半的 server 存活,server 数量 = 2*n + 2,n越大容错性越强,可以支持n台机器挂掉情况下服务依然可用。
同时,n越大,写扩散越大,写能力会变弱,查询能力会线性增长。单机 5w qps级别. (1w 写qps,4w读 qps)事务日志落盘
事务日志保证 client 写成功后数据不会丢失,write ahead,最好配置单独的磁盘。顺序写,所以依然可以有 1w 级别的写 qps。纯内存操作树结构
纯内存,容纳数据有限,线上服务器内存,比如32G。不能用于通常的数据存储,主要用于元数据。单节点现在最大 1m,太大会严重影响读写 qps,对于网络压力也很大。
zk在mysql应用#
mysql 主从库切换怎么做的?
直接用的 zk 的能力。数据同步通过 binlog 追加,写操作必须主库完成,一台从库 binlog 完成才返回。
从库应用binlog会有时延,所以会有主从延迟。日常10ms到100ms左右。后面的从库延迟更多。
zk是否适合服务注册发现#
服务注册发现规模巨大,服务规模 =F{服务 pub 数, 服务 sub 数},几千个服务,大服务集群机器上w台,比如淘宝交易系统就2w台机器,支撑200w qps。发布过程中会有很大的写入压力和监听扩散。
注册中心不需要很强的一致性,也不需要持久的事务日志。短暂的服务列表不一致只是造成部分的负载不均衡,影响不大。另外持久化事务日志保证宕机后快速恢复对于服务发现来说没啥用,只关注实时情况。