Pacifica 是微软 2008 年发表的一个通用的复制框架,早于 raft(2014),其具有简单、实用和强一致(strong consistency)的特点。Pacifica 的出现主要就是为了解决一致性复制协议(Paxos)理论和工程实践之间的 gap,也就是基于 Paxos 的一致性复制协议难以被正确实现的问题。Pacifica 通过将数据复制和配置管理(配置管理通常是用 Paxos 实现)分离解耦开来,因为当前已经有一些配置管理服务的解决方案(例如 zookeepr ,chubby等,现在有 etcd 等),它们经过了大量的线上环境的测试,能够保证较好的正确性,从使得系统只需要关系数据一致性复制部分,大大简化了设计的复杂性,有利于快速和正确的构建分布式存储系统。
首先来整体的看看 Pacifica 的核心特性,后面再详细描述和体会:
国内小米的开源分布式 key-value pegasus 也是基于 Pacifica 构建。
Pacifica 的基本框架主要有两部分组成:
负责管理复制组成员的信息,Primary/backup 信息,以及复制组配置 version,数据分片的位置信息
负责多副本数据的一致性复制
首先来看看存储集群的数据复制,相区别其它 quorum 机制,Pacifica 要求实现强一致的数据复制,也就是必须保证 Primary 上的数据复制给所有的 secondary 节点,才能返回给 client 端,这样可能会担心异常情况下 write 的 latency 会增加,但是在局域网中(非异地跨数据中心环境下)Primary 和 Secondary 之间的 latency 会比较稳定,而且作者也在论文指出了:
we focus our attention on a local-area network based cluster environment
既然是 Primary/Secondary 复制,那么所有的 query/update(也就是 read/write) 都被发送给 Primary,query 简单,直接返回即可,update 则需要通过 Log Replication 将数据复制给所有的 Secondary,保证数据的可靠性。
下面我们来详细看下详细的 Log Replication 流程:
Notes
对于 Pacifica 来说,其通过 Primary 实现对所有的 Op 定序,实现的是强一致复制,实际上这里的”强一致“有两重意思:
强一致的第 2 点也是由好处的,会让错误处理更加的容易,例如 Primary 挂掉之后,任意一个 Secondary 都可以成为 Leader,那么就可以不用选举,或者选举非常简单。
类似 GFS 的 Leader 保持,也是通过 Lease 机制来实现,但是略有不同,Pacifica 的心跳方向是:Primary -> Secondary,相比 GFS 从 Master 续租,这种复制组内部维持 Lease(decentralized implementation eliminates loads and dependencies on a centralized entity),可以减小 Leader 的压力,而且在一定程度上可以缩短租约的有效期,从而提高可用性。
grace_period > lease_period > beacon_interval * 2
其中 beacon_interval 就是 heartbeat,其中,grace_period:Secondary timeout > lease_period:Primary timeout,可以保证 Primary 总会先于 Secondary timeout
一旦通过上面的Failure Detection 发现了错误,就会触发 Configuration change(配置变更),确保存储集群恢复服务,保证可用性。
因为是强一致,一旦一个 Secondary 不在,那么复制就没有办法继续了。所以 Primary 需要剔除 Secondary。但是这里需要注意的,一旦 Primary 发现 Secondary 不在了,也就是自己的租约的过期了。这里是因为 Primary 的租约是由所有 Secondaries 来保证,租约过期了,自然必须停止服务,否则就可能产生双主,例如步骤 3 Primary 发送给配置管理服务的配置变更消息由于网路延迟的原因,落后于 Secondary 发送配置变更信息给配置管理服务,那么将会出现双主。实际上这种情况会有两种可能性:
实际上第 4 就是通过配置管理服务实现 Primary 续租,所以又可以开始提供服务了.
实际上 Recovery 一般就是通过(3)新增 Secondary 来实现的
Notes
配置变更每次都会携带上配置的版本号到配置管理服务,如果版本号小于配置管理服务上面的配置版本,那么自己配置变更就会失败,仅仅学习配置管理服务上面的最新配置
在 Change of Primary 的时候,会执行一次 Reconciliation process,来保持 Primary/Secondary 数据的一致,大致的过程是 Primary 将自己的 prepare list 上 uncommited 的 request 通过 prepare message 发送从节点,直到这些 request 全部提交,其中落后的补齐,领先的截断,保证 Primary-secondary 的数据一致。下图给出一个例子:

实际上这里和 Raft 类似,因为 new Primary (Leader) 并不知道当前的 commit point 在哪里,所以需要将当前的 prepare list 上的所有 Op log entry 都提交掉,保证不会丢数据,也保证了不会出现类似 raft 的 stale read,这里其实有两个目的:
Pacifica 通过 Addition of New Secondaries ,然后再通过 Removal of Secondaries 删除下线从节点,来实现下线节点的数据 recovery。实际上还可以通过 window azure storage 的 new-seal 的方式新开复制组,但是在 window azure storage stream layer append-only 的场景下,new-seal 相对处理起来简单,对于一些随机 read/write 的场景 new-seal 相对复杂,因为还涉及到 read 的 merge,和后期复制组的 merge,逻辑上复杂很多,但是对于解决由于慢盘、节点下线等造成系统的抖动效果会比较好。

论文在最后还给出了基于 Log-based storage system 的体系结构,以及如何基于这种架构来实现数据一致性复制,一共有三种解决方案:
[1]. PacificA: Replication in Log-Based Distributed Storage Systems. https://www.microsoft.com/en-us/research/wp-content/uploads/2008/02/tr-2008-25.pdf
[2]. PacificA:微软设计的分布式存储框架. https://zhuanlan.zhihu.com/p/27582424
[3]. Calder B, Wang J, Ogus A, et al. Windows Azure Storage: a highly available cloud storage service with strong consistency[C]//Proceedings of the Twenty-Third ACM Symposium on Operating Systems Principles. ACM, 2011: 143-157.
[4]. 一致性协议中的“幽灵复现”. https://zhuanlan.zhihu.com/p/47025699.
原文作者:;如有侵权,请联系管理员删除。