PACELC 基于 CAP 理论演进而来。算法
CAP 理论是一个分布式系统中老生常谈的理论了:网络
系统设计中,这三点只能取其二,通常的分布式系统要求必须有分区容错性。剩下的只能从 C 或者 A 中取舍。异步
可是这个理论并不能很好地应用于实际,首先, A 中是有必定争议的,很长时间才返回,虽然可用,可是业务上可能不能接受。而且,系统大部分时间下,分区都是平稳运行的,并不会出错,在这种状况下,系统设计要均衡的实际上是延迟与数据一致性的问题,为了保证数据一致性,写入与读取的延迟就会增高。这就引出了 PACELC 理论。分布式
在出现分区错误的状况下,取前半部分 PAC,理论和 CAP 内容一致。没有出现分区错误的状况下(PACELC 中的 E 表明 Else),取 LC,也就是 Latency(延迟)与 Consistency(一致性)。ide
如今,其实不少存储,都已经实现了不一样的 PACELC 的兼顾策略,而且交由用户配置去灵活根据不一样业务场景使用不一样的策略。函数
例如 DynamoDB 和 Riak 还有 Cassandra 都是 Dynamo 理论论文的基于一致性哈希写多份实现最终一致性的存储,在默认状况下,是 P+A 以及 E+L 的系统,可是能够根据配置修改,主要基于NWR模型与同步和异步备份。N 表明 N 个备份,W 表明要写入至少 W 份才认为成功,R 表示至少读取 R 个备份。配置的时候要求 W+R > N。 由于 W+R > N, 因此 R > N-W。这个是什么意思呢?就是读取的份数必定要比总备份数减去确保写成功的倍数的差值要大。
也就是说,每次读取,都至少读取到一个最新的版本。从而不会读到一份旧数据。当咱们须要高可写的环境的时候(例如,amazon 的购物车的添加请求应该是永远不被拒绝的)咱们能够配置W = 1 若是N=3 那么R = 3。 这个时候只要写任何节点成功就认为成功,可是读的时候必须从全部的节点都读出数据。若是咱们要求读的高效率,咱们能够配置 W=N R=1。这个时候任何一个节点读成功就认为成功,可是写的时候必须写全部三个节点成功才认为成功。
你们注意,一个操做的耗时是几个并行操做中最慢一个的耗时。好比R=3的时候,其实是向三个节点同时发了读请求,要三个节点都返回结果才能认为成功。假设某个节点的响应很慢,它就会严重拖累一个读操做的响应速度。设计
MongoDB 和上面的 Dynamo 相似,MongoDB关于一致性、可用性的权衡,取决于三者: code
write-concern
: 表示当写请求在value个MongoDB实例处理以后才向客户端返回read-concern
: 设定是否必须从 primary 读取最新的数据仍是能够从 secondary 读取最终一致性的数据。read-preference
: 对于replica set,是返回当前节点的最新数据,仍是返回写入节点最多的数据,仍是根据一些函数计算出的数据。MySQL主从复制包括异步模式、半同步模式、全同步复制中间件
默认状况下是异步模式,MySQL 一主多从部署读写分离的状况下,实现的为最终一致性,若是考虑必定延迟能够接受,通常能够经过 show slave status
来查看主从延迟从而决定数据是否能够从 slave 读取。 MyCat 等中间件就是用了这种机制。能够经过对于这个时延的容忍性,控制 L 与 C 的取舍 以及 A 与 C 的取舍。blog
全同步复制:指当主库执行完一个事务,全部的从库都执行了该事务才返回给客户端。这样保证了强一致性,可是响应时间变长了。
半同步复制:主库在执行完客户端提交的事务后不是马上返回给客户端,而是等待至少一个从库接收到并写到 relay log 中才返回给客户端。这样虽然仍是有延迟,可是延迟小了不少而且数据相比于异步复制更加不容易丢失。
一致性协议通常包括:
每日一刷,轻松提高技术,斩获各类offer: