天天看点

PacifiaA读书笔记

PacificA是微软研究院搞出的一个一致性协议,kafka据说受此启发,本文算是这篇文章的读书笔记吧。

架构

PacificA作为一个一致性协议,与传统的一致性(paxos, raft)等不同的在于,它关注的是一个基于日志的存储系统的一致性,与paxos只关注于对某一个值达成一致的协议不同。在PacificA中的机器有2个角色:Configuration Manager, Data Server。在PacificA中,数据存在Data Server里,逻辑上来讲是存在一个个replication group里。每个Data Server可以有多个replication group,在每个replication group里有1个leader和多个slave,他们分散在不同的data server里。这个Data Server只负责存储数据及其复制,而每个replication group的leader的选举则交给configuration manager负责。

数据的复制

每个replication group里的leader会处理update和read请求,并将update请求转化为日志发送给slave。与paxos不同的是,pacifica要求日志在被所有的slave写入到本地才算一次commit。那么如果有节点发生partion或者挂掉了怎么办?这里我们使用一个例子来说明pacifica的安全性。

我们假设一个replication group里有A, B, C三个节点,其中A是version=1的时候的leader。pacifica中使用lease机制来进行failure detection。当C发生partition时,A会向Configuration Manager发送请求来修改这个replication group的配置为A, B,版本为2;C也会同时发送请求修改这个replication group的配置为C,版本为2。不管这2个请求哪一个先到,Configuration manager只会批准一个,拒绝另外一个。这个任意一个时刻仍然每个replication group仍然只有一个leader,所以写入仍然是安全的。这个我们假设A的配置修改成功,那么C应该如何处理呢?原文对这种情况没有细讲,这个应该是由实现决定,比如说C可以尝试一定时间加入到原group里去,如果仍然失败则自动退出等。

安全性的另外一个保证是只要replication group里至少有一个节点存活,commit过的消息一定可以保留。这个是由同步算法保证的,也就是说当新的leader选举出来之后,最先做的事情就是让所有的slave同步leader自己的本地日志,而这个一定包含已经commit过的日志,因此很好理解。

一些优化

  1. 通常来说基于日志复制的系统会在本地维护一个状态机并定时做checkpoint从而可以truncate比较老的日志。而更新状态机的状态是需要消耗cpu和内存的,因此一个优化就是在slave中不维护状态机,而是只接受日志,并且定时接受checkpoint。
  2. 将多个逻辑日志合并为一个物理日志文件,从而减少文件数量,减少磁盘随机读写
  3. 可以像bigtable那样将日志存储到共享文件系统里去,这样的好处是简化系统逻辑,但是带来的坏处是复杂化了系统恢复的逻辑,因为当某台机器挂掉,这台机器上的多个replication group会分散到不同的机器上,如果采用了2的优化策略,会导致多台机器读同一份日志。

继续阅读