什么是zookeeper
- 高性能分布式协调服务,主要解决分布式一致性。
- 适用于读多写少场景,实现了CAP的C和P(即一致性和分区容忍性),但是需要注意的是,这里是弱一致性。
- 服务端使用java语言开发,提供JAVA和C的API。
弱一致性解读
zk机器需要有n+1台机器,最大允许n台机器同时失效,当发起写入请求时,当有n+1台机器返回成功,即为成功;
如果此时另外n台失效节点无法连通,则这些节点的客户端读取到的数据并非最新数据,只有当这些节点加入集群后,会从leader同步最新数据,此时整个cluster才能提供统一的逻辑视图。
zookeeper特点
- 顺序一致性:按照客户端请求分配ZXID(全局唯一事务ID),并顺序更新数据。
- 原子性:要么成功要么失败,不存在中间状态。
- 可靠性:数据更新成功将一直保持
- 及时性:客户端会在一个确定的时间内得到更新数据
zookeeper集群
- 集群要求:2n+1台服务,最大允许n个服务失效(为啥?查看下面脑裂部分)。
- zookeeper集群只能有一个leader,负责写数据,剩下的都是follower。
- follower负责提供读请求,客户端无论连接哪一台,发送写请求后都会传递给leader,然后由leader更新数据并同步至follower。
- 当一台节点连接到集群(集群状态变更),或者leader接收到写请求,都会产生全局唯一事务ID:ZXID.
- 客户端可以设置多个zookeeper地址,当发送请求到zookeeper上后得到确认会返回消息,此时会维护一个connection(TCP长连接)。
- 客户端通过TCP长连可以向服务端发送心跳,也由此接收服务端watcher通知。
zookeeper节点状态
zk节点存在以下状态:
- LEADING,领导者状态。
- LOOKING,竞选状态。
- FOLLOWING,随从状态,同步leader状态,参与投票。
- OBSERVING,观察状态,同步leader状态,不参与投票。
集群leader选举
- 什么时候发生选举:
- 客户端启动(初始化)
- follower无法和leader保持通讯(leader挂了、或网络导致的假死)
- 选举影响:集群选举的过程中将会暂停对外服务。
选举过程
- 每个服务端,发送本机myid和zxid给集群所有机器(包括自己)进行投票,表示方式:(myid,zxid)。
- 每个服务端,接收到请求
- 判断是否looking状态、epoch参数(详看脑裂部分)。
- 判断zxid是否小于自己记录的zxid,小则丢弃,大则替换,等同则比较myid,并求出最大。
- 广播投票结果,接受被广播发送的ACK
- 判断ACK数量是否超过过半服务器
- 确认Leader,变更服务器状态
zookeeper API
- connect - 连接到ZooKeeper集群
- create- 创建znode
- exists- 检查znode是否存在及其信息
- getData - 从特定的znode获取数据
- setData - 在特定的znode中设置数据
- getChildren - 获取特定znode中的所有子节点
- delete - 删除特定的znode及其所有子项
- close - 关闭连接
zookeeper 节点类型
client可以通过api创建节点,创建的节点有如下类型:
- 持久节点:节点创建后,就一直存在
- 持久顺序节点:基于持久节点,会分配顺序数字,例如创建节点test,则zk会自动给test_后面补充数字
- 临时节点:临时节点的生命周期和客户端会话绑定,客户端关闭/丢失连接,节点删除
- 临时顺序节点: 同上
zookeeper 脑裂
- 什么是脑裂:一个cluster产生两个leader。
- 产生原因:假设两台zk服务器相互通信ok,则会选举一个leader;如果通信不ok,则cluster会出现两个leader(自我选举)。
- zk解决方式:设置法定人数:Quorums,3节点Quorums是2,也就是上面说的2n+1个节点最多容忍N个节点失效;每次选举必须达到法定人数才可以。
假设旧leader假死,其他节点选举新leader,则旧leader发起写入数据操作会被拒绝;
如何会拒绝?集群选举leader后会产生递增的epoch,可理解为leader的编号;写入数据时会对这个参数进行判断。
观察者Observer
根据上面zk状态发现,有一个OBSERVING状态存在,拥有这个状态的即是观察者。
- 功能:不参与投票从而提高性能;因为投票会进行多轮对比,所以当观察者上、下线后,不会让集群产生投票动作。
- 场景:多数据中心、网络不稳定的情况下,观察者上下线不会影响集群。
zookeeper 缺点
- 选举过程服务不可用。
- 当集群存活node少于选举leader的法定人数Quorums时整个集群不可用。(降级方案:客户端加点缓存,但是会破坏CP。
- 大规模服务发现、大规模健康监测等方面有天然的短板(网络闪断、tcp心跳不能反馈更多信息)。
- 容量不可以横向扩展(Znode的大小限制为1M)。
zookeeper 优点
- 分布式锁(db、redis可替代)。
- 分布式选主。
- 分布式一致性。
选型场景
- 大数据场景适用(mapreduce、spard等分布式一致性,分布式协调)。
- 交易场景不可用(不能保证可用性,服务发现场景有缺陷)。