首页 > 数据库 > 数据库开发技术 > 业务定制型异地多活架构设计
异地多活本质上是CAP理论中的AP方案。

在异地多活方案中,系统选择了可用性(Availability)和分区容错性(Partition tolerance),这意味着系统会尽可能保持对外提供服务,即使在网络分区的情况下也会保持可用。这通常意味着系统会牺牲一致性(Consistency),即在不同数据副本之间可能会存在一定程度的数据不一致性,但系统仍然可以继续提供服务。
大道至简:CAP
粒度:CAP 关注的粒度是数据,而不是系统,需要根据不同业务的数据特点来设计
异地多活。
延迟:CAP 是忽略网络延迟的 ,但工程落地不可能做到零延迟。
分区容忍:C和A只能取1个是在发生分区的时候,正常运行情况下,可以同时满足 CA。
补救:放弃 != 无为,需要为分区恢复后做准备,包括人工修复数据。
3大原则:
原则1 - 只保证核心业务

假设一个银行有异地多活系统来处理客户的银行业务。银行的核心业务包括存款、取款、转账等操作。在异地多活架构下,银行在不同地理位置部署了多个活跃的系统实例,这些实例之间会进行数据同步和负载均衡,以确保任何一个地区的系统发生故障时,其他地区的系统仍能够继续提供核心业务服务。
原则2 - 只能做到最终一致性

举例来说,考虑一个在线购物平台的异地多活架构。该平台有多个数据中心分布在不同的地理位置,以提供更好的性能和容错性。购物平台的核心业务包括用户下单、库存管理和订单处理等。
在异地多活架构下,当用户在不同地理位置的系统实例上下单时,可能会出现以下情况:
用户A在地区X的系统下单,订单信息存储在地区X的数据中心。
同时,用户B在地区Y的系统下单,订单信息存储在地区Y的数据中心。
由于网络延迟或其他因素,地区X和地区Y之间可能会存在一定时间的数据同步延迟。在这段延迟期间,用户A可能会在地区X的系统看到自己的订单信息,但用户B在地区Y的系统看不到用户A的订单信息,反之亦然。
然而,购物平台的异地多活系统会努力保证最终一致性。一段时间后,系统会进行数据同步和调节,确保地区X和地区Y的订单信息最终达到一致状态。这意味着,尽管在瞬时时刻可能会存在数据的不一致性,但系统会在后续的过程中自动纠正这种不一致性,最终达到数据一致的状态。
原则3 - 只能保证绝大部分用户
不要为了0.01%的用户,而影响了99.9%的用户!
4个步骤
1.业务分类:将业务按照某个维度进行优先级排序,优先保证TOP3 业务异地多活。分析 TOP3 中的每个业务的关键数据特点,将数据分类。针对不同的数据分类设计不同的数据同步方式。
2.数据分类:分析 TOP3 中的每个业务的关键数据特点,将数据分类。

3.数据同步:针对不同的数据分类设计不同的数据同步方式。

4.异常处理:针对极端异常的情况,考虑如何处理,可以是技术手段或非技术手段。

假设我们有一个在线银行系统,我们将其业务按照某个维度进行优先级排序,并选择了TOP3业务进行异地多活保证。这些业务包括:
转账业务:允许用户在不同账户之间进行资金转移。
存款业务:用户向其账户存入资金。
取款业务:用户从其账户中提取资金。
举例说明:
现在,我们来分析这三个业务的关键数据特点并将数据分类:
转账业务:关键数据包括转出账户余额、转入账户余额、交易金额、交易时间等。
存款业务:关键数据包括存款账户余额、存款金额、存款时间等。
取款业务:关键数据包括取款账户余额、取款金额、取款时间等。
接下来,我们针对不同的数据分类设计不同的数据同步方式:
转账业务:采用同步方式进行数据同步,确保在进行转账操作时,转出账户余额和转入账户余额的变动是原子性的,即要么同时成功,要么同时失败。
存款业务:可以采用异步方式进行数据同步,允许存款操作稍后与存款账户余额的同步更新,因为存款操作一般不会立即影响账户的可用余额。
取款业务:同样可以采用异步方式进行数据同步,允许取款操作稍后与取款账户余额的同步更新。
最后,针对极端异常的情况,我们需要考虑如何处理。例如,如果某个地区的系统出现了长时间的网络分区或其他严重故障,我们可以采取以下措施:
技术手段:使用自动故障转移或自动负载均衡技术,将流量转移到其他正常运行的系统实例上,以确保核心业务的继续运行。
非技术手段:建立紧急通讯渠道,例如电话或短信通知,向用户说明当前系统故障情况,并提供备用的客服支持通道,以处理紧急的业务需求。
5大技巧:
消息队列同步

假设我们有一个在线零售平台,该平台使用消息队列来处理订单和库存更新等核心业务。我们在不同地理位置部署了多个活跃的消息队列系统,以提高系统的可用性和容错性。
订单处理示例:
重试机制:在消息队列同步失败后,实施自动的重试机制,尝试重新发送消息,直到成功为止。
备用队列:在发生故障时,将消息存储到备用队列中,并在故障恢复后进行补发。
场景描述:用户在网站上下单购买商品,订单信息需要被异步发送到不同地理位置的订单处理系统进行处理。
数据特点:订单数据包括订单号、商品信息、购买数量、客户信息等。
消息队列同步设计:当用户在某个地理位置下单时,订单信息首先被发送到该地区的消息队列系统中。然后,通过消息队列的同步机制,订单消息会被异步地发送到其他地理位置的消息队列系统中,以确保订单在所有地区的订单处理系统中都能得到处理。
异常处理:如果某个地理位置的消息队列系统发生故障或网络分区,无法将订单消息同步到其他地区,可以采用以下措施进行处理:
库存更新示例:
库存锁定:在处理订单时,提前对库存进行锁定,以确保即使在消息队列同步失败时,也不会出现库存超卖的情况。
手动修复:在故障恢复后,对库存进行手动修复,将漏掉的库存更新操作补上。
场景描述:用户下单购买商品后,库存需要被相应地减少,以防止超卖。
数据特点:库存更新数据包括商品编号、库存数量等。
消息队列同步设计:库存更新消息会在订单处理完成后生成,并发送到消息队列中。然后,通过消息队列的同步机制,库存更新消息会被异步地发送到其他地理位置的消息队列系统中,以确保各地区的库存数据保持一致。
异常处理:如果某个地理位置的消息队列系统在库存更新时出现故障或网络分区,可以采取以下措施:
库存拆分

假设我们有一个全球性的电子商务平台,需要处理各种商品的库存管理。考虑到不同地区的需求和供应链情况,决定在不同地理位置建立多个仓库,并对库存进行拆分管理。
业务分类与数据特点:
首先,我们对业务进行分类并分析其数据特点。例如,我们的电子商务平台销售服装、电子产品和家居用品等商品,这些商品的库存数据具有以下特点:
商品信息:包括商品编号、名称、描述等。
库存数量:不同尺码或型号的商品可能有不同的库存数量。
仓库位置:记录每个商品在哪个仓库中的库存量。
库存拆分设计:
我们根据业务需求和数据特点,设计库存拆分方案:
将不同类型的商品根据销售量和地理位置进行分类,并将其库存分配到相应的仓库中。
对于销售量较大或在特定地区需求较高的商品,可以将其库存集中存储在靠近该地区的仓库中,以提高交付速度和降低运输成本。
对于跨境销售的商品,可以在不同国家或地区建立仓库,并将其库存拆分存储在不同的仓库中,以避免海关清关延迟和运输风险。
数据同步:
在库存拆分的过程中,需要确保不同仓库中的库存数据保持同步,以确保订单处理和库存管理的准确性。可以采用以下方法进行数据同步:
实时同步:使用实时数据同步技术,确保每次库存变动都能够及时地在不同仓库之间同步。
批量同步:定期或按需将库存数据批量同步到各个仓库中,以确保数据一致性和准确性。
异常处理:
在库存拆分过程中,可能会遇到一些异常情况,例如某个仓库的库存不足或出现故障。针对这些异常情况,我们可以采取以下措施进行处理:
库存预警:设置库存预警机制,及时发现库存不足或异常情况,并采取补货或调拨等措施。
故障切换:在仓库出现故障时,及时切换到备用仓库,以确保订单处理和客户服务的连续性。
数据修复:在数据同步失败或不一致的情况下,及时对数据进行修复和同步,以确保库存数据的准确性和完整性。
事务合并

假设我们有一个在线电商平台,拥有多个地理位置的数据中心,每个数据中心都有自己的数据库实例。为了提高系统的性能和可用性,我们使用了异地多活架构。
业务场景:
在电商平台上,用户可以浏览商品、下单购买商品、付款等。这些操作涉及到多个数据中心的数据库,并且需要保证跨地域的事务操作的一致性。
事务合并设计:
在异地多活环境中,当用户在不同地理位置进行操作时,可能会发生多个地理位置的数据库同时被修改的情况。为了确保数据一致性,可以采用事务合并策略:
当用户在地理位置A下单购买商品时,该操作会在地理位置A的数据库中触发一个事务。
同时,该购买操作也会被同步到其他地理位置的数据库中,但不会立即执行。相反,它们会在本地数据库中被缓存,等待后续的事务合并。
定期或按需,系统会执行事务合并操作。这意味着将来自不同地理位置的事务合并到一个事务中,并且按照一定的规则来确定合并后的结果。例如,如果两个地理位置同时对同一商品进行了购买操作,可以通过一定的冲突解决策略来确定最终的结果,例如基于时间戳的冲突解决。
执行合并后的事务,确保数据在所有地理位置上的一致性。
异常处理:
在事务合并过程中可能会遇到一些异常情况,例如网络故障、数据冲突等。针对这些异常情况,我们可以采取以下措施进行处理:
冲突解决策略:设计合适的冲突解决策略,例如基于时间戳或优先级的策略,以确定最终的事务执行结果。
重试机制:在事务合并失败时,实施自动的重试机制,尝试重新合并事务,直到成功为止。
数据回滚:在合并过程中发现数据不一致或无法解决冲突的情况下,可以回滚事务,并进行手动修复或通知相关人员进行处理。
实时改异步

假设我们有一个在线聊天应用程序,用户可以发送即时消息给其他用户。最初,这个应用程序可能是实时处理用户发送的消息,即当用户发送消息时,服务器立即将消息传递给接收者。这种实时处理的方式可能会导致服务器负载过重,影响系统的性能和可伸缩性。
为了解决这个问题,我们可以将消息处理方式从实时改为异步。具体步骤如下:
设计异步消息队列:
引入消息队列作为异步处理的中介,当用户发送消息时,服务器不再直接处理消息,而是将消息写入消息队列中。
消息消费者:
引入消息消费者来从消息队列中异步读取消息,并处理消息。消息消费者可以是单独的进程、服务或者分布式系统。
消息处理:
当消息消费者从消息队列中读取到消息时,它会负责将消息发送给接收者。这个过程是异步的,消息消费者可以根据系统的负载情况和处理能力来自行调整处理速度。
实时性与可伸缩性的权衡:
由于消息处理变为异步,可能会导致消息的传递速度变慢,不再是实时的。但是通过增加消息消费者,我们可以水平扩展系统,以处理更多的消息,从而提高系统的可伸缩性。
异常处理:
在异步处理过程中,可能会遇到消息丢失、消息重复处理等异常情况。因此需要设计合适的异常处理机制,例如消息重试、消息确认机制等,来确保消息的可靠传递和处理。
适当容忍

假设我们有一个在线社交网络平台,用户可以在不同地理位置之间进行消息发送和接收。在异地多活环境中,为了提高系统的性能和可用性,我们采用了适当容忍的策略。
消息发送和接收:
当用户在某个地理位置发送消息时,消息会被异步地传输到其他地理位置的服务器上。在这个过程中,可能会出现一定程度的延迟,导致消息的接收方不能立即看到发送的消息。
适当容忍的实现:
对于用户来说,系统可以在发送消息后立即显示消息的发送状态,而不必等待消息被接收方接收确认。
同时,系统会异步地将消息传输到其他地理位置,以确保消息的可靠传递,但并不要求立即一致性。
接收方可能会在一定的延迟之后才能看到发送的消息,但这种延迟是可接受的,并且在用户体验上不会造成明显影响。
数据一致性与延迟权衡:
在采用适当容忍策略时,需要权衡数据一致性和延迟。系统可以允许一定程度的延迟,以降低数据一致性的要求,从而提高系统的性能和可用性。
异常处理:
在异地多活环境中,可能会发生网络故障或消息丢失等异常情况。系统需要设计相应的异常处理机制,例如消息重试、数据补偿等,来确保消息的可靠传递和处理。
原文作者:二进制跳动;如有侵权,请联系管理员删除。