大数据 频道

万达集团李明昊:地域分布式系统设计与实践

  【IT168 评论】导语:本文根据李明昊老师在2018年5月10日【第九届中国数据库技术大会(DTCC)】现场演讲内容整理而成。

  李明昊 万达网络科技集团 资深架构师

  现任万达网络科技集团资深架构师,BI(商业智能)团队技术负责人。之前曾在百度,360等公司参与设计研发过多个海量数据分布式存储系统,包括百度公有云服务的底层分布式存储系统MolaDB,360云盘的底层分布式存储系统Bada等。

  摘要:本次分享,深入剖析了主流的一致性协议paxos,raft等的历史渊源和设计细节,阐述了它们的优缺点与适用场景;并结合公司的实际场景,对raft协议做了改进,使自研的分布式存储系统可以运行于这个具体环境之上,同时兼顾性能,可靠性与硬件、网络成本。

  大纲:

  提出问题

  分析问题

  解决问题

  经验总结

  正文

  1. 提出问题

  万达在全国具有200+的实体广场,每个广场具备自己的内部机房。包括路由器,无线热点,主机,防火墙等硬件资源。当用户进入广场内部时,手机会通过热点自动连入广场内部局域网系统。

  但这些广场机房的服务质量远达不到专业数据中心的服务质量。广场内部接近局域网环境,广场之间接近广域网环境。

  如果我们能有效的利用广场内部硬件、网络资源,将用户或商品的一部分数据存入广场内部机房,并做合适的计算加工,用户将享受到本地计算与本地存储的体验,同时降低了硬件成本。但必须想办法解决小机房服务质量不达标的问题。

  2. 分析问题

  2.1了解必要的理论体系

  历史脉络

  这是我截取的一个分布式和数据库理论的重要事件时间轴。通过这个时间轴我们可以总结出如下结论:

  1、 计算机与互联网技术起源于战争的需要。

  2、以Jim Gray为代表的数据库技术和以Leslie Lamport为代表的分布式技术逐渐融合。

  这里面涉及到两个重要的人物,一个是Jim Gray。大约在七十年代,Jim Gray写了一篇文章,文章抽象出了数据库事务处理的概念,包括两阶段提交、日志以及其他事务处理的ACID概念。

  另外一个人是Leslie Lamport,他在1978年写了一篇论文,描述了逻辑时钟的概念,后续的很多分布式领域都是基于他的论文创建的,包括1990年Leslie Lamport自己提出的paxos协议。

  CAD猜想

  CAD是2000年Eric Brewer在UC Berkeley提出来的,并在2002年得到了证明。在分布式领域,CAD理论对我们的影响非常大。

  ACID、CPA两个C有什么不同?

  ACID里面的C指的是“Consistency(始终如一的)”,指的是同一份数据,不管进行怎样的操作始终保持一致性或者受约束的状态。CPA里面的C指的是“Consensus(共识的)”,指的是多份数据。当然这个说法也不是特别严谨。

  如下图所示:

  Consistency主要表现一种约束性,就比如图片上的一个五角星可以正好的放进左边的矩形框里,即可以说它是一致的。但是下面的五边形无法放进左边的矩形框里,它不符合约束,即非一致性。

  对于Consensus(共识的),如上图,五个一样的五角星保持一致即共识的,如果中间的一个五角星变成五边形,即非共识、非一致。

  关于分布式里的“一致性”,Amazon-com的CTO Werner Vogels又进一步进行了细分。Werner Vogels把一致性又分成了强一致性、弱一致性、最终一致性。最终一致性又分成因果一致性、读写一致性、会话一致性、单调读一致性、单调写一致性。

  如何划清问题边界?

  在六七十年代的时候,计算机刚被发明出来,底层有操作系统、文件系统、磁盘。那时大家如果想把银行转账的交易放在计算机系统里,想基于这个操作系统直接开发一个银行转账的账务系统,几乎是一个不可能完成的任务。

  Jim Gray提出了一个概念,在低层复杂的系统上构造一个事物层,通过复杂的环境抽象出一个简单的事物系统,事物系统本身保证ACID,业务系统直接针对ACID的事物系统进行操作,这样应用系统就会简化很多。

  业务逻辑简单了,但ACID又如何保证呢?

  Jim Gray写过一本书叫做《事物处理》,这本书对事物系统有很深的描述。书中有一章特别强调概率的作用,有一个结论是这样描述的: “绝对的ACID是不存在的,只是在某种概率上得到了保证。”深刻的强调了概率的重要性。

  于是我们得到了一个方法:对于特别复杂的环境,以某种概率抽象出一个简单的城市,然后假设基于这个城市去解决问题,关注的重点在于假设的环境而不是真实的环境。

  那么除了单机的抽象,分布式领域里的抽象又是什么样的呢?

  Leslie Lamport提出来一个分布式领域里的模型假设:

  1. 网络中包含多个主机

  2. 每个主机包含若干进程与磁盘

  3. 进程间通过网络包通信

  4. 网络包可能会重复,丢失,乱序,但内容不会出错

  5. 进程可能会重启

  6. 磁盘可能会损坏,导致数据丢失,但数据不会出错

  7. RTT一般在1ms之内(后加)

  基本上就是一个局域网的环境,其实近十几年来,我们做的分布式系统大部分都是基于这种假设去构建的一种“非拜占庭的环境”。

  拜占庭问题

  对于拜占庭问题,可以简单的理解为:承诺与实际表现不相符

  比如,网络包数据出错、磁盘数据出错、程序出现bug等。我们做设计的时候,如果考虑到拜占庭问题,系统将会特别复杂,几乎是不可能完成的设计。但是拜占庭问题在实际的环境中又真实存在,所以怎样去解决呢?

  基于刚才所说的概率问题,我们可以通过其他方式在一定的概率上解决拜占庭问题,但不能影响我们基于非拜占庭环境的架构设计。

  比如,网络包或者磁盘出错,我们加一些校验码,但是可能会给系统增加负担,如何去抉择还要基于实际情况,只要概率足够大满足我们的需求就足够。

  也就是我们在一个拜占庭的环境里抽象出一个非拜占庭环境,然后基于非拜占庭环境做设计。

  关于CPA的误解

  CPA理论对现在的分布式设计有很大影响,但是可能存在一些误解。

  2000年,Eric Brewer教授在UC Berkeley提出了CAP猜想:在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性)这三个基本需求,最多只能同时满足其中的2个。

  但是后续很多人对CAP猜想产生了质疑,有人认为CAP定理不正确,但也有人支持该理论,认为该理论可以解决CAP。在2002年,Eric Brewer教授再一次重新解释了CAP。

  这里存在一个很大的误解就是很多人将CAP理解成CA、AP或者CP。实际上CAP理论不是一个特别严格的理论,它只是一个工程领域对分布式系统设计思维框架的指导。大家不要把CAP理论看成一个枷锁,它不是绝对的,是有一些中间状态的。

  比如,它的可用性定义为在可接受的时间内给出反馈结果,可接受的时间就是一个很主观的概念,取决于实际场景的需要。

  对于结论,我们不需太纠结,以满足实际需求为标准。

  2.2实体场测,抽象问题模型

  回到我们最初的问题,万达在全国具有200+的实体广场,那么这200多个广场是什么样的呢?

  这是一个全国多个广场的真实测试数据,最终汇总如下:

  1. 网络中包含多个主机

  2. 每个主机包含若干进程与磁盘

  3. 进程间通过网络包通信

  4. 网络包可能会重复,丢失,乱序,但内容不会出错

  5. 进程可能会重启

  6. 磁盘可能会损坏,导致数据丢失,但数据不会出错

  7. RTT同广场1ms以下,同城10ms,跨城市几十ms

  得到的结论是同城接近局域网,跨城接近广域网,供电系统弱于专业机房,机房断电概率高于专业机房,冷却系统弱于专业机房,机器重启概率高于专业机房。

  2.3协议选型与改造1

  Paxos类协议

  一个很重要的协议就是Paxos协议,现今我们很多的强一致协议基本都是基于Paxos协议。

  多个节点如何就一个值达成一致?一个主要方式是value取得大多数acceptor的认可。

  多个节点就一个值达成一致有什么用?用处之一是多个节点选主。

  另一个用处就很重要了,它由Leslie Lamport提出。Leslie Lamport表示:假设有多台机器,每台机器里有一个顺序日志,另外有一个状态机,然后我们通过Paxos协议保证顺序日志一致。顺序日志每条条目是一个操作,把日志入到状态机里,这就是一个非常有用的模型。

  比如,状态机是一个存储引擎,那么它就是一个分布式数据库,如果我们把状态机定义成其他,那么它就是其他的一个系统。这就是所谓的Multi-Paxos。Multi-Paxos 只是一个思路,很多细节并没有完善,所以落实到实践会很难。

  2014年,斯坦福大学发布了一个Raft协议,这个协议描述的很精确,包括日志如何合并、如何入到状态机、多个日志之间如何同步等。对于实现一个真正的系统来说,Raft协议发挥了很大作用。

  我们假设采用Paxos模型(Raft模型),在北京的通州、石景山和爱琴海的三个机房里,运行一个Raft Group,还有Leader和Follower,它们的写是通过组进行的,读是任意读的。看起来似乎没有问题,但是如果这三个节点在不同的地域可能就存在问题了。比如三个节点分别在上海、北京和沈阳,数据可能会发生异地写,或者异地的日志同步,在广域网里面这种情况可能不会被接受,因为丢包率比较大、时延比较高。所以如何解决呢?

  一个方法是我们不要把Raft组里面的几个节点放到异地,保证Raft Group在一个近似局域网的环境。这样便解决了Raft Group数据同步的问题,但仍然没有完全实现本地读写。

  为了解决这个问题,我们抽样统计了用户的对某条数据的读写地点,发现99%以上的读写都发生在数据所在的同一个城市。

  基于这个假设我们便可以对这个协议进行改造。

  我们对Raft组里的每一个数据副本加一个历史访问信息,数据运行过之后,我们就能知道这个数据主要的访问点在哪,然后根据它的主要访问点把Raft Group里的副本分配到应该在的地方,这样就能够保证99%的读写都是本地的。

  方法总结:

  1. 根据历史访问规律,对数据增加归属地信息

  2. 99%以上的读写享受本地计算和本地存储的收益

  3. 对数据的读操作,提供强一致和最终一致两种接口。强一致读归属地机房,最终一致读

  本地机房。

  4. 系统统计用户的历史访问规律,对归属地信息做自适应的修改。

  优势是99%以上的读写享受本地操作待遇。劣势是受限于业务场景,不是一个“普适”的系统。也就是说它可能只是针对于线下人类活动的物理规律抽象出的一个模型,并不适合所有的场景。

  该如何解决呢?我们思考一下:

  所谓的“优化”本质上是针对特定场景下的访问规律在时间和空间两个维度做自适应和更精确的调度。目前我们能做到的是分析用户特定场景下的规律,针对这个规律做一些优化。一般的优化都要基于一个具体的场景,然后观察在时间和空间两个维度上是否能够做复用。

  最终一致类协议

  另外一种思路是Dynamo亚马逊的VectorClock。每一个点都可以读写,它读写的时候会带一个时间戳,这个时间戳可能是物理的时间戳也可能是逻辑的时间戳,在读的时候对这个时间戳做一个merge,最后取得一个最新的数据。

  详细内容大家可以参考下图片中的两个论文。这里我强调一下第二篇论文《Time Clocks and the Ordering of Events in a Distributed System》,是1978年由Leslie Lamport发表的,论文阐述了逻辑时钟的概念。

  如果我们真的可以做到在每一台机器上加一个时间戳,那么实现所有的系统都不是问题了。但是不同的机器时间是不同的,它们之间会存在误差,每台机器的时钟CPU里的时钟程序都可能会有误差。这是物理时钟存在的问题。

  待探索

  基于刚才的分析,我们是否还可以在进行一些改进呢?

  比如我们对每一条数据加入了一个历史访问信息,我们是否可以针对这些历史访问信息做一些挖掘,然后把这些数据自适应到全国的某一个广场某一台机器的某一台磁盘上去?甚至在用户去某一个广场之前,就把数据预测出来然后提前调度过去?这样天马行空的想法是否可行我们还需进一步探索。

  问题的关键点在于它不只是一个纯线上的活动,它是一个线上线下融合的系统。用户线下的物理行动是有一定规律可循的,我们可以对线下的规律进行挖掘,然后对线上的数据做一些适配。

  当然这也只是一个想法,是否可靠,尚待研究和实践检验。

  3.解决问题

  为了解决问题,我们最终的选择是Raft Group 挂Slave这种方式,针对历史信息把数据调度到合适的地方。

  但是又引发一个新的问题,实现一个生产级别的Paxos库,并不是一件容易的事。你在编码的时候会发现很多的问题,比如Paxos里的成员怎样做抽象?到底选择多线程还是多进程?用不用流水线?怎样充分利用CDO?

  好在我们国内有很多开源的实现,比如腾讯的PhxPaxos库、阿里的X-PAXOS架构等。

  系统设计与实践流程

  最后我们得到这样一个流程:

  面对一个特别复杂的软硬件环境,我们要先做测试然后建模、协议选型,如果选好的型不完全符合我们在进行改造,然后进行架构设计,最后测试、上线。

  4.经验总结

  1.理论决定上限,经验决定下限。

  2.架构师的抽象思维能力很重要。

  3.天马行空的思考,脚踏实地的实践。

  4.实践!实践!实践!

0
相关文章