写点什么

架构师必备:实时对账与离线对账

  • 2025-08-04
    福建
  • 本文字数:1701 字

    阅读完需:约 6 分钟

背景


在跨系统之间的数据写入场景下,上下游系统极有可能因为网络超时/抖动、或写本地 DB 与调外部接口不能同时成功等原因,而出现数据不一致的问题,因此需要有及时发现不一致问题、并自动修复的能力。下面结合笔者的经验,把对账做个总结。

需要注意的是,这里提的对账不特指资金对账,而是跨系统的字段对账,如 B 端与 C 端系统之间的对账。


对账的指标


判断对账是否做得好,主要看这几个指标:

  • 完备性:确保所有字段都有对账

  • 时效性:越高越好,秒级 > 分钟级 > 小时级 > 天级

  • 自动修复:对账发现不一致后自动修复,然后再次对账,确保修复后是最终一致的,形成闭环

下面分别介绍一下实时对账、离线对账,最好是两个都做。


1. 实时对账(秒级到分钟级对账)


实时对账可以尽快发现不一致,一般由数据写入方发起对账,数据接收方提供对账查询接口(例如查从库)。


触发方式分 2 种:

  • (不推荐)数据库变更事件触发:监听业务主表的 binlog 变更

  • (推荐)业务消息触发:监听业务消息变更

推荐由业务消息触发,是因为数据库变更事件触发有局限:

  • 如果有的写入操作不更新业务主表,比如只更新了扩展表,则需要新消费扩展表的 binlog 事件消息。

  • 如果存在中间状态,则需要等到记录变成终态后才能对账,需要过滤很多无效消息。


实现方案:

  1. 监听业务消息变更。业务消息需做成事务消息,即业务操作完成必发出、不完成不发出。业务消息可以携带多个表的信息,能减少一定的查 DB 请求。

  2. 延迟、批量消费变更消息,然后批量查询本地 DB 数据、以及上下游接口。

  3. 最后逐个字段做比较。



之所以要写入方发起对账,而不是接收方,是因为写入方调接收方的接口可能失败,接收方在写入失败时无法触发对账。

之所以要延迟消费,是为了避免短时间内的不一致造成误告警(例如数据库主从延迟、接口超时重试等原因),比如延迟 15 秒再消费。

之所以要积攒一批消息做批量消费,是为了避免对账查询 qps 过高,给本服务和上下游系统带来较大负载。


2. 离线对账(小时级到天级对账)


有了在线对账,为什么还需要离线对账呢?

  • 离线对账作为在线对账的兜底,可以定期跑历史存量数据

  • 离线对账不影响在线业务的稳定性

  • 外部第三方系统,一般只能定期提供离线数据,无法提供对账查询接口。典型的如第三方支付系统的对账单


实现方案:

  1. 离线采集:导出各系统的数据到 hive 表,可以是 mysql 表、或者是对账单

  2. 归一化数据:解析出所有的对账字段,按统一格式生成新的宽表 a、宽表 b

  3. 离线对比:

(1)需要比较条数是否一致

(2)以及数据内容是否一致:通过左连接找到只存在于左表的数据,通过右连接找到只存在于右表的数据,通过内连接并比较各个字段来找到存在差异的数据

下面看 sql 例子。

-- (1)比较两个表的条数是否一致select count(1) from table_a; -- 查出左表的条数select count(1) from table_b; -- 查出右表的条数
-- (2)比较数据内容是否一致-- (2.1)只存在于左表的数据:左连接查询,左表记录都会保留,右表字段为空则说明右表缺少数据:select * fromtable_a left outer join table_bon table_a.biz_field=table_b.biz_fieldwhere table_b.biz_field is null;
-- (2.2)只存在于右表的数据:右连接查询,右表记录都会保留,左表字段为空则说明左表缺少数据:select * fromtable_a right outer join table_bon table_a.biz_field=table_b.biz_fieldwhere table_a.biz_field is null;
-- (2.3)两个表存在差异的数据,内连接查询,比对各个字段是否一致:select * fromtable_a inner join table_bon table_a.biz_field=table_b.biz_fieldwhere(table_a.field_1 <> table_b.field_1or table_a.field_2 <> table_b.field_2or table_a.field_3 <> table_b.field_3);
复制代码


3. 自动修复


一般是写入方发现不一致后,需要做自动修复。流程如下:

  1. 记录差异,供后续定位排查

  2. 自动修复

  3. 修复后再次对账,确保数据最终一致


结论


实时对账和离线对账,互为补充、缺一不可。新需求除了保证功能正确性,还要同时做好对账,避免有不一致问题时发现不了,或很久才发现。

对账发现不一致后自动修复,能保证系统的最终一致性。


文章转载自:Java烘焙师

原文链接:https://www.cnblogs.com/toplist/p/19009976

体验地址:http://www.jnpfsoft.com/?from=001YH

用户头像

还未添加个人签名 2025-04-01 加入

还未添加个人简介

评论

发布
暂无评论
架构师必备:实时对账与离线对账_数据库_电子尖叫食人鱼_InfoQ写作社区