﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-mysileng-随笔分类-分布式</title><link>http://www.cppblog.com/mysileng/category/20570.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 22 Jun 2013 18:58:06 GMT</lastBuildDate><pubDate>Sat, 22 Jun 2013 18:58:06 GMT</pubDate><ttl>60</ttl><item><title>Zookeeper工作原理</title><link>http://www.cppblog.com/mysileng/archive/2013/06/22/201231.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Sat, 22 Jun 2013 15:03:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/06/22/201231.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/201231.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/06/22/201231.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/201231.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/201231.html</trackback:ping><description><![CDATA[<p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; color: #5f5f5f; font-family: Arial, 宋体; line-height: 23px; background-color: #ffffff;">ZooKeeper是一个分布式的，开放源码的分布式应用程序协调服务，它包含一个简单的原语集，分布式应用程序可以基于它实现同步服务，配置维护和命名服务等。Zookeeper是hadoop的一个子项目，其发展历程无需赘述。在分布式应用中，由于工程师不能很好地使用锁机制，以及基于消息的协调机制不适合在某些应用中使用，因此需要有一种可靠的、可扩展的、分布式的、可配置的协调机制来统一系统的状态。Zookeeper的目的就在于此。本文简单分析zookeeper的工作原理，对于如何使用zookeeper不是本文讨论的重点。</p><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; color: #5f5f5f; font-family: Arial, 宋体; line-height: 23px; background-color: #ffffff;"></p><h1>1 Zookeeper的基本概念</h1><h2>1.1 角色</h2><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; color: #5f5f5f; font-family: Arial, 宋体; line-height: 23px; background-color: #ffffff;">Zookeeper中的角色主要有以下三类，如下表所示：<br /><img src="http://www.cppblog.com/images/cppblog_com/mysileng/QQ截图20130622225741.jpg" width="596" height="575" alt="" /><br /><h2>1.2 设计目的</h2><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">1.最终一致性：client不论连接到哪个Server，展示给它都是同一个视图，这是zookeeper最重要的性能。</p><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">2 .可靠性：具有简单、健壮、良好的性能，如果消息m被到一台服务器接受，那么它将被所有的服务器接受。</p><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">3 .实时性：Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息，或者服务器失效的信息。但由于网络延时等原因，Zookeeper不能保证两个客户端能同时得到刚更新的数据，如果需要最新数据，应该在读数据之前调用sync()接口。</p><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">4 .等待无关（wait-free）：慢的或者失效的client不得干预快速的client的请求，使得每个client都能有效的等待。</p><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">5.原子性：更新只能成功或者失败，没有中间状态。</p><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">6 .顺序性：包括全局有序和偏序两种：全局有序是指如果在一台服务器上消息a在消息b前发布，则在所有Server上消息a都将在消息b前被发布；偏序是指如果一个消息b在消息a后被同一个发送者发布，a必将排在b前面。</p><h1>2 ZooKeeper的工作原理</h1><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">Zookeeper的核心是原子广播，这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式，它们分别是恢复模式（选主）和广播模式（同步）。当服务启动或者在领导者崩溃后，Zab就进入了恢复模式，当领导者被选举出来，且大多数Server完成了和leader的状态同步以后，恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。</p><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">为了保证事务的顺序一致性，zookeeper采用了递增的事务id号（zxid）来标识事务。所有的提议（proposal）都在被提出的时候加上了zxid。实现中zxid是一个64位的数字，它高32位是epoch用来标识leader关系是否改变，每次一个leader被选出来，它都会有一个新的epoch，标识当前属于那个leader的统治时期。低32位用于递增计数。</p><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">每个Server在工作过程中有三种状态：</p><ul style="margin: 0px; list-style: none; padding: 0px; font-size: 12px; line-height: 23px;"><li style="margin: 0px; list-style: none; padding: 0px;">LOOKING：当前Server不知道leader是谁，正在搜寻</li><li style="margin: 0px; list-style: none; padding: 0px;">LEADING：当前Server即为选举出来的leader</li><li style="margin: 0px; list-style: none; padding: 0px;">FOLLOWING：leader已经选举出来，当前Server与之同步</li></ul><h2>2.1 选主流程</h2><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">当leader崩溃或者leader失去大多数的follower，这时候zk进入恢复模式，恢复模式需要重新选举出一个新的leader，让所有的Server都恢复到一个正确的状态。Zk的选举算法有两种：一种是基于basic paxos实现的，另外一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。先介绍basic paxos流程：</p><ol style="font-size: 12px; line-height: 23px;"><li style="margin: 0px; list-style: none; padding: 0px;">1 .选举线程由当前Server发起选举的线程担任，其主要功能是对投票结果进行统计，并选出推荐的Server；</li><li style="margin: 0px; list-style: none; padding: 0px;">2 .选举线程首先向所有Server发起一次询问(包括自己)；</li><li style="margin: 0px; list-style: none; padding: 0px;">3 .选举线程收到回复后，验证是否是自己发起的询问(验证zxid是否一致)，然后获取对方的id(myid)，并存储到当前询问对象列表中，最后获取对方提议的leader相关信息(id,zxid)，并将这些信息存储到当次选举的投票记录表中；</li><li style="margin: 0px; list-style: none; padding: 0px;">4. &nbsp;收到所有Server回复以后，就计算出zxid最大的那个Server，并将这个Server相关信息设置成下一次要投票的Server；</li><li style="margin: 0px; list-style: none; padding: 0px;">5. &nbsp;线程将当前zxid最大的Server设置为当前Server要推荐的Leader，如果此时获胜的Server获得n/2 + 1的Server票数， 设置当前推荐的leader为获胜的Server，将根据获胜的Server相关信息设置自己的状态，否则，继续这个过程，直到leader被选举出来。</li></ol><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">通过流程分析我们可以得出：要使Leader获得多数Server的支持，则Server总数必须是奇数2n+1，且存活的Server的数目不得少于n+1.</p><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">每个Server启动后都会重复以上流程。在恢复模式下，如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信息，zk会记录事务日志并定期进行快照，方便在恢复时进行状态恢复。选主的具体流程图如下所示：</p><img src="http://www.cppblog.com/images/cppblog_com/mysileng/QQ截图20130622225958.jpg" width="383" height="799" alt="" /><br /><span style="font-size: 14px; line-height: 23px;">fast paxos流程是在选举过程中，某Server首先向所有Server提议自己要成为leader，当其它Server收到提议以后，解决epoch和zxid的冲突，并接受对方的提议，然后向对方发送接受提议完成的消息，重复这个流程，最后一定能选举出Leader。其流程图如下所示：</span><br /><img src="http://www.cppblog.com/images/cppblog_com/mysileng/QQ截图20130622230030.jpg" width="534" height="459" alt="" /><br /><h2>2.2 同步流程</h2><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">选完leader以后，zk就进入状态同步过程。</p><ol style="font-size: 12px; line-height: 23px;"><li style="margin: 0px; list-style: none; padding: 0px;">1. leader等待server连接；</li><li style="margin: 0px; list-style: none; padding: 0px;">2 .Follower连接leader，将最大的zxid发送给leader；</li><li style="margin: 0px; list-style: none; padding: 0px;">3 .Leader根据follower的zxid确定同步点；</li><li style="margin: 0px; list-style: none; padding: 0px;">4 .完成同步后通知follower 已经成为uptodate状态；</li><li style="margin: 0px; list-style: none; padding: 0px;">5 .Follower收到uptodate消息后，又可以重新接受client的请求进行服务了。</li></ol><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">流程图如下所示：</p><img src="http://www.cppblog.com/images/cppblog_com/mysileng/QQ截图20130622230116.jpg" width="390" height="152" alt="" /><br /><h2>2.3 工作流程</h2><h3>2.3.1 Leader工作流程</h3><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">Leader主要有三个功能：</p><ol style="font-size: 12px; line-height: 23px;"><li style="margin: 0px; list-style: none; padding: 0px;">1 .恢复数据；</li><li style="margin: 0px; list-style: none; padding: 0px;">2 .维持与Learner的心跳，接收Learner请求并判断Learner的请求消息类型；</li><li style="margin: 0px; list-style: none; padding: 0px;">3 .Learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息，根据不同的消息类型，进行不同的处理。</li></ol><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">PING消息是指Learner的心跳信息；REQUEST消息是Follower发送的提议信息，包括写请求及同步请求；ACK消息是Follower的对提议的回复，超过半数的Follower通过，则commit该提议；REVALIDATE消息是用来延长SESSION有效时间。<br />Leader的工作流程简图如下所示，在实际实现中，流程要比下图复杂得多，启动了三个线程来实现功能。</p><img src="http://www.cppblog.com/images/cppblog_com/mysileng/QQ截图20130622230153.jpg" width="498" height="591" alt="" /><br /><h3>2.3.2 Follower工作流程</h3><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">Follower主要有四个功能：</p><ol style="font-size: 12px; line-height: 23px;"><li style="margin: 0px; list-style: none; padding: 0px;">1. 向Leader发送请求（PING消息、REQUEST消息、ACK消息、REVALIDATE消息）；</li><li style="margin: 0px; list-style: none; padding: 0px;">2 .接收Leader消息并进行处理；</li><li style="margin: 0px; list-style: none; padding: 0px;">3 .接收Client的请求，如果为写请求，发送给Leader进行投票；</li><li style="margin: 0px; list-style: none; padding: 0px;">4 .返回Client结果。</li></ol><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">Follower的消息循环处理如下几种来自Leader的消息：</p><ol style="font-size: 12px; line-height: 23px;"><li style="margin: 0px; list-style: none; padding: 0px;"><strong>1 .PING</strong>消息： 心跳消息；</li><li style="margin: 0px; list-style: none; padding: 0px;"><strong>2 .PROPOSAL</strong>消息：Leader发起的提案，要求Follower投票；</li><li style="margin: 0px; list-style: none; padding: 0px;"><strong>3 .COMMIT</strong>消息：服务器端最新一次提案的信息；</li><li style="margin: 0px; list-style: none; padding: 0px;"><strong>4 .UPTODATE</strong>消息：表明同步完成；</li><li style="margin: 0px; list-style: none; padding: 0px;"><strong>5 .REVALIDATE</strong>消息：根据Leader的REVALIDATE结果，关闭待revalidate的session还是允许其接受消息；</li><li style="margin: 0px; list-style: none; padding: 0px;"><strong>6 .SYNC</strong>消息：返回SYNC结果到客户端，这个消息最初由客户端发起，用来强制得到最新的更新。</li></ol><p style="margin: 0px; list-style: none; padding: 0px 0px 5px; font-size: 14px; line-height: 23px;">Follower的工作流程简图如下所示，在实际实现中，Follower是通过5个线程来实现功能的。</p><img src="http://www.cppblog.com/images/cppblog_com/mysileng/QQ截图20130622230225.jpg" width="564" height="219" alt="" /><br /><br /><span style="font-size: 14px; line-height: 23px;">对于observer的流程不再叙述，observer流程和Follower的唯一不同的地方就是observer不会参加leader发起的投票。</span><br /></p><img src ="http://www.cppblog.com/mysileng/aggbug/201231.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-06-22 23:03 <a href="http://www.cppblog.com/mysileng/archive/2013/06/22/201231.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>分布式服务框架 Zookeeper -- 管理分布式环境中的数据</title><link>http://www.cppblog.com/mysileng/archive/2013/06/22/201230.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Sat, 22 Jun 2013 14:19:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/06/22/201230.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/201230.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/06/22/201230.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/201230.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/201230.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 安装和配置详解本文介绍的 Zookeeper 是以 3.2.2 这个稳定版本为基础，最新的版本可以通过官网&nbsp;http://hadoop.apache.org/zookeeper/来获取，Zookeeper 的安装非常简单，下面将从单机模式和集群模式两个方面介绍 Zookeeper 的安装和配置。单机模式单机安装非常简单，只要获取到 Zookeeper 的压缩包并解压到某个目录如：/hom...&nbsp;&nbsp;<a href='http://www.cppblog.com/mysileng/archive/2013/06/22/201230.html'>阅读全文</a><img src ="http://www.cppblog.com/mysileng/aggbug/201230.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-06-22 22:19 <a href="http://www.cppblog.com/mysileng/archive/2013/06/22/201230.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Google利器之Chubby </title><link>http://www.cppblog.com/mysileng/archive/2013/06/22/201222.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Sat, 22 Jun 2013 04:18:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/06/22/201222.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/201222.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/06/22/201222.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/201222.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/201222.html</trackback:ping><description><![CDATA[<div><p style="margin-bottom:0pt; margin-top:0pt; "><a href="http://blog.csdn.net/historyasamirror/article/details/3870168"><span style="color: #0000ff; font-size: 10pt; font-family: 'Times New Roman';">http://blog.csdn.net/historyasamirror/article/details/3870168</span></a></p><p style="margin-bottom:0pt; margin-top:0pt; line-height:22.5000pt; vertical-align:; background:#ffffff; "><a href="http://blog.csdn.net/historyasamirror/article/details/3870168"><span style="mso-spacerun:'yes'; color:#000000; font-weight:bold; font-size:15.0000pt; font-family:'微软雅黑'; ">Google利器之Chubby&nbsp;</span></a></p><p style="margin-bottom:0pt; margin-top:0pt; line-height:19.5000pt; background:#ffffff; "><a href="http://blog.csdn.net/historyasamirror/archive/2009/02/03/3861144.aspx"><span style="color: #0000ff; font-size: 10.5pt; font-family: Arial;">写完了Google&nbsp;Cluster</span></a><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">，该轮到Chubby了。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; ">参考文献：</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">[1]&nbsp;</span><a href="http://labs.google.com/papers/chubby.html" title="The Chubby lock service for loosely-coupled distributed systems"><span style="color: #0000ff; font-size: 10.5pt; font-family: Arial;">The&nbsp;Chubby&nbsp;lock&nbsp;service&nbsp;for&nbsp;loosely-coupled&nbsp;distributed&nbsp;systems</span></a>&nbsp;<span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">[2]&nbsp;</span><a href="http://research.microsoft.com/en-us/um/people/lamport/pubs/paxos-simple.pdf" title="Paxos Made Simple"><span style="color: #0000ff; font-size: 10.5pt; font-family: Arial;">Paxos&nbsp;Made&nbsp;Simple</span></a><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; ">声明</span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">文中大部分的观点来自于文献[1]中的描述，但也夹杂了部分本人自己的理解，所以不能保证本文的正确性。真想深入了解Chubby还是好好读原版论文吧：)</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; ">前言</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">MapReduce很多人已经知道了，但关于Chubyy似乎熟悉它的就非常有限，这倒是不奇怪，因为MapReduce是一个针对开发人员的ProgrammingModel，自然会有很多人去学习它，而Chubby更多的是一种为了实现MapReduce或者Bigtable而构建的内部的&nbsp;工具，对于开发人员来说基本上是透明的。文献[1]我反复读了至少有两三天，但感觉也只是一个囫囵吞枣的结果，里面有很多工程实现上的细节，如果不是自己&nbsp;亲自去设计或者实现，很难体会到其中的道理和奥妙。但是，对于这样一个分布式service的研究，还是让我对一个分布式系统的结构和设计思想有了更加直&nbsp;观的感觉。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; ">从distributed&nbsp;consensus&nbsp;problem说起</span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">distributed&nbsp;consensus&nbsp;problem(分布的一致性问题)是分布式算法中的一个经典问题。它的问题描述大概是这样的：在一个分布式系统中，有一组的Process，它们需要确&nbsp;定一个Value。于是每个Process都提出了一个Value，consensus就是指只有其中的一个Value能够被选中作为最后确定的值，并且&nbsp;当这个值被选出来以后，所有的Process都需要被通知到。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">表面上看，这个问题很容易解决。比如设置一个server，所有的process都&nbsp;向这个server提交一个Value，这个server可以通过一个简单的规则来挑选出一个Value（例如最先到达的Value被选中），然后由这个server通知所有的Process。但是在分布式系统中，就会有各种的问题发生，例如，这个server崩溃了怎么办，所以我们可能需要有几台server共同决定。还有，Process提交Value的时间都不一样，网络传输过程中由于延迟这些Value到达server的顺序也都没有保证。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">为&nbsp;了解决这个问题，有很多人提出了各种各样的Protocol，这些Protocol可以看做是一组需要遵循的规则，按照这些规则，这些Process就能&nbsp;够选举出一个唯一的Value。其中，最有名的一个Protocol就是Paxos算法。（八卦一下，Paxos的提出者叫做Lamport，有很多分布&nbsp;式的算法都是他提出的，他还是Latex的作者，大牛啊...）。想更加了解Paxos算法可以参考文献[2]，很漂亮的一篇文章。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">那么&nbsp;这些和Chubby有什么关系呢？其实Chubby就是为了这个问题而构建出来的。只是它并不是一个Protocol或者是一个算法，而是google精&nbsp;心设计的一个service。这个service不仅能够解决一致性问题，还有其它的一些很实用的好处，会在下文慢慢介绍。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; ">一个实例</span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">在Google&nbsp;File&nbsp;System(GFS)中，有很多的server，这些server需要选举其中的一台作为master&nbsp;server。这其实是一个很典型的consensus问题，Value就是master&nbsp;server的地址。GFS就是用Chubby来解决的这个问题，所有的server通过Chubby提供的通信协议到Chubby&nbsp;server上创建同一个文件，当然，最终只有一个server能够获准创建这个文件，这个server就成为了master，它会在这个文件中写入自己&nbsp;的地址，这样其它的server通过读取这个文件就能知道被选出的master的地址。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; ">Chubby是什么</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">从&nbsp;上面的这个实例可以看出，Chubby首先是一个分布式的文件系统。Chubby能够提供机制使得client可以在Chubby&nbsp;service上创建文件和执行一些文件的基本操作。说它是分布式的文件系统，是因为一个Chubby&nbsp;cell是一个分布式的系统，一般包含了5台机器，整个文件系统是部署在这5台机器上的。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">但是，从更高一点的语义层面上，Chubby是一个lock&nbsp;service，一个针对松耦合的分布式系统的lock&nbsp;service。所谓lock&nbsp;service，就是这个service能够提供开发人员经常用的&#8220;锁&#8221;，&#8220;解锁&#8221;功能。通过Chubby，一个分布式系统中的上千个client都能够&nbsp;对于某项资源进行&#8220;加锁&#8221;，&#8220;解锁&#8221;。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">那么，Chubby是怎样实现这样的&#8220;锁&#8221;功能的？就是通过文件。Chubby中的&#8220;锁&#8221;就是文件，在上例&nbsp;中，创建文件其实就是进行&#8220;加锁&#8221;操作，创建文件成功的那个server其实就是抢占到了&#8220;锁&#8221;。用户通过打开、关闭和读取文件，获取共享锁或者独占锁；&nbsp;并且通过通信机制，向用户发送更新信息。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">综上所述，Chubby是一个lock&nbsp;service，通过这个lock&nbsp;service可以解决分布式中的一致性问题，而这个lock&nbsp;service的实现是一个分布式的文件系统。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">可能会有人问，为什么不是直接实现一个类似于Paxos算法这样的Protocol来解决一致性问题，而是要通过一个lock&nbsp;service来解决？文献[1]中提到，用lock&nbsp;service这种方式有几个好处：</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">1.大部分开发人员在开始开发service的时候都不会考虑到这种一致性的问题，所以一开始都不会使用consensus&nbsp;protocol。只有当service慢慢成熟以后，才开始认真对待这个问题。采用lock&nbsp;service可以使得在保持原有的程序架构和通信机制的情况下，通过添加简单的语句就可以解决一致性问题；</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">2.正如上文实例中所展现，很多时候并不仅仅是选举出一个master，还需要将这个master的地址告诉其它人或者保存某个信息，这种时候，使用Chubby中的文件，不仅仅是提供锁功能，还能在文件中记录下有用的信息（比如master的地址）。所以，很多的开发人员通过使用Chubby来保存metadata和configuration。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">3.&nbsp;一个基于锁的开发接口更容易被开发人员所熟悉。并不是所有的开发人员都了解consensus&nbsp;protocol的，但大部分人应该都用过锁。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">4.&nbsp;一个consensus&nbsp;protocol一般来说需要使用到好几台副本来保证HA（详见Paxos算法），而使用Chubby，就算只有一个client也能用。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">可以看出，之所以用lock&nbsp;service这样的形式，是因为Chubby不仅仅想解决一致性问题，还可以提供更多更有用的功能。事实上，Google有很多开发人员将Chubby当做name&nbsp;service使用，效果非常好。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">关于lock&nbsp;service，还有两个名词需要提及。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">一&nbsp;个是advisory&nbsp;lock。Chubby中的lock都是advisory&nbsp;lock。所谓的advisory&nbsp;lock，举个例子，就是说当有人将某个文件锁住以后，如果有其他的人想不解锁而直接访问这个文件，这种行为是不会被阻止的。和advisory&nbsp;lock对应的是mandatory&nbsp;lock，即如果某个文件被锁住以后，如果有其他的人直接访问它，那么这种行为是会产生exception的。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">另&nbsp;一个是coarse-grained（粗颗粒度的）。Chubby的lock&nbsp;service是coarse-grained，就是说Chubby中的lock一般锁住的时间都比较长，可能是几小时或者几天。与之对应的是fined-grained，这种lock一般只维持几秒或者更少。这两种锁在实现的时候是会有很多不同的考虑的，比如coarse-grained的lock&nbsp;service的负载要小很多，因为加锁解锁并不会太频繁。其它的差别详见文献[1]。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; ">Chubby的架构</span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="position:absolute; z-index:1; left:0px; margin-left:0.0000px; margin-top:0.0000px; width:33.0000px; height:33.0000px; "><img width="33" height="33" src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps_clip_image-22590.png" alt="" /></span><span style="position:absolute; z-index:1; left:0px; margin-left:0.0000px; margin-top:0.0000px; width:33.0000px; height:33.0000px; "><img width="33" height="33" src="file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps_clip_image-25212.png" alt="" /></span></p><p style="margin-bottom: 0pt; margin-top: 0pt; line-height: 19.5pt; background-color: #ffffff; background-position: initial initial; background-repeat: initial initial;"><span style="color: #333333; font-family: Arial; font-size: 10.5pt; line-height: 19.5pt;"><img src="http://www.cppblog.com/images/cppblog_com/mysileng/QQ截图20130622121710.jpg" width="789" height="538" alt="" /><br /><br />上图就是Chubby的系统架构。&nbsp;</span></p><p style="margin-bottom: 0pt; margin-top: 0pt; line-height: 19.5pt; background-color: #ffffff; background-position: initial initial; background-repeat: initial initial;"><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">基本上分为了两部分：服务器一端，称为Chubby&nbsp;cell；client一端，每个Chubby的client都有一个Chubby&nbsp;library。这两部分通过RPC进行通信。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">client端通过Chubby&nbsp;library的接口调用，在Chubby&nbsp;cell上创建文件来获得相应的锁的功能。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">由于整个Chubby系统比较复杂，且细节很多，我个人又将整个系统分为了三个部分：</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">Chubby&nbsp;cell的一致性部分</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">分布式文件系统部分</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">client与Chubby&nbsp;cell的通信和连接部分</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">先从Chubby&nbsp;cell的一致性部分说起。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">一般来说，一个Chubby&nbsp;cell由五台server组成，可以支持一整个数据中心的上万台机器的lock&nbsp;service。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">cell中的每台server我们称之为replicas（副本）。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">当Chubby工作的时候，首先它需要从这些replicas中选举出一个master。注意，这其实也是一个distributed&nbsp;consensus&nbsp;problem，也就是说Chubby也存在着分布式的一致性问题。Chubby是通过采用consensus&nbsp;protocol（很可能就是Paxos算法）来解决这个问题的。所以，Chubby的client用Chubby提供的lock&nbsp;service来解决一致性问题，而Chubby系统内部的一致性问题则是用consensus&nbsp;protocol解决的。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">每个master都具有一定的期限，成为master&nbsp;lease。在这个期限中，副本们不会再选举一个其它的master。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">为&nbsp;了安全性和容错的考虑，所有的replicas（包括master）都维护的同一个DB的拷贝。但是，只有master能够接受client提交的操作对DB进行读和写，而其它的replicas只是和master进行通信来update它们各自的DB。所以，一旦一个master被选举出来后，所有的client端都之和master进行通信（如图所示），如果是读操作，那么master一台机器就搞定了，如果是写操作，master会通知其它的replicas进行update。这样的话，一旦master意外停机，那么其它的replicas也能够很快的选举出另外一个master。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">再说说Chubby的文件系统</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">前&nbsp;文说过，Chubby的底层实现其实就是一个分布式的文件系统。这个文件系统的接口是类似于Unix系统的。例如，对于文件名&#8220;/ls/foo&nbsp;/wombat/pouch&#8221;，ls表示的是&#8220;lock&nbsp;service&#8221;，foo表示的是某个Chubby&nbsp;cell的名字，wombat/pouch则是这个cell上的某个文件目录或者文件名。如果一个client端使用Chubby&nbsp;library来创建这样一个文件名，那么这样一个文件就会在Chubby&nbsp;cell上被创建。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">Chubby的文件系统由于它的特殊用途做了很多&nbsp;的简化。例如它不支持文件的转移，不记录文件最后访问时间等等。整个文件系统只包含有文件和目录，统一称为&#8220;Node&#8221;。文件系统采用Berkeley&nbsp;DB来保存Node的信息，主要是一种map的关系。Key就是Node的名字，Value就是Node的内容。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">还有一点需要提及的&nbsp;是，Chubby&nbsp;cell和client之间用了event形式的通知机制。client在创建了文件之后会得到一个handle，并且还可以订阅一系列的event，例&nbsp;如文件内容修改的event。这样的话，一旦client相关的文件内容被修改了，那么cell会通过机制发送一个event来告诉client该文件被&nbsp;修改了。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">最后谈谈client与cell的交互部分</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">这里大致包含两部分的内容：cache的同步机制和KeepAlive握手协议。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">为&nbsp;了降低client和cell之间通信的压力和频率，client在本地会保存一个和自己相关的Chubby文件的cache。例如如果client通过Chubby&nbsp;library在cell上创建了一个文件，那么在client本地，也会有一个相同的文件在cache中创建，这个cache中的文件的内容和cell上文件的内容是一样的。这样的话，client如果想访问这个文件，就可以直接访问本地的cache而不通过网络去访问cell。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">cache有两个状态，有效和无效。当&nbsp;有一个client要改变某个File的时候，整个修改会被master&nbsp;block，然后master会发送无效标志给所有cache了这个数据的client（它维护了这么一个表），当其它client端收到这个无效标志&nbsp;后，就会将cache中的状态置为无效，然后返回一个acknowledge；当master确定收到了所有的acknowledge之后，才完成整个modification。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">需要注意的是，master并不是发送update给client而是发送无效标志给client。这是因为如果发送update给client，那么每&nbsp;一次数据的修改都需要发送一大堆的update，而发送无效标示的话，对一个数据的很多次修改只需要发送一个无效标示，这样大大降低了通信量。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; ">至于KeepAlive协议，则是为了保证client和master随时都保持着联系。client和master每隔一段时间就会KeepAlive一次，这样的话，如果master意外停机，client可以很快的知道这个消息，然后迅速的转移到新的master上。并且，这种转移对于client端的application是透明的，也就是说application并不会知道master发生了错误。关于cache和KeepAlive还有很多的&nbsp;细节，想了解的读文献[1]吧。</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-weight:bold; font-size:10.5000pt; font-family:'Arial'; ">总结</span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="mso-spacerun:'yes'; color:#333333; font-size:10.5000pt; font-family:'Arial'; "><br /></span><span style="color: #333333; font-size: 10.5pt; font-family: Arial;">其实在我的这篇文章中，还有一个很大的主题没有提及，那就是Chubby的容错机制。基本上，容错这个思想贯穿了文献[1]的始终，也正是因此，我很难将&nbsp;它单独提取出来解释，因为它散落在了Chubby系统设计的所有角落。我个人感觉，容错是一个分布式系统设计的核心思想，在设计的时候要求考虑到所有可能&nbsp;会发生的错误，不仅仅包括了硬件的错误，网络的故障，还包括了开发人员可能出现的错误。我想，这是我读这篇文章[1]最大的收获。<br /><br /><br /><a href="/Files/mysileng/Paxos算法深入分析.doc">/Files/mysileng/Paxos算法深入分析.doc</a><br /></span></p><p style="margin-bottom:0pt; margin-top:0pt; "></p></div><img src ="http://www.cppblog.com/mysileng/aggbug/201222.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-06-22 12:18 <a href="http://www.cppblog.com/mysileng/archive/2013/06/22/201222.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>高并发处理方案</title><link>http://www.cppblog.com/mysileng/archive/2013/06/19/201153.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Wed, 19 Jun 2013 08:33:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2013/06/19/201153.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/201153.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2013/06/19/201153.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/201153.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/201153.html</trackback:ping><description><![CDATA[<span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">时常看到高并发的问题，但高并发其实是最不需要考虑的东西。为何，他虚无缥缈，很少有网站真的需要这些东西，而且其中很多技术，其实你已经在用了。有这个意识就够了，不需要时刻盯着这个问题。只有很少的网站真的能达到高并发。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">简单做一个归纳，从低成本、高性能和高扩张性的角度来说有如下处理方案：&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">&nbsp; 1、HTML静态化&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">&nbsp; 2、图片服务器分离&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">&nbsp; 3、数据库集群和库表散列&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">&nbsp; 4、缓存&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">&nbsp; 5、镜像&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">&nbsp; 6、负载均衡;一个典型的使用负载均衡的策略就是，在软件或者硬件四层交换的基础上搭建squid集群，这种思路在很多大型网站包括搜索引擎上被采用，这样的架构低成本、高性能还有很强的扩张性，随时往架构里面增减节点都非常容易。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">下面也是一个牛人所做的总结，跟上面部分相同。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">高并发时，性能瓶颈及当前常用的应对措施&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">1.数据库瓶颈。Mysql并发链接100&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">2.apache 并发链接1500&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">3.程序执行效率&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">1.有数据库瓶颈时，当前处理方案无外乎 主从，集群。增加cache(memcached).&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">如：手机之家新系统介绍及架构分享（http://www.slideshare.net/Fenng/ss-1218991?from=ss_embed）&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">就是在cache层做优化&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">又拍网架构（http://www.bopor.com/?p=652）&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">是以增加数据库，分表分库的方法解决。&nbsp;<br /></span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">Sina增加了mq(消息队列)来分发数据。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">还有风站用了key-value的数据库。其实这可以理解成一个持久化的缓存。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">2.apache瓶颈。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">增加服务器。负载均衡。如sina的F5&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">由于进程数的限制。会把一些基本不变的代码挪出来放到单独的服务器。如css/js/图片。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">国内成功的案例是tom的cdn&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">又如nginx的横空出世和squid的反向代理都是基于这个原因出来的。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">3.php的执行效率。原因有多个。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">1）.本身的效率低。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">解决的成功案例是Zend Optimizer 和 facebooke的hiphop&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">Taobao是把php代码编译成模块解决效率问题。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">2). 数据库查询效率问题。如可能有order by ,group by 等Sql数据问题。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">这个其实应该归结到数据库设计问题。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">解决的办法是建立正确的索引。增加memcache.。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">对like表 用专用的sphinx.和lucence 等搜索服务。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">程序员都应该会用explain对sql语句作分析。&nbsp;</span><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><br style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; " /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.200000762939453px; background-color: #ffffff; ">说到底。解决高并发就是上面所列技术，程序员要做的就是把每个技术具体实现。&nbsp;</span>&nbsp;<img src ="http://www.cppblog.com/mysileng/aggbug/201153.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2013-06-19 16:33 <a href="http://www.cppblog.com/mysileng/archive/2013/06/19/201153.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>