Zookeeper 如何保证分布式系统数据一致性
写在前面
分布式架构出现后,越来越多的分布式系统会面临数据一致性的问题。目前,ZooKeeper 是在解决分布式数据一致性上最成熟稳定且被大规模应用的工业级解决方案。
ZooKeeper 保证 分布式系统数据一致性的核心算法就是 ZAB 协议(ZooKeeper Atomic Broadcast,原子消息广播协议)。
ZAB 协议
ZooKeeper 能够保证数据一致性主要依赖于 ZAB 协议的 消息广播,崩溃恢复和数据同步 三个过程。

消息广播
一个事务请求(Write)进来之后,Leader 节点会将写请求包装成 Proposal 事务,并添加一个全局唯一的 64 位递增事务 ID,也就是 Zxid(消息的先后顺序就是通过比较 Zxid);
Leader 节点向集群中其他节点广播 Proposal 事务,Leader 节点和 Follower 节点是解耦的,通信都会经过一个 FIFO 的消息队列,Leader 会为每一个 Follower 节点分配一个单独的 FIFO 队列,然后把 Proposal 发送到队列中;
Follower 节点收到对应的 Proposal 之后会把它持久到磁盘上,当完全写入之后,发一个 ACK 给 Leader;
当 Leader 节点收到超过半数 Follower 节点的 ACK 之后(Quorum 机制),会提交本地机器上的事务,同时开始广播 commit, Follower 节点收到 commit 之后,完成各自的事务提交。

ZAB 协议针对事务请求的处理过程类似于一个两阶段提交过程,第一阶段是广播事务操作,第二阶段是广播提交操作,而在这种两阶段提交模型下,是无法处理因 Leader 节点宕机带来的数据不一致问题的,比如下面两种情况:
当 Leader(Server1) 发起一个事务 Proposal1 后就宕机了,导致 Follower 都没有 Proposal1。
当 Leader 发起 Proposal2 后收到了半数以上的 Follower 的 ACK,但是还没来得及向 Follower 节点发送 Commit 消息就宕机了。
为了解决 Leader 宕机以及宕机后导致的数据不一致问题,ZAB 协议引入了崩溃恢复模式。
崩溃恢复模式必须解决以下问题:
Server1 恢复过来再次加入到集群中的时候,必须确保丢弃 Proposal1,即保证被丢弃的消息不能再次出现。
选举出的新 Leader 必须拥有集群中所有机器 Zxid 最大的 Proposal,即保证已经被处理的消息不能丢。
崩溃恢复
Zookeeper 集群进入崩溃恢复阶段的时机:
集群服务刚启动时进入崩溃恢复阶段选取 Leader 节点。
Leader 节点突然宕机或者由于网络原因导致 Leader 节点与过半的 Follower 失去了联系,集群也会进入崩溃恢复模式。
选举 Leader 节点
首先使用 Leader 选举算法选出一个新的 Leader 节点。选举过程如下:
各个节点变为 Looking 状态
Leader 宕机后,余下的 Follower 节点都会将自己的状态变更为 Looking(注意 Observer 不参与选举),然后开始进入 Leader 选举过程。
各个 Server 节点都会发出一个投票,参与选举
在第一次投票中,所有的 Server 都会投自己,然后各自将投票发送给集群中所有机器。
集群接收来自各个服务器的投票,开始处理投票和选举
处理投票的过程就是对比 Zxid 的过程,假定 Server3 的 Zxid 最大,Server1 判断 Server3 可以成为 Leader,那么 Server1 就投票给 Server3,判断的依据如下:首先选举 epoch 最大的,如果 epoch 相等,则选 zxid 最大的,若 epoch 和 zxid 都相等,则选择 server id 最大的。
在选举过程中,如果有节点获得超过半数的投票数,则会成为 Leader 节点,反之则重新投票选举。选举成功,各节点的状态为 Leading 和 Following。
Zab 中的节点有三种状态,folloing(当前节点是 Follower 节点),leading(当前节点是 Leader 节点),looking/election(当前节点处于选举状态);伴随着的 Zab 协议消息广播和崩溃恢复两阶段之间的转换,节点状态也随之转换。
数据同步
崩溃恢复完成选举以后,接下来的工作就是数据同步,在选举过程中,通过投票已经确认 Leader 节点是最大 Zxid 的节点,同步阶段就是利用 Leader 前一阶段获得的最新 Proposal 历史同步集群中所有的副本。
总结
ZAB 协议是 CAP 理论中 CP 的典型实现,其崩溃恢复阶段涉及到的 Leader 节点选举过程和数据同步选举完成后的数据同步过程都是对外不提供服务的,就是为了保证数据的强一致性牺牲了可用性。到这里,关于 ZooKeeper 使用 ZAB 协议保证分布式系统下数据一致性已经分析完了,有关于 Paxos 算法以及 ZAB 协议与 Paxos 算法之间的联系这里不做详细分析,有兴趣的小伙伴可以查阅《从 Paxos 到 ZooKeeper 分布式一致性原理与实战》这本书,里面有详细的介绍。
参考
《从 Paxos 到 ZooKeeper 分布式一致性原理与实战》
《分布式技术原理与实战 45 讲》
最后
如果大家想要实时关注我更新的文章以及我分享的干货的话,可以关注我的公众号 我们都是小白鼠。

Zookeeper 如何保证分布式系统数据一致性的更多相关文章
- ZooKeeper 如何保证数据一致性?
在分布式场景中,ZooKeeper 的应用非常广泛,比如数据发布和订阅.命名服务.配置中心.注册中心.分布式锁等. 在分布式场景中,ZooKeeper 的应用非常广泛,比如数据发布和订阅.命名服务.配 ...
- Zookeeper并不保证读取的是最新数据
Zookeeper并不保证读取的是最新数据 原文地址:http://www.crazyant.net/2120.html 如果是对zk进行读取操作,读取到的数据可能是过期的旧数据,不是最新的数据. 已 ...
- ZooKeeper如何保证单一视图
由于ZooKeeper的数据模型简单且全部在内存中,ZooKeeper的速度非常快.它提供了一系列保证: • 顺序一致性 • 原子性 • 单一视图 • 可靠性 • 实时性 下面将结合源码(3.4.10 ...
- 品味Zookeeper之选举及数据一致性_3
品味Zookeeper之选举及数据一致性 本文思维导图 前言 为了高可用和数据安全起见,zk集群一般都是由几个节点构成(由n/2+1,投票机制决定,肯定是奇数个节点).多节点证明它们之间肯定会有数据的 ...
- 【分布式】Zookeeper在大型分布式系统中的应用
一.前言 上一篇博文讲解了Zookeeper的典型应用场景,在大数据时代,各种分布式系统层出不穷,其中,有很多系统都直接或间接使用了Zookeeper,用来解决诸如配置管理.分布式通知/协调.集群管理 ...
- FAQ系列 | 如何保证主从复制数据一致性(转)
导读 MySQL主从复制环境中,如何才能保证主从数据的一致性呢? 关于主从复制 现在常用的MySQL高可用方案,十有八九是基于 MySQL的主从复制(replication)来设计的,包括常规的一主一 ...
- zookeeper系列(五)zookeeper在大型分布式系统中的应用
作者:leesf 掌控之中,才会成功:掌控之外,注定失败. 出处:http://www.cnblogs.com/leesf456/p/6063694.html 尊重原创感谢博主公开这么好的博文, ...
- zookeeper有几种部署模式? zookeeper 怎么保证主从节点的状态同步?
一.zookeeper的三种部署模式 Zookeeper 有三种部署模式分别是单机模式.伪集群模式.集群模式.这三种模式在不同的场景下使用: 单机部署:一般用来检验 Zookeeper 基础功能,熟悉 ...
- Zookeeper内部实现分布式数据一致性(底层系统模型)(一)
Zookeeper的几个概念:(接下来将从这几个概念书写Zookeeper的内部工作流程) 数据模型 节点特性 版本 Watcher ACL <1> 数据模型: Zookeeper的视图很 ...
随机推荐
- 1、flink介绍,反压原理
一.flink介绍 Apache Flink是一个分布式大数据处理引擎,可对有界数据流和无界数据流进行有状态计算. 可部署在各种集群环境,对各种大小的数据规模进行快速计算. 1.1.有界数据流和无界 ...
- 递归复制&查看文件夹下的指定后缀的文件
<?php header("content-type:text/html;charset=utf8"); set_time_limit(0); $dir = "d: ...
- 2.Python是什么?使用Python的好处是什么?
Python是什么?使用Python的好处是什么? 答: Python is a programming language with objects, modules, threads, except ...
- Vue项目开发流程(自用)
一.配置开发环境 1.1 安装Node.js npm集成在Node中,检查是否安装完成:node -v 1.2 安装cnpm(淘宝镜像) npm install -g cnpm,检查安装是否完成:cn ...
- Red 编程语言 2019 开发计划:全速前进!
开发四年只会写业务代码,分布式高并发都不会还做程序员? >>> Red 编程语言开发团队昨日发布了一篇 "Full steam ahead" 的文章,对其 2 ...
- flutter中使用redux之多界面互动
在上一篇文章,我们介绍了如何在flutter中使用redux.在上一篇文章的例子中,我们使用了单界面集成redux,但是在实际项目中,我们通常涉及多个模块,每个模块涉及多个界面,那么如何使用redux ...
- AWS访问慢的原因分析及解决方案
中国区的用户在访问海外AWS服务器的时候会遇到访问很慢的情况,那如何快速访问海外AWS服务器,今天和大家一起聊一下这个话题. 首先,为什么中国的用户访问海外AWS会变慢? 我总结来下大概有以下几方面的 ...
- java socket实现服务端,客户端简单网络通信。Chat
之前写的实现简单网络通信的代码,有一些严重bug.后面详细写. 根据上次的代码,主要增加了用户注册,登录页面,以及实现了实时显示当前在登录状态的人数.并解决一些上次未发现的bug.(主要功能代码参见之 ...
- python(简介)
python发展史: 自从20世纪90年代初Python语言诞生至今,它已被逐渐广泛应用于系统管理任务的处理和Web编程. Python的创始人为荷兰人吉多·范罗苏姆 [3] (Guido van ...
- AWVS 安全渗透扫描
1.打开软件,点击 New Scan 2.在 website url 中输入被扫描的网址,点击 next 3.在 scanning profile 中选择测试的漏洞类型,默认选择 default(默认 ...