在多IDC的环境下,一个很现实的问题就是如何进行数据同步,如何保证数据的完整性?
分布式存储业界已经有很多经验,甚至有了理论依据来描述这些问题。通过对分布式存储相关理论,算法,方案进行了一段时间的浅尝辄止的研究,对整体概念有了一个初步的认识,梳理出来记录下来形成此文。
本文试图从实际角度出发,对分布式存储的算法,理论进行一些简单的介绍,并根据现实的需求最终选择其中一种作为将来演进系统依赖的方案。
CAP理论
提到分布式系统,不得不提到CAP理论,这是由Eric A. Brewer 在2000年提出的猜想,由Gilbert and Lynch在2003年证明。
Brewer认为在设计一个大规模可扩放的网络服务时候会遇到三个特性:一致性 、可用性、分区容错都需要的情景,然而这是不可能都实现的。只能在以下三者其中选择两者:
- 数据一致性(Consistency),等同于所有节点访问同一份最新的数据副本
- 对数据更新具备高可用性(Availability)
- 能容忍网络分区(Partition tolerance)
对三种特性的解释
举例来说:系统有两个节点N1,N2,客户A连接了N1节点操作了某条数据X1 加一使之变为X2, 客户B连接到N2节点需要读取X的最新数据。
C+A
放弃了P ,意味着没有网络分区,意味着N1,N2必须合并到一个节点,这就相当于回到传统的单点数据库系统,由数据库保证事务的正确性
C+P
放弃了A,意味着当分区发生时,用户无法进行操作,必须等待N1,N2节点的数据完全同步完成,才可继续操作。这一点可以以银行跨行转账系统举例,当网络断开的时候,会直接告诉客户,服务不可用
A+P
放弃了C, 意味着当客户读取数据时,没有读到X的最新数据。
以Mysql的replication为例,在MS结构中,节点M和节点S,都可以对外提供服务,当其中的一个节点故障,另一个节点仍然能够对外提供服务,所以MS方案认为是满足Availability的;目前MS结构仍然是异步的方式运行,即当主库写入时,备库未必一定也写入了,备库甚至允许短暂和主库断开连接,而且当主库处理请求时,也无需确认备库的状态,所以MS结构是满足Partition tolerance的;但是由于MS结构的异步特性,我们看到主备的数据是可能不一致的,即不满足Consistency。
如果MySQL使用DRBD(严格模式) 做HA方案,则实现了Consistency,就失去了Partition tolerance。
ACID和BASE理论
传统关系型数据库系统的事务都有ACID的属性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。英文为:
- Atomic: Everything in a transaction succeeds or the entire transaction is rolled back.
- Consistent: A transaction cannot leave the database in an inconsistent state.
- Isolated: Transactions cannot interfere with each other.
- Durable: Completed transactions persist, even when servers restart etc.
中译为:
- 原子性: 整个事务中的所有操作要么成功,要么失败导致回滚。
- 一致性: 在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
- 隔离性: 两个事务的执行是互不干扰的。
- 持久性: 在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中。
BASE理论:
- Basic Availability:基本可用
- Soft-state :软状态/柔性事务,可以理解为”无连接”的, 而 “Hard state” 是”面向连接”的
- Eventual consistency:最终一致性,最终整个系统(时间和系统的要求有关)看到的数据是一致的。
在BASE中,强调可用性的同时,引入了最终一致性这个概念,不像ACID,并不需要每个事务都是一致的,只需要整个系统经过一定时间后最终达到是一致的。以用户头像为例,首先要保证A,B用户都能获得正常服务,都能得到头像,即使是过时的。但是一定时间之后,最终新头像会在N1,N2两个结点之间保证同步。
从理论上说,BASE与ACID是一定程度对立的,ACID强调CAP中的C,BASE强调CAP中的A。
字面上BASE是碱,ACID是酸,恰恰也是对立。
一致性几种算法和实现
PAXOS
分布式系统中的节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。基于消息传递通信模型的分布式系统,不可避免的会发生以下错误:进程可能会慢、垮、重启,消息可能会延迟、丢失、重复,在基础 Paxos 场景中,先不考虑可能出现消息篡改即拜占庭错误的情况。Paxos 算法解决的问题是在一个可能发生上述异常的分布式系统中如何就某个值达成一致,保证不论发生以上任何异常,都不会破坏决议的一致性。
paxos选择了CAP理论中的”Consistency, Partition”, 需要牺牲availability。它可以在多个IDC之间实现强一致性复制。
Paxos缺点
- IDC之间需要高速稳定网络
- 一个2f+1个节点的网络中,需要f+1个节点完成事务才能成功。
- Throughput低,不适合高请求量的场合。所以大部分分布式存储产品并不直接使用Paxos算法来同步数据。
严格说来Dynamo并不仅仅是算法,而是Amazon的 的高可用性的键-值存储系统
Dynamo的一个node中的同步是由client端来“解决”的,使用所谓的(N, R, W)模型,其中,N表示node中机器的总数,R表示一个读请求需要的机器参与总数,W代表一个写请求需要的机器参与总数,这些值由client端配置。
由于CAP三者无法同时满足,Amazon Dynamo论文中引入了用户可配置的NWR策略,在CAP三个特性中作出权衡。例如,一个node有5台机器(N=5),client发出写请求——广播到5台机,如果收到3个“写完成”的返回消息,即认为写成功(W=3);client发出读请求——还是广播到5台机,如果收到2个“读完成”的返回消息,即认为读成功(R=2)。对于数据十分重要的应用(如金融),配置可以为(5, 5, 5)此时强调一致性,即要求node中所有机器的写都成功;而对于数据读写访问量极高的应用,配置可以为(5, 1, 1)此时强调可用性。
Yahoo PNUTS
PNUTS模式是目前最看好的多IDC数据同步方式。它的算法大部分是为多IDC设计。
PNUTS主要为Web应用设计,而不是离线数据分析(相比于Hadoop/HBase)。
- Yahoo!的数据基本都是用户相关数据,典型的以用户的username为key的key value数据。
- 统计数据访问的特征发现85%的用户修改数据经常来源自相同的IDC。
根据以上的数据特征,Yahoo!的PNUTS实现算法是
- 记录级别的master, 每一条记录选择一个IDC作为master,所有修改都需要通过master进行。即使同一个表(tablet)中不同的记录master不同。
- master上的数据通过Yahoo! Message Broker(YMB)异步消息将数据复制到其他IDC。
- master选择具有灵活的策略,可以根据最新修改的来源动态变更master IDC, 比如一个IDC收到用户修改请求,但是master不在本地需要转发到远程master修改,当远程修改超过3次则将本地的IDC设成master。
- 每条记录每次修改都有一个版本号(per-record timeline consisitency),master及YMB可以保证复制时候的顺序。
Yahoo!的PNUTS实际可理解为master-master模式。
一致性:由于记录都需通过master修改,master再复制到其他IDC, 因此可达到所有IDC数据具有最终一致性。
可用性:
- 由于所有IDC都有每条记录的本地数据,应用可以根据策略返回本地cache或最新版本。
- 本地修改只要commit到YMB即可认为修改成功。
- 任一IDC发生故障不影响访问。
初步结论:
数据库理论之ACID和BASE的比较
http://www.sigma.me/2011/06/17/database-acid-and-base.html
The CAP-Theorem & Yahoo’s PNUTS
http://www.math.hu-berlin.de/~muellste/CAP-PNUTS-Text.pdf
多IDC的数据分布设计(=)
http://timyang.net/data/multi-idc-design/
CAP理论十二年回顾:"规则"变了
http://www.infoq.com/cn/articles/cap-twelve-years-later-how-the-rules-have-changed
Brewer's CAP理论
http://code.alibabatech.com/blog/dev_related_728/brewers-cap-theorem.html
Trying to understand CAP
http://www.warski.org/blog/2011/07/trying-to-understand-cap/