社区编辑申请
注册/登录
跨系统数据一致性问题经验实战
开发 前端
随着互联网的告诉发展,跨系统数据一致性应用需求一定会越来越迫切,跨地域跨系统场景的真正痛点也会越来越清晰,希望我们在跨系统数据一致性方面的调研和探索可以给大家一个思路和参考。

目前随着微服务化建设的普及,存在越来越多的跨系统数据交互情况,跨系统数据一致性问题越发凸显,那如何有效保证跨系统数据的一致性呢?

本文旨在总结沉淀工作中问题的解决经验,整理解决跨系统数据不一致问题的经验方法。

1、为什么会有跨系统数据一致性问题?

提到数据一致性,我们很容易想到的就是数据库中的事务操作。

事务的原子性和持久性可以确保在一个事务内,操作多条数据,要么都成功,要么都失败。这样在一个系统内部,我们可以很自然地使用数据库事务来保证数据一致性。但是在微服务的今天,一项操作会涉及到跨多个系统多个数据库的时候,用单一的数据库事务就没办法解决了。

另外常见的一种情况就是:存在依赖情况的系统服务,例如业务端与用户端(业务端负责生产数据,用户端负责展示数据),需要数据同步来保障跨系统服务的数据一致性,很多时候采用何种数据同步方式,来保障数据应用的时效性至关重要。

2、一致性问题的难点分析

为了更好的描述和理解问题,我们用一个案例来阐述:

假设存在订单系统与库存系统,在实际业务中订单的创建会伴随着库存的减少。 两个系统为微服务化部署,其应用数据也存放在独立的数据库中,两个系统间通过网络进行通信。

2.1 CAP原则

CAP 指的是Consistency(一致性)、Availability(可用性)、Partition tolerance(分区容错性)。

放弃 A (可用性)来保障 CP

具体表现为产生通信故障后,应用会进入阻塞状态,一直尝试与库存系统恢复通信直到完成所有数据处理。这种方案是优先保障数据完整性,但此方案用户体验极差,因为在所有操作完成前用户会一直处于等待的状态。

CAP 本身就是互斥的,只能从三者中选两个,对于 CA、AP、CP 都有它们自己的应用场景,要结合实际进行选择。

  • CA 因为不考虑分区容忍度,所以它的所有操作需要在同一进程内完成(也就是我们常说的单体应用);
  • AP 因为放弃数据一致性,适合数据要求不高但强调用户体验的项目,如博客、新闻资讯等;
  • CP 反之放弃了可用性,适合数据要求很高的交易系统,如银行交易、电商的订单交易等,就算是用户长时间等待,也要保障数据的完整可靠。

CAP 原则在实际项目中的运用,对于互联网应用来说,如果为了用户体验完全放弃数据一致性这也是不可取的,毕竟数据才是应用的根本。

那该怎么解决呢?

保障最终一致性的措施有很多,主要包括:分布式事务和TCC 一致性方案。

MySQL 其实有一个两阶段提交的分布式事务方案(MySQL XA),但是该方案存在严重的性能问题。

比如,一个数据库的事务与多个数据库之间的 XA 事务性能可能相差 10 倍。另外,在 XA 的事务处理过程中它会长期占用锁资源,所以一开始我们并不考虑这个方案。

在此,我们主要讨论一下TCC一致性方案。

2.2 TCC 一致性方案

TCC 是一种数据一致性方案,我们会把原来的一个接口分为三个接口:

  • Try 接口用来检查数据、预留业务资源。
  • Confirm 接口用来确认实际业务操作、更新业务资源。
  • Cancel 接口是指释放 Try 接口中预留的资源。

在TCC中,它将分布式处理过程分为两个阶段:

  • Try 是第一个阶段,用于尝试并锁定资源;
  • 如果资源锁定成功,第二个阶段开始进行 Confirm 提交完成数据操作;
  • 如果资源锁定失败,第二个阶段就会进行 Cancel 将数据回滚;

TCC 实施过程中有哪些注意事项呢?

1)在 Try 阶段做尽可能多的事情

要把绝大多数的业务逻辑在 Try 阶段完成,因为 TCC 设计之初认为 Confirm 或 Cancel 是一定要成功的,因此不要二阶段包含任何业务代码或者远程通信,只通过最简单的代码释放冻结资源。

2)保障Confirm 或 Cancel 执行成功

假如 Confirm 或 Cancel 执行时出现错误,那具体应用时也会不断重试执行操作来尽量保证执行成功,这个过程中可能会多次执行 update 语句,因此要注意代码的幂等性。

3)Confirm 或 Cancel 执行失败的兜底方案

极小概率下,Confim 或 Cancel 在多次重试后宣告失败,便会出现数据最终不一致的情况,这就需要自己开发额外的数据完整性校验程序补救或者通过人工进行补录。

TCC 归根结底是一种理论设计,需要厂商实现相应的框架给予支撑。

在 Java 开源领域著名的 TCC 框架有:ByteTCC、Hmily、Tcc-transaction 与 Seata。

3、有效数据同步方案实践

问题描述:我们还是以之前的案例场景,数据需要从订单系统同步到库存系统中。

解决数据一致性常用的三类数据同步方案:实时同步、定时同步、手动同步。

3.1 实时同步

实时同步可以从数据库、应用处理两个层面来解决。

3.1.1 数据库层面

通用采用数据库的数据同步,主从解决,当master(主)库的数据发生变化的时候,变化会实时的同步到slave(从)库。

优势:

  • 水平扩展数据库的负载能力。
  • 容错,高可用,Failover(失败切换)/High Availability
  • 数据备份。

如何实现主从一致

关于 MySQL 主从复制主要同步的是 binlog 日志,涉及到三个线程,一个运行在主节点(log dump thread),其余两个(I/O thread, SQL thread)运行在从节点,如下图所示:

(1)主节点 binary log dump 线程

当从节点连接主节点时,主节点会创建一个 log dump 线程,用于发送 binlog 的内容。在读取 binlog 中的操作时,此线程会对主节点上的 binlog 加锁,当读取完成,在发送给从节点之前,锁会被释放。

(2)从节点 I/O 线程

当从节点上执行start slave命令之后,从节点会创建一个 I/O 线程用来连接主节点,请求主库中更新的 binlog。I/O 线程接收到主节点 binlog dump 进程发来的更新之后,保存在本地 relay-log(中继日志)中。

(3)从节点 SQL 线程

SQL 线程负责读取 relay log 中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。

3.1.2 API调用

一次业务数据操作,需要调用多方API实现实时数据的同步。

劣势比较明显,主要表现在:

1)处理耗时长,需要串行调用多方API并等待响应,用户体验较差;

2)会有一定几率出现数据不一致情况(个别API调用出错、未响应等情况)。

3.2 异步同步

3.2.1 异步消息队列

Message Queue(MQ),消息队列中间件。

MQ 通过将消息的发送和接收分离来实现应用程序的异步和解偶,同时MQ屏蔽底层复杂的通讯协议,定义了一套应用层的、更加简单的通讯协议。

应用MQ的优点:解耦,削峰,数据分发。

在业务系统设计中,我们常常会存在一个平台系统 A,它关联同步了许许多多的系统的对接(系统B、C、D等)。

利用MQ可以很好的解决系统对接和数据同步问题,同时可以忽略对接系统的稳定性等诉求。

3.2.2 定时同步

定时任务在系统中并不少见,主要目的是用于需要定时处理数据或者执行某个操作的情况下,如定时关闭订单,或者定时备份。

常见的定时任务分为2种:

1)第一种:固定时间执行,保障同步并校准数据

如:每分钟执行一次,每天执行一次。

2)第二种:延时多久执行,即动作发生后,定时多久后执行任务

如:15分钟后关闭订单付款状态,24小时候后关闭订单并且释放库存等。

3.3 手动同步

在一般数据管理中,在具备了上述实时同步和异步同步的情况下,为了防止其他异常情况造成的数据不一致,可以考虑开发备用数据同步工具(脚本)来手动方式主动进行恢复,将数据同步并进行校准。

其优劣也很明显,优势:随时随地主动操作;劣势:需要人工进行干预。

数据同步最好的情况是能够实现实时同步,但是考虑到数据同步过程中对系统的压力以及数据实时同步的必要性等因素有时会选择定时同步和手动同步。

4、应用经验总结

技术还是要解决实际问题来落地。应用场景很关键,不要单纯为了技术而技术,技术归根结底还是为应用场景和产业落地服务。 软件设计过程中,不需要刻意去应用看起来高大上的解决方案,而当需要引入时,要同时考虑开发、维护成本以及对应性能的提升的性价比,否则得不偿失。

(1)任何架构方案都是不断演进的

任何数据同步本身没有优劣之分,都有其适合的应用场景。

(2)架构的目的是解决业务问题

能够解决当前问题的架构方案,同时兼具易于扩展及维护,那就是一个优秀的架构。

随着互联网的告诉发展,跨系统数据一致性应用需求一定会越来越迫切,跨地域跨系统场景的真正痛点也会越来越清晰,希望我们在跨系统数据一致性方面的调研和探索可以给大家一个思路和参考。

责任编辑:武晓燕 来源: 今日头条
相关推荐

2022-05-18 23:42:08

网络安全安全分析工具

2022-05-20 14:54:33

数据安全数字化转型企业

2022-05-17 15:51:32

数据中心运维能力基础设施

2022-05-17 14:03:42

勒索软件远程工作

2022-05-09 15:08:56

存储厂商NFV领域华为

2022-05-16 10:36:08

GitHub开源项目

2022-05-12 13:44:35

2022-05-11 15:08:52

驱动开发系统移植

2022-05-16 13:37:12

Sysrv僵尸网络微软

2022-05-24 12:42:24

物联网

2022-05-11 14:48:33

腾讯云寿险民生保险

2022-05-09 11:57:39

云原生实践安全

2022-05-11 14:05:11

区块链网络安全存储

2022-05-12 14:44:38

数据中心IT云计算

2022-05-16 10:49:28

网络协议数据

2022-05-14 08:05:18

Linux内存管理

2022-05-17 16:56:33

开发工具前端

2022-04-19 08:15:53

DDD领域建模实战

2022-04-25 21:25:38

数据模式

2022-05-24 08:21:16

数据安全API

同话题下的热门内容

让程序员心动的11种新编程语言Flutter vs ReactJS:2022年应该选哪个?再有人问你什么是分库分表,直接把这篇文章发给他前端配置化真香~上班又多了60%的摸鱼时间2022年值得使用的 Node.js 框架HTTP 的缓存为什么这么设计?前端监控的搭建步骤,别再一头雾水了!如何加快Java中大型集合的处理

编辑推荐

太厉害了,终于有人能把TCP/IP协议讲的明明白白了!牛人5次面试腾讯不成功的经验HBase原理–所有Region切分的细节都在这里了Javascript如何监听页面刷新和关闭事件如何搭建一个HTTPS服务端
我收藏的内容
点赞
收藏

51CTO技术栈公众号