基于操作序列的一致性机制对分布式系统设计的意义

声明
本文为Gleasy原创文章,转载请指明引自Gleasy团队博客

保证一致性的策略
原子事务:使用ACID策略保证强一致性,这是最粗暴也是最稳妥的一致性保证手段。这是标准的CP型系统设计,牺牲可用性和性能。系统规模不能太大。
二段式提交:分布式事务的经典实现,一致性强度基本与事务持平。优点是系统规模比原子事务要大,而且适用于跨平台,跨系统。缺点同样牺牲可用性。
PAXOS:强一致性保证,2n+1个结点,只需要n+1个结点达成一致,比上面两种方法在可用性方面有大幅提升,广泛应用于NO-SQL数据库的集群(比如MongoDB)。但它仍然是CP的,因为要达成一致至少需要一半以上结点同意,同样牺牲了可用性。
BASE:可用为主,软状态(状态不用时刻一致),最终一致。以可用性为主要考虑对象的系统设计思想。数据库的主-从同步当属范畴,允许主从延迟的存在,本身就是一种软状态,但随着主从同步完成,最终状态趋于一致。

基于操作序列的一致性保证
本文想重点聊的基于操作序列的一致性方法,可以算作BASE的范畴。它是指分布式系统在写入的时候,可以更新某个结点(或者干脆不直接更新任务结点),将操作序列存放在消息队列(MQ)中。写入MQ成功,则等同于写入成功。分布式系统结点通过按顺序消费MQ来实现最终一致性。使用该机制,可以有效地保证数据写入的速度,最大可能地提供高可用高性能。

Gleasy的分布式文件系统Cloudfs和分布式索引平台CloudIndex,就是使用了这种机制。Cloudfs某个结点上传了文件,会立刻往MQ里面生成一条写入记录,其它结点会即时消费该记录,从该结点同步文件,同样,当文件被删除,也会生成一条删除记录,其它结点做相应的删除动作。CloudIndex则是更新索引时,直接写入MQ,不更新结点,所有结点都通过MQ获取索引更新或者删除的操作指令去执行相应动作。当不一致发生时,可以从问题发出前的时间点重新消费MQ来完整重现问题发生后的所有操作,从而实现数据一致性恢复。使用这一机制,保证了Cloudfs和CloudIndex的高性能(具体可以参见博客相应文章),而且数据一致性也完全处于可以接受的级别。

这种方式是万能的么
任何技术都是双刃剑,使用基于序列的方式保证一致性来换取高性能的技术,同样有其固有的限制。
首先,操作序列必须是可以重复执行的。这一点是极为重要的。如果操作序列中有类似set a=a+1,这种动作,这种机制是完全失效的。Cloudfs只有add,del两个动作;CloudIndex只有add,remove两个动作。这两个动作在保证序列的情况可,完全可以多次执行。
其次,延迟是可以接受的,或者可以规避的。使用这种机制,在某一时刻,不同结点的数据是不一致的。Cloudfs通过保证相同的文件只会去到固定结点去读取来规避这种延迟;而CloudIndex本身是允许索引延迟的。
以上两个条件,缺一不可。

结论
在设计分布式系统的过程中,由于系统特性,需求的不同,供选择的方案可以千差万别。了解一种技术,最重要是了解技术背后的弱点的限制。没有最好的技术,只有最适合的技术。

此条目发表在 Java技术, 分布式技术, 数据库技术, 运维 分类目录。将固定链接加入收藏夹。

基于操作序列的一致性机制对分布式系统设计的意义》有 1 条评论

  1. Pingback 引用通告: Cloudfs一致性问题分析及解决 | Gleasy团队博客

发表评论