<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tim[后端技术] &#187; 3PC</title>
	<atom:link href="http://timyang.net/tag/3pc/feed/" rel="self" type="application/rss+xml" />
	<link>http://timyang.net</link>
	<description>Tim&#039;s blog, 关于后端架构、互联网技术、分布式、大型网络应用、NoSQL、Key Value等</description>
	<lastBuildDate>Mon, 26 Jul 2010 15:32:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>多IDC的数据分布设计(一)</title>
		<link>http://timyang.net/distributed/multi-idc-consensus/</link>
		<comments>http://timyang.net/distributed/multi-idc-consensus/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 13:04:18 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[分布式]]></category>
		<category><![CDATA[2PC]]></category>
		<category><![CDATA[3PC]]></category>
		<category><![CDATA[consensus]]></category>
		<category><![CDATA[paxos]]></category>
		<category><![CDATA[Three-phase commit]]></category>
		<category><![CDATA[Two-phase commit]]></category>

		<guid isPermaLink="false">http://timyang.net/?p=546</guid>
		<description><![CDATA[上个月跟某个朋友谈及多IDC数据同时读写访问的问题(tweet)，当时觉得有不少解决方案，但觉得思路还不够清晰。最近看了Google App Engine工程师Ryan Barrett介绍GAE后端数据服务的演讲稿Transactions Across Datacenters(视频)，用Ryan的方法来分析这个问题后就豁然开朗。
按Ryan的方法，多IDC实现有以下几种思路。
一、Master/slave
这个是多机房数据访问最常用的方案，一般的需求用此方案即可。因此大家也经常提到“premature optimization is the root of all evil”。
优点：利用mysql replication即可实现，成熟稳定。
缺点：写操作存在单点故障，master坏掉之后slave不能写。另外slave的延迟也是个困扰人的小问题。
二、Multi-master
Multi-master指一个系统存在多个master, 每个master都具有read-write能力，需根据时间戳或业务逻辑合并版本。比如分布式版本管理系统git可以理解成multi-master模式。具备最终一致性。多版本数据修改可以借鉴Dynamo的vector clock等方法。
优点：解决了单点故障。
 缺点：不易实现一致性，合并版本的逻辑复杂。
三、Two-phase commit(2PC)
Two-phase commit是一个比较简单的一致性算法。由于一致性算法通常用神话(如Paxos的The Part-Time Parliament论文)来比喻容易理解，下面也举个类似神话的例子。
某班要组织一个同学聚会，前提条件是所有参与者同意则活动举行，任意一人拒绝则活动取消。用2PC算法来执行过程如下
Phase 1
Prepare: 组织者(coordinator)打电话给所有参与者(participant) ，同时告知参与者列表。
 Proposal: 提出周六2pm-5pm举办活动。
 Vote: participant需vote结果给coordinator：accept or reject。
 Block: 如果accept, participant锁住周六2pm-5pm的时间，不再接受其他请求。
Phase 2
Commit: 如果所有参与者都同意，组织者coodinator通知所有参与者commit, 否则通知abort，participant解除锁定。
Failure 典型失败情况分析
Participant failure:
任一参与者无响应，coordinator直接执行abort
Coordinator failure:
 Takeover: 如果participant一段时间没收到cooridnator确认(commit/abort)，则认为coordinator不在了。这时候可自动成为Coordinator备份(watchdog)
 Query: watchdog根据phase 1接收的participant列表发起query
 Vote: 所有participant回复vote结果给watchdog, accept or reject
 Commit: 如果所有都同意，则commit, 否则abort。
优点：实现简单。
 缺点：所有参与者需要阻塞(block)，throughput低；无容错机制，一节点失败则整个事务失败。
四、Three-phase commit (3PC)
Three-phase [...]]]></description>
			<content:encoded><![CDATA[<p>上个月跟某个朋友谈及多IDC数据同时读写访问的问题(<a href="http://twitter.com/xmpp/status/7625866165">tweet</a>)，当时觉得有不少解决方案，但觉得思路还不够清晰。最近看了Google App Engine工程师Ryan Barrett介绍GAE后端数据服务的演讲稿<a href="http://snarfed.org/space/transactions_across_datacenters_io.html">Transactions Across Datacenters</a>(<a href="http://www.youtube.com/watch?v=srOgpXECblk">视频</a>)，用Ryan的方法来分析这个问题后就豁然开朗。</p>
<p>按Ryan的方法，多IDC实现有以下几种思路。</p>
<h2>一、Master/slave</h2>
<p>这个是多机房数据访问最常用的方案，一般的需求用此方案即可。因此大家也经常提到“premature optimization is the root of all evil”。<br />
<strong>优点：</strong>利用mysql replication即可实现，成熟稳定。<br />
<strong>缺点：</strong>写操作存在单点故障，master坏掉之后slave不能写。另外slave的延迟也是个困扰人的小问题。</p>
<h2>二、Multi-master</h2>
<p><a href="http://en.wikipedia.org/wiki/Multi-master_replication">Multi-master</a>指一个系统存在多个master, 每个master都具有read-write能力，需根据时间戳或业务逻辑合并版本。比如分布式版本管理系统git可以理解成multi-master模式。具备最终一致性。多版本数据修改可以借鉴Dynamo的vector clock等方法。</p>
<p><strong>优点：</strong>解决了单点故障。<br />
<strong> 缺点：</strong>不易实现一致性，合并版本的逻辑复杂。</p>
<h2>三、Two-phase commit(2PC)</h2>
<p><a href="http://en.wikipedia.org/wiki/Two-phase_commit_protocol">Two-phase commit</a>是一个比较简单的一致性算法。由于一致性算法通常用神话(如Paxos的The Part-Time Parliament论文)来比喻容易理解，下面也举个类似神话的例子。</p>
<p>某班要组织一个同学聚会，前提条件是所有参与者同意则活动举行，任意一人拒绝则活动取消。用2PC算法来执行过程如下</p>
<h3>Phase 1</h3>
<p><strong>Prepare: </strong>组织者(coordinator)打电话给所有参与者(participant) ，同时告知参与者列表。<br />
<strong> Proposal:</strong> 提出周六2pm-5pm举办活动。<br />
<strong> Vote:</strong> participant需vote结果给coordinator：accept or reject。<br />
<strong> Block:</strong> 如果accept, participant锁住周六2pm-5pm的时间，不再接受其他请求。</p>
<h3>Phase 2</h3>
<p><strong>Commit:</strong> 如果所有参与者都同意，组织者coodinator通知所有参与者commit, 否则通知abort，participant解除锁定。</p>
<h3>Failure 典型失败情况分析</h3>
<p><strong>Participant failure:</strong><br />
任一参与者无响应，coordinator直接执行abort<br />
<strong>Coordinator failure:</strong><br />
<strong> Takeover:</strong> 如果participant一段时间没收到cooridnator确认(commit/abort)，则认为coordinator不在了。这时候可自动成为Coordinator备份(watchdog)<br />
<strong> Query:</strong> watchdog根据phase 1接收的participant列表发起query<br />
<strong> Vote:</strong> 所有participant回复vote结果给watchdog, accept or reject<br />
<strong> Commit:</strong> 如果所有都同意，则commit, 否则abort。</p>
<p><strong>优点：</strong>实现简单。<br />
<strong> 缺点：</strong>所有参与者需要阻塞(block)，throughput低；无容错机制，一节点失败则整个事务失败。</p>
<h2>四、Three-phase commit (3PC)</h2>
<p><a href="http://en.wikipedia.org/wiki/Three-phase_commit_protocol">Three-phase commit</a>是一个2PC的改进版。2PC有一些很明显的缺点，比如在coordinator做出commit决策并开始发送commit之后，某个participant突然crash，这时候没法abort transaction, 这时候集群内实际上就存在不一致的情况，crash恢复后的节点跟其他节点数据是不同的。因此3PC将2PC的commit的过程1分为2,分成preCommit及commit, 如图。<br />
<img class="alignnone" title="3PC" src="http://upload.wikimedia.org/wikipedia/en/3/39/Three-phase_commit_diagram.png" alt="" width="611" height="321" /><br />
(图片来源：<a href="http://en.wikipedia.org/wiki/File:Three-phase_commit_diagram.png">http://en.wikipedia.org/wiki/File:Three-phase_commit_diagram.png</a>)</p>
<p>从图来看，cohorts(participant)收到preCommit之后，如果没收到commit, 默认也执行commit, 即图上的timeout cause commit。</p>
<p>如果coodinator发送了一半preCommit crash, watchdog接管之后通过query, 如果有任一节点收到commit, 或者全部节点收到preCommit, 则可继续commit, 否则abort。</p>
<p><strong>优点：</strong>允许发生单点故障后继续达成一致。<br />
<strong> 缺点：</strong>网络分离问题，比如preCommit消息发送后突然两个机房断开，这时候coodinator所在机房会abort, 另外剩余replicas机房会commit。</p>
<h2>五、Paxos</h2>
<p>Google Chubby的作者Mike Burrows说过， “there is only one consensus protocol, and that’s Paxos” – all other approaches are just broken versions of Paxos. 意即“世上只有一种一致性算法，那就是Paxos”，所有其他一致性算法都是Paxos算法的不完整版。相比2PC/3PC, Paxos算法的改进</p>
<ul>
<li>P1a. 每次Paxos实例执行都分配一个编号，编号需要递增，每个replica不接受比当前最大编号小的提案</li>
<li>P2. 一旦一个 value v 被replica通过，那么之后任何再批准的 value 必须是 v，即没有拜占庭将军(Byzantine)问题。拿上面请客的比喻来说，就是一个参与者一旦accept周六2pm-5pm的proposal, 就不能改变主意。以后不管谁来问都是accept这个value。</li>
<li>一个proposal只需要多数派同意即可通过。因此比2PC/3PC更灵活，在一个2f+1个节点的集群中，允许有f个节点不可用。</li>
</ul>
<p>另外Paxos还有很多约束的细节，特别是Google的chubby从工程实现的角度将Paxos的细节补充得非常完整。比如如何避免Byzantine问题，由于节点的持久存储可能会发生故障，Byzantine问题会导致Paxos算法P2约束失效。</p>
<p>以上几种方式原理比较如下</p>
<p><a href="http://timyang.net/blog/wp-content/uploads/2010/02/idc-transaction.png"><img class="alignnone size-full wp-image-547" title="idc-transaction" src="http://timyang.net/blog/wp-content/uploads/2010/02/idc-transaction.png" alt="" width="500" height="228" /></a></p>
<p>(图片来源：<a href="http://snarfed.org/space/transactions_across_datacenters_io.html">http://snarfed.org/space/transactions_across_datacenters_io.html</a>)</p>
<p>后文会继续比较实践环境选取何种策略合适。</p>
<p>（PS: 写完后在Google Reader上发现本文跟王建硕最近发表的《<a href="http://home.wangjianshuo.com/cn/20100201_aeaeaecee.htm">关于两个机房的讨论</a>》文章有点类似，特别是本文一、二方式。不过他的文章偏MySQL的实现，我的重点是一致性算法，大家可以有选择性的阅读。）</p>
Similar Posts:<ul><li><a href="http://timyang.net/data/multi-idc-design/" rel="bookmark" title="March 25, 2010">多IDC的数据分布设计(二)</a></li>

<li><a href="http://timyang.net/distributed/paxos-scenarios/" rel="bookmark" title="September 23, 2009">Paxos在大型系统中常见的应用场景</a></li>

<li><a href="http://timyang.net/architecture/consistent-hashing-practice/" rel="bookmark" title="September 6, 2009">某分布式应用实践一致性哈希的一些问题</a></li>

<li><a href="http://timyang.net/data/dynamo-flawed-architecture-chinese/" rel="bookmark" title="March 1, 2010">Dynamo一个缺陷的架构设计(译)</a></li>

<li><a href="http://timyang.net/architecture/yahoo-pnuts/" rel="bookmark" title="June 21, 2009">Yahoo!的分布式数据平台PNUTS简介及感悟</a></li>
</ul><!-- Similar Posts took 18.328 ms -->]]></content:encoded>
			<wfw:commentRss>http://timyang.net/distributed/multi-idc-consensus/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
