分布式系统设计(2)

副本

3.1 概念

副本(replica/copy)指在分布式系统中为数据或服务提供的冗余。对于数据副本指在不一样的节点上持久化同一份数据,当出现某一个节点的存储的数据丢失时,能够从副本上读到数据。数据副本是分布式系统解决数据丢失异常的惟一手段。另外一类副本是服务副本,指数个节点提供某种相同的服务,这种服务通常并不依赖于节点的本地存储,其所需数据通常来自其余节点。网络

3.2  基本副本协议

3.2.1  中心化副本控制协议

中心化副本控制协议的基本思路是由一个中心节点协调副本数据的更新、维护副本之间的一致性。图  2-7 给出了中心化副本协议的通用架构。中心化副本控制协议的优势是协议相对较为简单,全部的副本相关的控制交由中心节点完成。并发控制将由中心节点完成,从而使得一个分布式并发控制问题,简化为一个单机并发控制问题。所谓并发控制,即多个节点同时须要修改副本数据时,须要解决“写写”、“读写”等并发冲突。单机系统上经常使用加锁等方式进行并发控制。对于分布式并发控制,加锁也是一个经常使用的方法,但若是没有中心节点统一进行锁管理,就须要彻底分布式化的锁系统,会使得协议很是复杂。中心化副本控制协议的缺点是系统的可用性依赖于中心化节点,当中心节点异常或与中心节点通讯中断时,系统将失去某些服务(一般至少失去更新服务),因此中心化副本控制协议的缺点正是存在必定的停服务时间架构

 

3.2.2  primary-secondary 协议

在 primary-secondary 类型的协议中,副本被分为两大类,其中有且仅有一个副本做为 primary 副本,除 primary 之外的副本都做为 secondary 副本。维护 primary 副本的节点做为中心节点,中心节点负责维护数据的更新、并发控制、协调副本的一致性。并发

Primary-secondary 类型的协议通常要解决四大类问题:数据更新流程、数据读取方式、Primary副本的肯定和切换、数据同步(reconcile)。分布式

数据更新基本流程

Primary-secondary 协议的数据更新流程性能

1.  数据更新都由 primary 节点协调完成。spa

2.  外部节点将更新操做发给 primary 节点设计

3.  primary 节点进行并发控制即肯定并发更新操做的前后顺序日志

4.  primary 节点将更新操做发送给 secondary 节点blog

5.  primary 根据 secondary 节点的完成状况决定更新是否成功并将结果返回外部节点ci

其中第 步 primary 节点将更新操做发送到 secondary 节点时,每每发送的也是更新的数据。在工程实践中,若是由 primary 直接同时发送给其余 个副本发送数据,则每一个secondary 的更新吞吐受限于 primary 总的出口网络带宽,最大为 primary 网络出口带宽的 1/N为了解决这个问题,有些系统(例如,GFS),使用接力的方式同步数据,即 primary 将更新发送给第一个 secondary 副本,第一个 secondary 副本发送给第二 secondary 副本,依次类推。因为异常,第 4步可能在有些副本上成功,有些副本上失败,在有些副本上超时。不一样的副本控制协议对于第 步异常的处理都不同。

数据读取方式

数据读取方式是 primary-secondary 类协议须要解决的第二个问题。与数据更新流程相似,读取方式也与一致性高度相关。若是只须要最终一致性,则读取任何副本均可以知足需求。若是须要会话一致性,则能够为副本设置版本号,每次更新后递增版本号,用户读取副本时验证版本号,从而保证用户读到的数据在会话范围内单调递增。使用 primary-secondary 比较困难的是实现强一致性

这里简单讨论 primary-secondary 实现强一致性的几种思路。

第1、因为数据的更新流程都是由 primary 控制的,primary 副本上的数据必定是最新的,因此若是始终只读 primary 副本的数据,可以实现强一致性。

第2、由 primary 控制节点 secondary 节点的可用性。当 primary 更新某个 secondary 副本不成功时,primary 将该 secondary 副本标记为不可用,从而用户再也不读取该不可用的副本。不可用的secondary 副本能够继续尝试与 primary 同步数据,当与 primary 完成数据同步后,primary 能够副本标记为可用。这种方式使得全部的可用的副本,不管是 primary 仍是 secondary 都是可读的,且在一个肯定的时间内,某 secondary 副本要么更新到与 primary 一致的最新状态,要么被标记为不可用,从而符合较高的一致性要求。这种方式依赖于一个中心元数据管理系统,用于记录哪些副本可用,哪些副本不可用。某种意义上,该方式经过下降系统的可用性来提升系统的一致性。

第3、基于 Quorum 机制,后面详细说quorum机制。

primary 副本的肯定与切换

在 primary-secondary 类型的协议中,另外一个核心的问题是如何肯定 primary 副本,尤为是在原primary 副本所在机器出现宕机等异常时,须要有某种机制切换 primary 副本,使得某个 secondary副本成为新的 primary 副本。

这边提出两个问题:

第1、如何肯定节点的状态以发现原 primary 节点异常

第2、切换 primary后,不能影响副本的一致性。尤为是提供较强一致性服务的系统,切换 primary 的影响更是须要控制。要达到这个目的,一种直观的方式是切换的新 primary 的副本数据必须与原 primary 的副本一致。然而在原 primary 已经发送宕机等异常时,如何肯定一个 secondary 副本使得该副本上的数据与原primary 一致又成为新的问题。

数据同步

Primary-secondary 型协议通常都会遇到 secondary 副本与 primary 不一致的问题。此时,不一致的 secondary 副本须要与 primary 进行同步(reconcile)。

一般不一致的形式有三种:1、因为网络分化等异常,secondary 上的数据落后于 primary 上的数据。2、在某些协议下,secondary 上的数据有多是脏数据,须要被丢弃。所谓脏数据是因为primary 副本没有进行某一更新操做,而 secondary 副本上反而进行的多余的修改操做,从而形成secondary 副本数据错误。3、secondary 是一个新增长的副本,彻底没有数据,须要从其余副本上拷贝数据。

对于第一种 secondary 数据落后的状况,常见的同步方式是回放 primary 上的操做日志(一般是redo 日志),从而追上 primary 的更新进度对于脏数据的状况,较好的作法是设计的分布式协议不产生脏数据。若是协议必定有产生脏数据的可能,则也应该使得产生脏数据的几率降到很是低得状况,从而一旦发生脏数据的状况能够简单的直接丢弃有脏数据的

副本,这样至关于副本没有数据。另外,也能够设计一些基于 undo 日志的方式从而能够删除脏数据。若是 secondary 副本彻底没有数据,则常见的作法是直接拷贝 primary 副本的数据,这种方法每每比回放日志追更新进度的方法快不少。但拷贝数据时 primary 副本须要可以继续提供更新服务,这就要求 primary 副本支持快照(snapshot)功能。即对某一刻的副本数据造成快照,而后拷贝快照,拷贝完成后使用回放日志的方式追快照造成后的更新操做。

3.2.3 去中心化副本控制协议

去中心化副本控制是另外一类较为复杂的副本控制协议。与中心化副本系统协议最大的不一样是,去中心化副本控制协议没有中心节点,协议中全部的节点都是彻底对等的,节点之间经过平等协商达到一致。从而去中心化协议没有由于中心化节点异常而带来的停服务等问题。

然而,没有什么事情是完美的,去中心化协议的最大的缺点是协议过程一般比较复杂。尤为当去中心化协议须要实现强一致性时,协议流程变得复杂且不容易理解。因为流程的复杂,去中心化协议的效率或者性能通常也较中心化协议低。一个不恰当的比方就是,中心化副本控制协议相似专制制度,系统效率高但高度依赖于中心节点,一旦中心节点异常,系统受到的影响较大;去中心化副本控制协议相似民主制度,节点集体协商,效率低下,但个别节点的异常不会对系统整体形成太大影响。

3.3 工程中的应用

GFS

GFS 系统的副本控制协议是典型的 Primary-Secondary 型协议,Primary 副本由 Master 指定,Primary 副本决定并发更新操做的顺序。虽然在 GFS 中,更新操做的数据由客户端提交,并在各个副本之间流式的传输,及由上一个副本传递到下一个副本,每一个副本都即接受其余副本的更新,也向下更新另外一个副本,可是数据的更新过程彻底是由 primary 控制的,因此也能够认为数据是由primary 副本同步到 secondary 副本的

Chubby/Zookeeper

Chubby和 Zookeeper 使用了基于 Paxos 的去中心化协议选出 primary 节点,但完成 primary节点的选举后,这两个系统都转为中心化的副本控制协议,即由 primary 节点负责同步更新操做到secondary 节点。

相关文章
相关标签/搜索