RSS Feed

Posts Tagged ‘分布式’

  1. chubby(zookeeper)和paxos

    August 22, 2013 by xudifsd

    解决的问题

    先说为什么要有这两个东西。比如你开了个银行,里面有三个账户A,B和C。这时有两个人想转账,一个人想从A中转到B中,另一个人想从A中转到C中。但是A中的金额只够支持转一次,所以要不第一个人转账失败,要不第二个失败。

    如何实现?非常简单,只部署一个服务器接收所有请求,第一个收到的请求成功,第二个失败即可,但是这会产生单节点失败——假设这个服务器挂了,那么银行的所有业务都会挂掉。这样我们可以起两个服务器(或者多个服务器),指定一个为主服务器,其他服务器在主服务器挂掉后成为主服务器,如果只有两个服务器那么另一个就成为主服务器,但是如果有多个服务器如何选择主服务器呢?并且在两个服务器的情况下可能另一个没有挂掉,仍然能收到别人的请求,只是无法收到另一个服务器的请求了,这样就会造成有两个服务器都认为自己是主服务器(网络分区)。这样就可能会造成两个转账都成功。

    问题的核心就是多个服务器状态的一致性,状态的一致就需要服务器达成共识,前面描述的问题可以靠两个共识来解决:

    • 谁是主服务器
    • 谁的转账应该成功

    如果系统能达成这两个共识的其中一个就能解决问题:

    如果能达成第一个共识,那么所有的转账操作都需要由主服务器做出判断,其他从服务器只需要跟随即可,同时为了解决前面的网络分区问题只需要做一个master lease即可(一群服务器选举出一个master,并且承诺不会在一定时间内的任何情况下选出其他master,这样如果出现网络分区,整个服务可能不可用,但是过了master lease期,集群就能选出另一个master,并重新提供服务。而原来的master因为没能成为新master而成为跟随者)。

    或者达成另一个共识“谁的转账应该成功”,这样就不要求谁来成为master来做决定:给两个转账分配序列号,这个序列号是单调递增的,并且对转账都是唯一,这个序列号就是需要所有服务器达成的共识。达成共识后服务器再按照序列号的顺序应用操作即可,这样所有服务器也能达到一致状态。

    总结起来就是:

    • 为了解决单节点失败问题,需要多个服务器。
    • 为了让多个服务器的状态一致,可以用前面提到的两种解决方法之一。

    前面的两个解决方法对应的就是chubbypaxos。开源的解决方案对应的就是zookeeperlibpaxos

    chubby或者说zookeeper提供一个类似于文件系统的接口,让使用者能用类似于文件锁的方式选举出自己的master,而chubby本身为了维持高可用需要部署在至少3台服务器上(这样挂掉少于一半的服务器,整体还能工作),而且他们内部就是使用paxos算法产生内部共识的(zookeeper使用类似于paxos的算法Zab,详情见《Hadoop权威指南》)。

    这样看起来似乎使用libpaxos比较方便,因为都能解决问题,并且libpaxos不需要多余的服务器来运行chubby服务,只需要服务本身使用这个库就行。但是chubby论文就说道了为什么Google内部实现了chubby而不是实现一个库:

    1. 大部分开发人员在开始开发时都不会考虑到高可用性问题,所以一开始都只会运行在一台服务器上。只有当服务的用户增多以后,才开始认真对待这个问题。使用chubby可以在保持原有的程序架构的情况下,通过添加简单的语句就可以解决一致性问题。
    2. 有时候并不仅仅需要选出一个master,还需要让zookeeper托管一些信息,比如服务的配置信息以及master的地址等,但是zookeeper并不是专门用来做存储的,所以不要往zookeeper上写太多东西。
    3. 一个基于锁的接口更容易被开发者接受。因为并不是所有的开发者都了解分布式共识协议的,但大部分都用过锁。
    4. 一个分布式共识协议需要使用到好几台副本来保证高可用,而使用chubby,就算只有一个用户也能用。

    这样来说chubby这样的系统更加好用,因为Chubby不仅解决了一致性问题,还可以提供更多更有用的功能,像配置的管理。并且能用上zookeeper的公司都不是小公司,这样的公司有许多组件需要zookeeper这样的东西来维持高可用,而且zookeeper设计时就尽量减少使用者与它的交互,避免zookeeper成为瓶颈,所以可以很多服务同时使用一个zookeeper集群。

    zookeeper和redis的不同

    有时候很多人会觉得zookeeper很像redis,但是他们完全不是一个东西。

    首先,他们的配置就完全不一样,redis需要手动配置谁是master,谁是slaver,而且slaver主要用于加速读而已,并且要想让redis的master挂掉后让其中一个slaver当master还得自己写很多东西(貌似redis的sentinel在解决这个问题,具体没研究过)。但是这在zookeeper中完全不是问题,配置里甚至不会指定谁是master,由他们自己选举(注意,zookeeper中选举master和别的服务靠zookeeper选举master是两回事,zookeeper中选master主要是为了避免活锁,提高性能,详见paxos那篇论文)。

    第二个不同就是客户端连接zookeeper给的地址类似“zk1:2181,zk2:2181,zk3:2181”这样的逗号分割的IP、端口对,客户端自动连接到zookeeper中的master,并在zookeeper的master换了之后自动连接master,这和redis也完全不同。

    第三个不同就是zookeeper提供了大量的接口用于分布式机器间的同步。举例来说,在zookeeper中可以通过一个接口用文件来表示某个客户端,一旦zookeeper与客户端失去连接,zookeeper会自动把文件删除。并且zookeeper还提供了异步的API让客户端可以watch某个节点下文件的变动,这两个API结合起来就能用于让zookeeper通知客户端:他们中某个客户端已经挂掉。这样就不需要让这些客户端不断轮询zookeeper来获取信息。而redis要实现这个功能则需要服务器自己去查,很费流量的。


  2. 近两个月总结

    June 30, 2013 by xudifsd

    最近挺忙,发现都有两个月没写博客了,当年花钱买个主机而不是建个免费博客就是为了逼自己每个月写一篇博客的,但是这两个月实在是太忙了。眼看这7月就要到了,GR也要推上断首台了。总要挤些东西出来,恩。

    之前没上过班时觉得就算上班时间也应该挺充裕,能有自己的时间做东西。但是事实是,每天早上起来后马上就去上班,下完班吃完饭就已经7点了。而且由于盯了一天电脑了,回到家实在是不想再看电脑,顶多看下kindle或纸质书。而且在coursera上报了ML的课,每天下班看点视频,周末把编程作业做了,这样一来其他空闲时间就不多了,真心佩服那些报几个coursera课的人。而且这个月又是毕业季,上半个月总要花些时间整毕业论文的东西(特别是格式。。)。

    这两个月在公司里基本上没怎么干活,都在学习(不过从明天开始美好的日子就要过去,要开始干活了)。学了clojure,看了Google很久前发的几篇论文,还看了spark的论文。虽然说是看了,不过很多都看得很浅显,没空闲时间,基本上没有在学校那种能坚持下来看一些东西,并且形成一篇好的博客或程序的,或许也是因为自己才工作,没有形成一种好的习惯吧。

    好吧,能坚持看到我废话到现在的人也不容易,给你们些可能对你们有用的东西吧,是这两个月看的分布式方面的一些总结。

    在这里的分布式,我指的是类似于Google数据中心的廉价PC服务器组成的集群,也就是cluster。

    关于为什么需要使用这样的cluster《The Datacenter as a Computer》里说得很清楚了,就是因为便宜。虽然廉价PC的错误率虽然很高,但是就算加上容错所需要多出来的PC,价格也会比硬件超好的服务器便宜。而由于硬件的错误,软件就必须在设计时考虑容错与灾难恢复,这两点也是在Google那三篇论文中强调的。Google那三篇论文加上一篇冷门论文就是、GFSBigTableMapReducechubby。他们对应的开源版本分别是HDFS、HBase、Hadoop和zookeeper。都是apache的项目,而且都用的是java,这也是为什么互联网企业会有这么多用java的。如果想真正学好分布式就需要从chubby也就是zookeeper入手,其他一些东西只是建立在它之上的,学起来对于真正的分布式似乎没太大作用,对使用开源版本倒是有些作用。所以要想自己做个分布式框架能复用的就只有chubby了,但是chubby又很底层,知道和学习的并不多。不过很多分布式的框架和一些底层都会依赖于它,比如mesos、spark(因为基于mesos)、storm等。

    再说说spark,spark的论文在,不过这篇论文介绍的主要却不是spark,而是spark的原理,论文最有意思的地方是它介绍的灾难恢复的技术,这也是分布式程序需要做最多优化和权衡的地方。另外据论文描述,使用它进行ML计算比用hadoop计算要快20倍。。当时看到这个比例就惊了,那就是说hadoop需要计算一天的东西spark一小时就能搞定诶(看完后就问我厂研究院的新员工他们拿什么计算,想推荐下这个,她竟然说具体不知道,她是拿单机算,于是我就只能呵呵呵了)。spark的缺点就是它的语言接口是scala根据评论发现spark的接口既有scala和也有python,不过豆瓣有克隆版dpark,接口是python,应该比较好用,还要问豆瓣厂工。

    所以如果是我,我会先拿chubby入手,并且看看一些使用zookeeper的程序是如何使用它的,一旦这个学会,再自己实现个什么小东西,分布式也就基本上差不多了,同时再推一个解释chubby挺好的博文