在计算机科学领域,分布式一致性是一个相当重要且被广泛探索与论证的问题,首先来看三种业务场景。
(1)火车站售票。一位旅客去车站的售票处购买车票,如果他选择的目的地是杭州,而某一趟开往杭州的火车只剩下最后一张车票,会出现这样的情况:同一时刻,不同售票窗口的另一位乘客也购买了同一张车票。若售票系统没有进行一致性保障,两人都购票成功了,而在检票口检票的时候,其中一位乘客会被告知他的车票无效。从这个例子中我们可以看出,终端用户对购票系统提出了严格的一致性要求,系统的数据无论在哪个售票窗口,每时每刻都必须是准确无误的。
(2)银行转账。当客户在银行柜台完成转账操作后,转账金额一般会在 N 个工作日后到账,即使转账时间延迟,客户也需要转账金额准确到账,这成了所有用户对于现代银行系统最基本的需求。
(3)网上购物。当客户看见一件库存量为5的心仪商品时,会迅速确认购买,写下收货地址,然后下单,但在下单的一瞬间,系统可能会告知该客户:“库存量不足”。因为在商品详情页上显示的库存量通常不是该商品的真实库存量,只有在真正下单购买的时候,系统才会检查该商品的真实库存量。
对于上面三个例子,终端用户在使用不同的计算机产品时对数据一致性的需求是不一样的。有些系统既要快速响应用户,同时还要保证系统的数据对任意客户端都是真实可靠的,例如火车站售票系统;有些系统需要为用户保证绝对可靠的数据安全,虽然在操作上存在延时,但最终必须保证严格的数据一致性,例如银行的转账系统;有些系统虽然向用户展示了一些可以说是“错误”的数据,但是在系统使用过程中,一定会在某一个流程对系统数据进行准确无误检查,从而避免用户发生不必要的损失。
在分布式系统中要解决的一个重要问题就是数据的复制。在日常开发中,很多开发人员都遇到过这样的问题:假设客户端 C 1将系统中的一个值 K 由 V 1更新为 V 2,但客户端 C 2无法立即读取到 K 的最新值,需要在一段时间之后才能读取到,这是由于数据库复制存在延时。
分布式系统对数据的复制需求一般都来自以下两个原因:一是为了增加系统的可用性,以防止单点故障引起的系统不可用;二是提高系统的整体性能,通过负载均衡技术,让分布在不同地方的数据副本都能够为用户提供服务。数据复制在可用性和性能方面给分布式系统带来了巨大的好处,但数据复制所带来的一致性挑战也是每一个系统研发人员不得不面对的。
分布一致性问题是指在分布式环境中引入数据复制机制之后,不同数据节点之间可能出现且无法依靠计算机应用程序自身解决的数据不一致的情况。简单来讲,数据一致性就是指在对一个数据副本进行更新的时候,必须确保能够更新其他的副本,否则不同副本之间的数据将不一致。
因此,如何在保证数据一致性的同时不影响系统运行的性能,是每一个分布式系统都需要重点考虑和权衡的问题。为了解决这一问题,一致性级别由此诞生。
● 强一致性:这种一致性级别是最符合用户直觉的,它要求系统写入与读出的内容必须一致。在强一致性情况下,用户体验好,但实现起来往往对系统的性能有较大影响。
● 弱一致性:这种一致性级别约束了系统在写入成功后,不承诺立即可以读到写入的值,也不承诺多久之后数据能够达到一致,但会尽可能地保证到某个时间级别(比如毫秒级别)后,数据能够达到一致状态。
● 最终一致性:它是弱一致性的一个特例,系统会保证在一定时间内能够达到数据一致状态。它是弱一致性中非常流行的一种一致性模型,也是业界在大型分布式系统的数据一致性上比较常用的模型。