追求可用性

常青笔记

  • BASE 是对 CAP 中一致性和可用性权衡的结果。更强调追求可用性。核心思想是,即使无法做到强一致性,但每个系统都可以根据自身的业务 特点,采用适当的方式来使系统达到**最终一致性**
  • 基本可用,即指可以允许损失部分可用性。常见的服务质量下降有两种类型。响应时间的损失和功能的损失(服务降级)。又可以从其他角度分为流量削峰延迟响应体验降级过载保护
  • ACID 理论是传统数据库常用的设计理念,追求强一致性模型。BASE 理论支持的是大型分布式系统,通过牺牲强一致性获得高可用性。BASE 理论在很大程度上,解决了事务型系统在性能、容错、可用性等方面痛点。BASE 理论在 NoSQL 中应用广泛,是 NoSQL 系统设计的事实上的理论支撑。

概念

BASE 理论是 CAP 理论中的 AP 的延伸,是对互联网大规模分布式系统的实践总结,强调可用性

它的核心就是基本可用(Basically Available)和最终一致性(Eventually consistent)。也有人会提到软状态(Soft state),在我看来,软状态描述的是实现服务可用性的时候系统数据的一种过渡状态,也就是说不同节点间,数据副本存在短暂的不一致。你只需要知道软状态是一种过渡状态就可以了。 BASE 是 Basically Available(基本可用)、Soft state(软状态,即可以是中间态,不影响系统的过渡态)和 Eventually consistent(最终一致性)三个短语的简写,BASE 是对 CAP 中一致性和可用性权衡的结果,其来源于对大 规模互联网系统分布式实践的结论,是基于 CAP 定理逐步演化而来的。

BASE 理论的核心思想是:即使无法做到强一致性,但每个系统都可以根据自身的业务 特点,采用适当的方式来使系统达到最终一致性

  1. 基本可用. 基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性。即允许服 务质量下降。常见的服务质量下降有两种类型:
  • 响应时间的损失
  • 功能的损失(服务降级)
  1. 软状态。 软状态,是指允许系统数据存在的中间状态,并认为该中间状态的存在不会影响系统的 整体可用性,即允许系统主机间进行数据同步的过程存在一定延时。软状态,其实就是一种 灰度状态,过渡状态。
  2. 最终一致性 最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到 一个一致的状态。

一致性的数据,以什么为准?

你首先要知道它以什么为准,因为这是实现最终一致性的关键。一般来说,在实际工程实践中有这样几种方式:

  • 以最新写入的数据为准,比如 AP 模型的 KV 存储采用的就是这种方式;
  • 以第一次写入的数据为准,如果你不希望存储的数据被更改,可以以它为准。

一致性的具体方式

那实现最终一致性的具体方式是什么呢?常用的有这样几种。

  • 读时修复:在读取数据时,检测数据的不一致,进行修复。比如 Cassandra 的 Read Repair 实现,具体来说,在向 Cassandra 系统查询数据的时候,如果检测到不同节点的副本数据不一致,系统就自动修复数据。
  • 写时修复:在写入数据,检测数据的不一致时,进行修复。比如 Cassandra 的 Hinted Handoff 实现。具体来说,Cassandra 集群的节点之间远程写数据的时候,如果写失败就将数据缓存下来,然后定时重传,修复数据的不一致性。
  • 异步修复:这个是最常用的方式,通过定时对账检测副本数据的一致性,并修复

如何应用?

我们可以通过写时修复和异步修复实现最终一致性。另外,还实现自定义写一致性级别,支持 All、Quorum、One、Any 4 种写一致性级别,用户在写数据的时候,可以根据业务数据的特点,设置不同的写一致性级别

Base理论

解决方案

本地消息表⭐ (基于 MQ 的可靠消息投递方案,最常用,最终一致性)

MQ

基于 MQ 的可靠消息投递的方案不仅可以解决由于业务流程的同步执行而造成的阻塞问题,还可以实现业务解耦合流量削峰。生产者需要额外创建消息表,还需要对本地消息表进行轮询,业务负担较重

  1. MQ 手动应答机制处理消息丢失

  2. 双向消息确认机制,解决高并发场景下的消息积压导致消息丢失

    1. 生产者,本地持久化消息,状态为待发送
    2. 生产者,发送到mq,消息状态为 已发送
    3. 消费者,消费消息,并回复给生产者,消息状态为 已完成 这样,即使最终 MQ 出现了消息丢失,也可以查询数据库,补偿重发

http://image.clickear.top/20220119121624.png

容错机制:

  • 扣减余额事务 失败时,事务直接回滚,无后续步骤
  • 轮序生产消息失败, 增加余额事务失败都会进行重试

本地消息表的特点:

  • 长事务仅需要分拆成多个任务,使用简单
  • 生产者需要额外的创建消息表
  • 每个本地消息表都需要进行轮询
  • 消费者的逻辑如果无法通过重试成功,那么还需要更多的机制,来回滚操作

适用于可异步执行的业务,且后续操作无需回滚的业务。

最大努力通知(适用于微信交易通知等)

可靠消息一致性,发起通知方需要保证将消息发出去,并且将消息发到接收通知方,消息的可靠性关键由发起通知方来保证。

最大努力通知,发起通知方尽最大的努力将业务处理结果通知为接收通知方,但是可能消息接收不到,此时需要接收通知方主动调用发起通知方的接口查询业务处理结果,通知的可靠性关键在接收通知方。

解决方案上,最大努力通知需要:

  • 提供接口,让接受通知放能够通过接口查询业务处理结果
  • 消息队列ACK机制,消息队列按照间隔1min、5min、10min、30min、1h、2h、5h、10h的方式,逐步拉大通知间隔 ,直到达到通知要求的时间窗口上限。之后不再通知

最大努力通知适用于业务通知类型,例如微信交易的结果,就是通过最大努力通知方式通知各个商户,既有回调通知,也有交易查询接口。