阅读http://book.mixu.net/distsys/replication.html的笔记,是本系列的第四章

拷贝其实是一组通信问题,为一些子问题,例如选举,失灵检测,一致性和原子广播提供了上下文。

同步拷贝

可以看到三个不同阶段,首先client发送请求。然后同步拷贝,同步意味着这时候client还在等待着请求返回。最后,服务器返回。

这就是N-of-N write,只有等所有N个节点成功写,才返回写成功给client。系统不容忍任何服务器下线。从性能上说,最慢的服务器决定了写的速度。

异步拷贝

相对的是异步拷贝。

master节点立即返回。该节点可能在本地做了复制,但是不会向其他服务器发送拷贝。只有在返回以后,异步的任务在开始执行。

相对地,这是1-of-N write。性能上说,快。但是不能提供强一致性保证。

主流拷贝的途径

作者用下面的方式分类:

  • 可防止divergence(单拷贝系统)
  • 存在divergence(多master系统)

第一类途径使系统表现得像“single system”,即使系统部分失效。

单拷贝系统按照一次执行中传递的消息数目,可以做一下分类:

  • 1n messages(异步 主从备份)
  • 2n messages(同步 主从备份)
  • 4n messages(2-phase commit,Multi-Paxos)
  • 6n messages (3-phase commit,Paxos with repeated leader election)

下面的图告诉我们,在不同侧重中选择(折中),我们会得到什么样的结果。

等待,性能就变差,一致性上的保证就更强。

主从备份拷贝(Primary/Backup replication)

最常见最基本的拷贝方式。所有的update发生在primary,并且以log的形式拷贝到backup 服务器。主从备份也分同步和异步两种。

MySQL和MongoDB都使用异步主从备份。同步主从备份保证在返回给client之前,backup节点成功存储了拷贝(Replica)。不过即使这样,同步方式也仅能保证较弱的承诺。考虑下面的场景:

  • 主服务器收到write,发送到backup
  • backup 写成功。返回ACK
  • 主服务器fail,client超时,认为写失败。

client现在认为写失败,但是backup其实成功。如果backup promote成为primary,那么就不对了。

2阶段提交(2PC)

2PC在很多经典的关系型数据库中都使用到了。例如MySQL 集群使用2PC提供同步拷贝。下面是2PC的基本流程

[ Coordinator ] -> OK to commit?     [ Peers ]
<- Yes / No [ Coordinator ] -> Commit / Rollback [ Peers ]
<- ACK

在第一阶段,投票,协调者(Coordinator)给所有参与者发送update。每个参与者投票决定是否commit。如果选择commit,结果首先存放在临时区域(the write-ahead log)。除非第二阶段完成,这部分都只算“临时”的update。

在第二阶段,决策,协调者决定结果,并通知参与者。如果所有参与者都选择commit,那结果从临时区域移除,而成为最终结果。

2PC在最后commit之前,有一个临时区域,就能够在节点失效的时候,从而允许回滚。

之前讨论过,2PC属于CA,所以它没有考虑网络分割,对网络分割并没有容错。同时由于是N-of-N write,所以性能上会有一些折扣。

对网络分割容错的一致性算法

最著名的是Paxos算法,不过比较难理解和实现。所以Raft可以讲讲。

什么是网络分割(Network Partition)

节点本身正常运行,但是网络链路发生问题。不同的Partition甚至还能接收client的请求。

2节点,节点失效 vs 网络分割

3节点,节点失效 vs网络分割

单拷贝一致系统必须找到方法去破坏对称性。否则如果网络分裂成两个独立对等系统,divergence发生,无法保证single-copy。所以必须保证只有一个Partition处于活动状态。

多数的决策

所以,对分割容错的一致性算法依赖多数投票。依赖多数,而不是所有(例如2PC)节点,即可容许少数因为网络分割出现的较慢的,无法到达的节点。只要 (N/2 + 1)of N中的节点正常,系统就可以正常运行。

在对网络分割容错的算法中,系统一般使用奇数数目的节点,例如3个节点的系统,允许1个节点失效。5个允许2个失效。这样发生网络分割,我们总能找到一个“大多数”的Partition。

角色

在系统中,节点要么都扮演同一角色,要么各自担任不同角色。

一致性算法通常使节点扮演不同角色。有一个固定的领导或主节点,可以让算法更加高效。Paxos和Raft都利用了不同角色。在Paxos中,存在Proposer。领导者负责在操作中协调,余下的节点作为followers(Paxos中的Acceptors 或者 Voters)

Epochs(不翻了。。。)

在Paxos和Raft中,每次操作的周期都叫一个Epoch(”term“ in Raft)。在每个epoch,都有一个节点被指定为领导(Leader,后面都用英文吧,免得有歧义)。这个有点类似中国的朝代。

在每一次成功的选举后,一个epoch始终使用一个固定的leader,如上图。一些选举可能失败,那么epoch里面迭代到下一个。

真有点类似前面提到的逻辑时钟,让其他节点可以辨识凹凸的节点。那些分割的节点的epoch计数会比较小。

通过决斗(Duels),改变Leader

在一开始,某节点变成leader,其他节点成为follower。在操作过程中,leader维护心跳消息,这样follower就知道leader是否失灵,或者有网络分割发生。

当某节点发现leader没有响应了,(或者在初始状态,没有leader),该节点就转换成中间模式(在Raft称为candidate),然后将其epoch计数加1,发起leader的选举(election),竞争成为leader。

要成为leader,节点必须接收到足够多的votes,一种获取vote的方式就是谁先到谁取得。这样,最终会选出一个leader。

在epoch内,数字标记提案(Proposal)

在每个epoch,leader提议某值用于投票。提案用一个唯一的递增的数字标记。followers则接受它们收到的第一个提案。

普通操作

普通操作中,所有提案都经过leader节点。当一个client提交提案(client指分布式系统使用者),leader节点联系所有法定人数中的节点,如果在follower的回复中,没有与此冲突的提案,leader就提议某值。如果大多数follower都接受该值,那么该值就被认为正式接收。

当然有可能另外一个节点也在尝试成为leader,我们需要确保一旦提案被接受,该值永不改变。否则一个已经接受的提案可能被另外一个竞争leader推翻。

Lamport对该属性有如下表述:

如果对于值v的某提案被选中,那么每一个有较高数字标记的提案都有该值v。

原文如下:

P2: If a proposal with value v is chosen, then every higher-numbered proposal that is chosen has value v.

这个性质可以理解为一致性,也就是业已提出的提案,对其他后来提案都可见,是一种有效性。

为了保证该属性,proposer(leader)必须首先要求followers出示它们已有的最高数字的提案和值。如果proposer发现某提案已经存在,那么必须首先完成执行而不是重新提出提案。Lamport表述如下。

P2b. If a proposal with value v is chosen, then every higher-numbered proposal issued by any proposer has value v.

更具体地,

P2c. For any v and n, if a proposal with value v and number n is issued [by a leader], then there is a set S consisting of a majority of acceptors [followers] such that either (a) no acceptor in S has accepted any proposal numbered less than n, or (b) v is the value of the highest-numbered proposal among all proposals numbered less than n accepted by the followers in S.

这是Paxos算法的核心。如果之前有多个提案存在,那么数字标记最高的提案会被提出。为了保证在leader在依次询问每个acceptor其最新的value的过程中不出现冲突的提案,leader告知follower不要接受比当前提案数字标记小的提案。

那么在Paxos中要达成一个决策,需要两轮通信。

[ Proposer ] -> Prepare(n)                                [ Followers ]
<- Promise(n; previous proposal number
and previous value if accepted a
proposal in the past) [ Proposer ] -> AcceptRequest(n, own value or the value [ Followers ]
associated with the highest proposal number
reported by the followers)
<- Accepted(n, value)

准备阶段,proposer须知道任何冲突或者之前的提案。第二个阶段,一个新的value或者之前被提出的value,在proposer处提出。在某些情况下,比如说同时有两个proposer;比如消息丢失了;或者大多数节点失灵,那么不会有提案被多数节点接受。而这时允许的,因为最终的value还是收敛的。(也就是拥有最高数字标记的那个提案)。

这里非常类似西方民主国家的决策流程。在某项政策需要执行前,首先举行听证会,广泛征求意见。然后根据反馈的结果确定最后的政策。

当然在工程实现上还有不少挑战,这里列举了一些。

网络分割容忍一致性算法的例子:Paxos,Raft和ZAB

强一致下的拷贝算法

总结下各类算法的一些关键特征。

主从备份

  • 单独的,静态的master节点
  • 复制日志,slaves节点并不参与执行具体操作
  • 拷贝操作的延时没有上限
  • 无法容错网络分割
  • 在不一致和错误发生情况下,需要手工干涉

2PC

  • 统一投票:提交或者放弃
  • 静态的master节点
  • 协调者和普通节点同时挂掉情况下无法保证一致性
  • 无法容错网络分割

Paxos

  • 多数投票
  • 动态master节点
  • 允许n/2-1节点挂
  • 对延时并不太敏感

[分布式系统学习]阅读笔记 Distributed systems for fun and profit 之四 Replication 拷贝的更多相关文章

  1. [分布式系统学习]阅读笔记 Distributed systems for fun and profit 之一 基本概念

    因为工作的原因,最近打算看一些分布式学习的资料.其中这个http://book.mixu.net/distsys/就是一篇非常适合分布式入门的介绍. 这个短小的材料有下面5个小的章节,图文并茂,也没有 ...

  2. [分布式系统学习]阅读笔记 Distributed systems for fun and profit 之三 时间和顺序

    这是阅读 http://book.mixu.net/distsys/time.html 的笔记,是该系列的第三章. 为什么时间和顺序很重要呢?为什么我们关系事件A发生在事件B之前? 因为分布式系统要解 ...

  3. [分布式系统学习]阅读笔记 Distributed systems for fun and profit 抽象 之二

    本文是阅读 http://book.mixu.net/distsys/abstractions.html 的笔记. 第二章的题目是"Up and down the level of abst ...

  4. Distributed systems theory for the distributed systems engineer

    Gwen Shapira, SA superstar and now full-time engineer at Cloudera, asked a question on Twitter that ...

  5. [置顶] 人工智能(深度学习)加速芯片论文阅读笔记 (已添加ISSCC17,FPGA17...ISCA17...)

    这是一个导读,可以快速找到我记录的关于人工智能(深度学习)加速芯片论文阅读笔记. ISSCC 2017 Session14 Deep Learning Processors: ISSCC 2017关于 ...

  6. 可扩展的Web系统和分布式系统(Scalable Web Architecture and Distributed Systems)

    Open source software has become a fundamental building block for some of the biggest websites. And a ...

  7. 论文阅读笔记 Improved Word Representation Learning with Sememes

    论文阅读笔记 Improved Word Representation Learning with Sememes 一句话概括本文工作 使用词汇资源--知网--来提升词嵌入的表征能力,并提出了三种基于 ...

  8. (转)深度学习word2vec笔记之基础篇

    深度学习word2vec笔记之基础篇 声明: 1)该博文是多位博主以及多位文档资料的主人所无私奉献的论文资料整理的.具体引用的资料请看参考文献.具体的版本声明也参考原文献 2)本文仅供学术交流,非商用 ...

  9. 深度学习word2vec笔记之基础篇

    作者为falao_beiliu. 作者:杨超链接:http://www.zhihu.com/question/21661274/answer/19331979来源:知乎著作权归作者所有.商业转载请联系 ...

随机推荐

  1. python对日志处理的封装

    一个适应性范围较广的日志处理 # coding=utf8 """ @author bfzs """ import os import log ...

  2. pycharm使用docker镜像的python解释器,pycahrm可视化操作和管理dcoker

    网上关于pycahrm怎么使用docker容器的python解释器的科普,这方面太少,一半都只介绍pycahrm怎么使用linux的解释器.首先pycahrm确保是pro版本. 下面详细的介绍步骤 首 ...

  3. [原]pomelo开发环境搭建

    pomelo基于nodejs服务器开源框架,比较牛逼的! 1.安装nodejs(官网下载地址) 安装python等 具体见官网说明 2.安装pomelo(见官方步骤)或者 http://blog.cs ...

  4. 开启apache的server-status辅助分析工具

    在Apache的调优过程中,可以通过查看Apache提供的server-status(状态报告)来验证当前所设置数值是否合理,在httpd.conf文件中做如下设置来打开: #加载mod_status ...

  5. 05-Vim命令合集

    Vim命令合集 命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filena ...

  6. MacOS的多重启动工具

    在osx Lion升级到Mavericks后原有的refit(http://refit.sourceforge.net)启动管理工具就失效了,refit已经停止更新,新的分支项目时rEFInd(htt ...

  7. 一句话木马:PHP篇

    珍藏版: 一个简单的过D盾的免杀php <?php $ab = $_REQUEST['d']; $a['t'] = "";//主要带对象 D盾就不管后面的了... eval( ...

  8. RF失败案例重跑

    1.1        失败案例重跑 该功能主要是针对上次连跑失败的案例需要重新执行测试的情况,可自动识别上次执行失败的案例并进行重跑,无需手动选择相应的案例,简单高效. 1.5.1.        重 ...

  9. 使用node中的iconv-lite实现对“gbk”格式的转码

    在window中,gbk和utf-8是最常见的两种格式,但是我们在显示的时候往往需要将GBK转换为UTF-8,我现在有一个同步读取文件的操作: const fs = require('fs'); co ...

  10. 二叉查找树(BST)的性质

    二叉查找树的性质: 1.左子树上所有结点的值均小于或等于它的根结点的值. 2.右子树上所有结点的值均大于或等于它的根结点的值. 3.左.右子树也分别为二叉排序树. 下图中这棵树,就是一颗典型的二叉查找 ...