FuzzyLog:偏序关系 shared log 系统

摘要

本文摘自 Joshua Lockerman等人发表的论文 The FuzzyLog: A Partially Ordered Shared LogThe FuzzyLog 一文介绍了名为 FuzzyLog 的 shared log 设计。

问题

大规模系统往往依赖于控制服务(如文件系统中的 namenode)。这类服务从单节点走向分布式时,要想保持服务的持久性、高可用和可扩展性会带来新挑战。传统的做法是依赖于分布式协议,如 Paxos 或两阶段提交(2PC)。基于共享日志抽象(shared log abstraction)的设计是一种新思路。

采取这种设计思路的有zlog, Sirius, Chariots。但目前基于 shared log 设计的系统要求维护系统全局全序,这个要求开销昂贵、难于达成,在某种意义上来说没有必要。基于此,Lockerman 等人设计了 FuzzyLog,它只需要维护日志的偏序关系。在抽象上,它是一个有向无环图(DAG),节点表示日志,一条从 A 到 B 的边表示 A 必须在 B 之后执行。

名词解析

  • 全序: 简单来说,如果一个集合中任意一对元素都可以互相比较,那么这个集合满足全序关系,一个简单的例子就是实数轴,实数轴上任意两个实数都是可以比较的。参考全序关系

  • 偏序: 相比全序关系,偏序全系不要求完全性条件(即 a≤b 或 b≤a 至少成立一个)。严格的偏序关系与有向无环图直接对应。考虑一个简单的例子:AlphaGo 打败了李世石,也打败了柯洁,可以知道 AlphaGo 比李世石强,也比柯洁强,但是在李世石和柯洁直接较量之前,我们并不知道李世石与柯洁孰强孰弱(当然他们两个较量过)。参考偏序关系

思路

shared log 的思路很简单:每次状态转换就是提交一条新日志。只要维持日志的一致性,集群就能维持一致性,即使有节点崩溃,只要按照顺序重新执行一次日志即可。

对全序 shared log 的批评主要有两点:

  • 开销高。通过选主确定全序的方法中,往往需要主节点,这使得系统的性能受限于单节点的 I/O。CORFU 选择了旁路序列器代替主节点,这带来了网络 I/O 开销。随着集群规模的增大,旁路序列器消耗的资源增长得非常快。

  • 全序是无法完全保证的:任何保证线性有序的协议都无法在网络分裂的情况下保证可用性(参考Towards robust distributed systems)。

为此,FuzzyLog 希望通过放松对全序性的要求,改进 shared log 的设计。

FuzzyLog 设计

设计思路

FuzzyLog 是一类有向无环图。多个客户端可以并发地构建或遍历它。FuzzyLog 中的每个节点都带有自己的颜色链。每一种“颜色”都是各自区域中的全序集,每个颜色链与别的区通过交叉边构成有向无环图保持。每个区拥有自己最新的更新,其他区全部但是可能比较旧的颜色链,客户端只与本区的颜色链交互。

FuzzLog设计原理图

API

// 创建新节点,并提供一个新颜色
FL_ptr new instance(colorID color , snapID snap=NULL)
// 将节点加入一条颜色链中
int append(FL ptr handle, char *buf, size t bufsize ,colorset *nodecolors)
// 客户端用于同步节点状态,取出颜色链的快照,并按照DAG的顺序排列节点
// 注意,其他链中没有根据交叉边确定偏序关系的节点会以任意顺序排列
snapId sync(FL ptr handle, void (* callback ) (char *buf, size t bufsize ) ) ;
// 修剪颜色链
int trim(FL ptr handle, snapID snap);

FuzzyLog 的 API 设计相当简单,这是 shared log 设计中的优点。不同区对同一颜色链的操作是因果一致的(causally consistent),考虑两个不同的区域两个不同的节点 A 和 B 操作同一颜色链,它们的操作只有在 A 和 B 互相知道对方操作的情况下才是有序的。有向无环图的性质确保并发更新不会导致颜色链分裂。

其他情况下,客户端只会修改自己区域跟其他区域不相交的部分,所以不会有冲突。此外,同一个区中的操作都是可序列化的(serializable)。

相关研究与总结

如何确保分布式系统中的更新有序,资料来自于诸如 状态机复制, Multi-Paxosraft。这些工作相当成熟(按:并且有成熟的工业实现),它们当中大部分在更新时要求维持全局全序关系。与此相比,FuzzyLog 将全序条件松弛为偏序条件, 改进了 shared log 设计,提高了控制服务的可扩展性。目前,已经有一个基于FuzzyLog 的实现 Dapple。

更多相关内容,可以关注滴滴云技术团队的持续更新。

本文作者:张晔

猜你喜欢

转载自blog.csdn.net/java060515/article/details/83995514