上一篇文章中介绍了分布式中数据的分布方式,有普通哈希、按数据范围,按数据量、一致性哈希、哈希桶、以及组合方式。它解决了“数据”分布的问题,是一个典型的分而治之思想的体现。本文讲解下「 副本协议 」,副本与副本之间的”沟通交流“是怎么规定的。
副本协议 是怎么控制副本数据的 读写行为 、使得副本满足一定的可用性和一致性要求 。它还具有一定的 对抗异常 状态的容错能力,一个优秀的架构师会尽可能对异常情况进行处理。回忆下之前的文章提到 异常 有:网络分化、机器宕机、消息丢失、消息乱序、存储数据丢失、存储数据读出的数据错误、磁盘故障、网络不稳定以及拥塞。
从CAP定理得出,想要在分布架构中设计一个满足强一致性,且出现网络异常时都可用的副本协议是不可能。实际的副本协议总是在 可用性 、 一致性与性能 等要素之间妥协折中。
中心化副本协议
中心化副本协议的基本思路是由一个 中心节点 协调副本数据的更新、维护副本之间的一致性。现实生活中很多机构部门都有中心节点的影子存在,可以参考对比下。中心化副本控制协议的优点是 协议相对简单 ,所有副本的控制权都在中心节点。 并发控制 也在中心节点完成,从而使得一个分布式并发控制问题,简化为一个单机并发控制问题。这里的并发控制是指多个节点同时操作副本数据,解决”写写“、”读写“等并发冲突造成的 脏数据 。单机系统常用加锁进行并发控制。分布式并发控制,如果没有一个中心节点统一进行锁管理(转为单机进行管理),实现一个完全分布式的锁系统,会使得协议非常复杂 。
中心化副本控制协议的缺点是系统的可用性 依赖于中心化节点 ,当中心节点异常或中心节点 通信中断 时,系统将失去某些服务(通常失去更新服务),所以中心化副本控制协议的缺点是存在一定的 停服务 时间。
0、primary-backup协议
主备协议也叫主从协议,从是主的backup,这里的backup一般多为 热备 。通常是需要承担一部分读数据操作。它是一种非常常用的中心化副本控制协议。应用场景:MySQL一主多从、 MongoDB 一主多从、 Redis 一主两从、HDFS主从架构。通常仅有一个副本作为primary副本,除primary以为的副本都为backup副本。primary副本所在的节点称为 中心节点 , primary-backup 类型的协议一般要解决 四大类问题 :数据更新流程、数据读取方式、primary副本的确定和切换、数据同步。
1、数据更新基本流程
-
数据更新都由primary节点 协调 完成
-
外部节点将更新操作发给primary节点
-
primary节点进行并发控制即确定并发更新操作的先后顺序
-
primary节点将更新操作发送给backup节点
-
primary根据backup节点的完成情况决定更新是否成功并将结果返回外部节点
其中第4步primary节点将更新操作发给backup节点,发送的也是更新数据。工程实践中,如果primary 直接同时 发送给其他N个副本数据,则每个backup的更新吞吐受限于primary总的 出口网络带宽 。每个backup最大为primary网络出口带宽的1/N。为了解决这个问题,像GFS使用 接力的方式 同步数据,primary将更新发送给第一个backup副本,第一个backup副本在发送给第二个backup,依次往下。由于 网络异常 的不可避免,第4步的更新操作可能在有些副本上 成功 ,有些副本上 失败 ,在有些副本上 超时 。对 数据一致性 要求不同的副本控制协议对异常处理不同。提供最终一致性服务的系统中,backup节点可以与primary不一致,只要后续backup节点可以慢慢同步到与primary一致的状态即可满足 最终一致性 的要求。
2、数据读取方式
与数据更新流程类似,读取方式也与一致性高度相关。如果只需要最终一致性,则读取任意副本都可以满足需求。如果需要 会话一致性 ,则可以为副本设置版本号,每次更新后递增版本号,用户读取副本时验证版本号,从而保证与读取到的数据在会话范围内单调递增。使用primary-backup比较困难的是实现 强一致性 。
这里简单讨论下primary-backup实现强一致性的几种思路。
-
数据更新流程都是通过primary控制的,primary副本上数据一定是最新的, 始终只读primary 副本的数据。实践中,如果副本中数据分布不与机器绑定,而是按照数据段为单位维护副本,仅有primary副本提供读服务在很多场景下不会造成机器资源浪费。每台机器上有一些数据的primary副本,也有一些数据段的backup副本。
-
primary控制节点backup节点的可用性。当primary更新某个backup副本不成功时,primary将该backup副本标记为不可用。从而用户不再读取不可用的副本。不可用的副本可以继续尝试与primary同步数据,当与primary完成数据同步后,则该backup副本标记为可用。这样使得所有可用的副本都是可读的。标记的数据需要依赖一个中心元数据管理系统,记录副本可用、不可用状态。其实是通过降低系统的可用性来提高系统的一致性。 实际的副本协议总是在 可用性 、 一致性与性能 等要素之间妥协折中。
3、primaty副本的确定与切换
如何确定primary副本,尤其是在原primary副本所在的机器出现宕机等异常时,需要 某种机制切换 primary副本,使得某个backup副本成为新的副本。哪个副本是primary这一信息都属于元信息,由专门的元数据服务器维护。
切换副本难点在于两个方面,其一: 如何确定 节点的状态以发现原primary节点异常。下一篇文章我们介绍基于Lease机制确定节点状态的方法。 其二:切换primary后, 不能影响 副本的一致性。尤其是提供强一致性服务的系统,切换的新primary的副本必须和原primary的副本一致。如何在原primary发送宕机异常时,如何确定一个顶替的副本是与原primary副本上的数据一致。后面我们会介绍Quorum机制确定新primary的方法。
确定发现primary副本的异常是需要一定探测时间的,通常是10秒级别,意味着在确定期间内,没有primary,系统不能提供primary的更新服务、读服务。primary-backup类副本的最大缺点就是primary的切换带来一定的 停服务时间 。
4、数据同步
primary-backup 类型协议都会遇到backup副本与primary不一致的问题。不一致的backup副本需要与primary进行同步。
异常造成的不一致形式有三种:
-
网络分化等异常,backup上的数据落后于primary上的数据
回放primary上的操作日志(通常是redo日志),追赶上primary的更新进度
-
某些协议下,backup上的数据有可能是脏数据,需要被丢弃
a. 设计的分布式协议不产生脏数据,或者降低产生脏数据的概率到非常低
b. 丢弃有脏数据的副本,backup副本完全没有数据就可以直接拷贝primary,被拷贝的primary得继续服务,就要求primary副本支持快照功能,对某一刻的副本数据形成快照,拷贝快照后使用回放日志方式追赶快照后的更新操作
c. 基于undo日志的方式回退从而删除脏数据
-
backup是一个新增加的副本,完全没有数据,需要从其他副本上拷贝数据
去中心化副本协议
去中心化副本控制是另一种较为复杂的副本控制协议。去中心化副本控制协议是没有中心节点,协议中所有的节点都是 完全对等 的,节点之间通过 平等协商 达到一致。不会因为中心化节点异常带来停服务的问题。去中心化协议最大的缺点就是协议过程比较复杂。尤其当去中心化协议要实现强一致性的时候,协议流程变得复杂且不容易理解。由于流程的复杂,去中心化协议的效率或者性能一般比中心化协议低。一个不恰当的比方是,中心化副本控制协议类似专制制度,效率高但高度依赖于中心节点,一旦中心节点异常,系统就会出现不可用。去中心化副本控制协议类似民主制度,节点集体协议,效率低但个别节点的异常不会造成不可用。 副本协议总是在 可用性 、 一致性与性能 等要素之间妥协折中。
后面我们会讲 强一致性 去 中心化副本控制协议 paxos 。
工程投影
primary-backup
-
GFS(https://pdos.csail.mit.edu/6.824/papers/gfs.pdf)
-
PNUTS(https://timyang.net/architecture/yahoo-pnuts/)
-
Niobe(A practical replication protocol)
去中心化
-
Cassandra(http://cassandra.apache.org/)
-
Zookeeper(https://zookeeper.apache.org/)
推荐阅读
参考资料:《分布式系统原理介绍》作者:刘杰
扫 描下面的二维码关注我
喜欢就点个 "在看" 呗^_^
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Programming Python
Mark Lutz / O'Reilly Media / 2006-8-30 / USD 59.99
Already the industry standard for Python users, "Programming Python" from O'Reilly just got even better. This third edition has been updated to reflect current best practices and the abundance of chan......一起来看看 《Programming Python》 这本书的介绍吧!