ODS层数据同步问题总结

发布时间 2023-08-04 18:14:58作者: 卤鸭架

ODS层数据同步问题总结

项目中参与到一些贴源层从各个系统同步数据的需求,理论上ODS层是不做任何处理的,应该很简单才对,但是实际还是超出理论的, 结合其他同事踩过的坑,总结一些接入的问题。

其实大部分问题,都是源表不规范导致的,因此在抽数前,一定要做好调研,下次写一篇如何做调研的总结。

名词解释

  • 源系统: 业务系统,如用户管理系统、交易系统、手机APP等

ODS同步方案分析

ods从源端同步数据,大方向主要是推和拉两种,推就是上游系统在约定时间将数据文件推送到某个服务器,或者是kafka的topic中,下游从指定地方获取,如canel就是个典型的实时推送mysql binlog的程序; 拉则是用的比较多的,由ods段主动去抽取想要的数据。

更新策略一般是增量和全量加载两种,即是抽所有,还是抽变动的数据。

源系统规范问题

源表的创建时间、更新时间字段问题

1.缺少创建日期、更新日期:

源系统的数据库表设计不规范,缺少了创建日期、更新日期的字段,那么对下游来说就无法判断哪些数据是新的,哪些数据是旧的,只能做全量抽取。

对于一些写入后数据不再更新或者很少更新的表,全量抽取每次都要抽一大堆旧数据,比较浪费资源。例如:活动报名表, 用户报名后记录一条数据,不可更改报名信息;而且有很多已结束的活动报名记录。

2.创建日期、更新日期使用不当:

各个源系统对于这两个字段的使用方式不当:

  • 新增数据时,不对这两个字段赋值
  • 新增数据时,只赋值创建时间
  • 新增数据时,创建时间和更新时间都赋值
  • 新增数据时,在TIMESTAMP字段类型中赋值DATE,即丢失时分秒
  • 更新数据时,创建时间和更新时间都更新
  • 更新数据时,更新时间不更新


    对于ODS抽数来说,只要有条件判断该条数据,是否变动就可以了,不管是哪个时间,或者某个标志都行,因此推荐源系统 新增数据时,创建时间和更新时间都赋值;更新数据时,只刷新更新时间; 这种规范也便于源系统排查问题

源系统数据质量问题

3.源系统数据存在物理删除的情况

物理删除即 delete语句把数据给删了,通常情况下重要的业务数据不应该删除,需要使用一个失效标志来标记出来做逻辑删除。

对于ODS来说如果通过增量加载,那么源系统删除的数据,会在ODS一直存在,导致两者数据不一致,影响可信度。

4.源系统表设计职责不清

要明确几种表的类型:

  • 配置表:存一些代码映射,系统配置等,一般保持最新即可。
  • 状态表:存一些合约类型的信息,如贷款协议表,还款计划表; 每一条记录都应该对应一个实际的业务对象,有明确的业务主键,发生变化时应该更新原来的对象。
  • 事件表:存发生的事情,如交易、投诉、催收等;每条记录对应一个实际发生的动作,通常主键是流水号,和时间相关。


    有的业务系统的状态表,每次更新时都新增一条数据,当成事件表用;对ODS没什么影响,但是会导致更下一层的DWD出现主键重复的问题。
5.缺少业务主键或主键重复或者主键被更新
  • 缺少主键:影响DWD和DWS数据,在数仓范式建模下,每个表都是对象或者关系,因此需要标识唯一
  • 主键重复:重复数据可能导致下游计算错误,如用户贷款金额为10000,用户号重复, 关联统计后变成了20000
  • 主键被更新: 这个场景很诡异,影响都是让下游用数不准确; 活动邀请信息表,主键为邀请用户ID+被邀请用户ID, 但是用户A将生成邀请页面后创建一条数据后,会先生成一条 邀请用户ID为用户A,但被邀请用户ID为null的数据, 当用户B点击A发送的邀请链接完成规则后,更新被邀请用户为B,导致主键变动; 但是对于下游增量加载的策略来说,这个是一条新增的数据,就会导致数据重复了。

协同类问题

6.事件表数据更新未通知下游

事件类的表,可能有修历史数据的需求,如果源系统没有通知下游,那么可能有两种情况:

  • 修数时没更新udpate_time, ods抽不到数据
  • 修数时更新了update_time,但ods把这条数据作为了一条新增的数据,导致数据重复

解决方案:

  • ods将增量数据和历史对比,判断是否为新增的
  • 上游将变更通知到下游,并给出修数方案

第一种特别浪费资源,但是在IT水平低的企业,通常还是这种做法。

7.源系统数据归档

源系统通常是关系型库,表越大性能越差,所以对于数据量大的表会做归档操作,比如将3年前的所有数据归档到线下,在线上表中删除。

对于ODS来说,增量数据是不影响的,但是如果要做历史数据的初始化,就需要额外的处理,需要沟通好方案。