什么是分布式系统中的一致性?

什么是一致性?

在分布式系统中,一致性指的是多个节点之间数据的一致性。具体而言,如果一个节点对数据进行了更新操作,那么其他节点也必须更新相应的数据,从而保持整个系统的数据一致性。

例如,在一个分布式数据库系统中,如果用户在节点 A 上更新了数据表中的一条记录,那么该更新操作必须同步到其他节点(如节点 B 和节点 C)上。否则,当用户在节点 B 或节点 C 上查询该记录时,可能会出现数据不一致的情况。

事务一致性本质

看了不少一致性解决方案,不知道有没有发现一些规律?

核心组件基本一致:

  1. 应用程序:简单理解为开发的应用系统,借助事务管理器和资源管理的的能力,完成事务一致性保障;

  2. 事务管理器:事务的协调者,接收应用程序的请求,对多个资源管理器进行协调,共同完成正向补偿和逆向补偿;

  3. 资源管理器:单一资源管理者,对外提供正向补偿接口和逆向补充接口,供应用程序和事务管理器使用;

核心流程基本一致:

  1. 正向补偿:应用流程向前推进,最终从一个状态变化为另一个状态;

  2. 逆向补偿:应用流程向后推进,将所有操作进行回滚,使其恢复到前一状态;

简单来说:事务一致性就是通过协调各个参与节点来实现分布式事务的提交或回滚,确保所有涉及到的操作,要么全部执行成功,要么全部不执行。不同的实现方式只是不同的工具,其实现思路基本一致。

实现一致性的方法

在分布式系统中,为了实现一致性,通常有以下几种方法:

1. 强一致性

强一致性指的是所有节点之间的数据是强一致的,即任何时候任何节点对数据的更新都能立即同步到所有其他节点上。这种方式可以确保系统的数据一致性,但同时也会带来较高的延迟和网络开销。

2. 弱一致性

弱一致性指的是所有节点之间的数据是弱一致的,即任何时候节点之间的数据可能存在短暂的不一致情况。这种方式可以减少网络开销和延迟,但同时也会带来数据不一致的风险。

3. 最终一致性

最终一致性指的是所有节点之间的数据是最终一致的,即经过一段时间后,所有节点之间的数据会达到一致状态。这种方式可以在保证系统性能的同时,尽可能地减少数据不一致的风险。

一致性协议和算法 

在实现分布式系统中的一致性时,常用的协议和算法有以下几种:

1. Paxos 协议

Paxos 是一种著名的分布式一致性协议,由 Leslie Lamport 在 1990 年提出。该协议主要用于解决分布式系统中的一致性问题,已被广泛应用于分布式数据库、分布式文件系统等领域。

Paxos 协议的工作原理比较复杂,需要通过多轮投票来选举 Leader,并确保 Leader 能够提交正确的更新操作。由于其实现较为繁琐,因此通常使用一些基于 Paxos 的库或框架,如 ZooKeeper、etcd 等。

2. Raft 协议

Raft 是一种相对较新的分布式一致性协议,由 Diego Ongaro 和 John Ousterhout 在 2014 年提出。该协议与 Paxos 类似,但更具可读性和可理解性,因此在工程实践中得到了广泛应用。

Raft 协议通过 Leader 选举、心跳机制和日志复制等方式来维护数据一致性。与 Paxos 相比,Raft 更加容易理解和实现,因此在很多分布式系统中都得到了广泛应用。

3. Gossip 协议

Gossip 协议是一种基于疫情传播理论的分布式一致性算法,由 David Kempe 和 Maarten Van Steen 在 2002 年提出。该算法主要用于解决大规模分布式系统中的数据同步问题。

Gossip 协议的工作原理比较简单,每个节点随机选择一些其他节点进行通信,并将本地数据同步到对方节点上。这样,通过节点之间的“疯传”操作,最终可以达到全局数据一致的状态。

由于 Gossip 协议具有良好的可扩展性和容错性,因此在很多大规模分布式系统中都得到了广泛应用,如 Amazon Dynamo、Apache Cassandra 等。

一致性保证

大部分多副本数据库(replicated databases)提供最终一致性(eventually consistency)的保证,这意味着,只要你对数据库停写,并等待足够长的时间,则所有对相同数据的读取请求最终会返回相同的结果。从另一个角度来说,所有的不一致都是暂时的,最终都会被解决(当然,这得是在网络故障能最终修复的假设之下)。描述相同意思的一个更好的名字可能:收敛性(convergence),即最终,所有副本都会收敛到相同的值。

但这是一个相当不靠谱的保证——没有提供任何关于何时收敛的信息。而在收敛之前,对于相同数据的读取,可能会返回任意值甚至不返回。举个例子,你向多副本数据库中写入了一条数据,并立即读取他。你能读到什么,最终一致性对此不会提供任何保证,因为读取请求可能会被路由到任何其他副本。

最终一致性对于应用层开发者很不友好,因为它表现出的行为和单线程程序中的变量完全不一致。在单线程模型里,如果对某个变量赋值后立即读取,我们默认一定会读到刚才的赋值,而不是读到旧值或者读取失败。数据库在对外表现上很像一组可读写的变量集,但具有复杂得多的语义。

在使用只提供弱保证的数据库时,我们需要时刻记得其限制,而不能偶尔自己增加额外假设,否则,会产生非常致命且难以察觉的 BUG。因为大部分时间里,应用层表现得毫无波澜,只有在系统中出现故障(网络拥塞、节点宕机)或在高负载场景下,这些边缘情况才会被触发。

本章我们会一起探究一些更强的一致性模型,但选择这些模型是有代价的。相对弱一致性模型系统来说,这么做要么会牺牲性能,要么会牺牲可用性。但提供强保证会让应用层能更加容易、正确的使用。但当然,我们最终还是得根据具体场景,来选择使用何等强度一致性模型。

在实践中,我们常会使用分层策略,让某些底层解决可用性、性能和容量的问题,让上层解决一致性的问题。比如云上各种基于 aws s3 的关系型数据库。另外,也有些系统会同时提供多种一致性模型供用户选择,在一致性和性能间进行取舍。

分布式系统中的一致性模型的强弱和第七章讲的事物的隔离级别层次有一些共通之处,比如在性能和隔离性/一致性间做取舍。但他们是相对独立的抽象:

  1. 事务隔离级别是为了解决并发所引起的竞态条件

  2. 分布式一致性是处理由于多副本间延迟和故障所引入的数据同步问题

总结

在分布式系统中实现一致性是一个非常重要的问题,涉及到多个节点之间的通信和数据同步。本文介绍了一致性的定义、实现方法和常见协议和算法,希望能够帮助读者更好地理解和应用分布式系统中的一致性问题。 

  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值