摘自阿里大数据之路
什么是数据漂移
通常我们把从源系统同步进入数仓的第一层数据称为 ODS或者staging层数据,接入层 。
数据漂移是接入层数据的一个顽疾。
数据漂移定义:接入层ODS表同一个业务日期数据中包含前一天或者后一天凌晨附近的数据或者丢失当天的变更数据。
数据漂移出现的原因
通常落地数仓的ODS表会按时间切分做分区存储,实际上往往由于时间戳字段的准确性问题导致发生数据漂移。通常有四类时间戳:
modified_time:数据库记录某条数据更新的时间。
log_time:数据库日志记录某条数据更新的时间。
proc_time:具体业务过程发生时间。
extract_time:数据记录被抽取时间。
理论上这四个时间是一致的,但由于以下原因会出现数据漂移:
1)同一条记录的数据抽取时间extract_time明显是晚于另外三个时间的,如果用这个字段切分,ODS某个分区中的数据会包含前一天末尾的数据,并丢失当天末尾的数据。
2)如果用数据库记录的更新时间modified_time,前台业务系统手工订正数据时可能会遗忘同步更新该时间,导致该抽取的数据被遗漏掉。
3)另外,由于网络或者系统压力问题,log_time或者modified_time可能会晚于proc_time,导致数据漂移。
4)如果我们直接使用proc_time时间进行切分,这种情况仅仅对包含一个业务过程的ODS表有效果,如果该表每条记录需要存储多个业务过程,则用proc_time切分会丢失其他发生在当天的业务过程记录。
处理数据漂移的方式
1.多获取后一天的数据
既然很难解决数据漂移的问题,那么就在ODS每个时间分区中向前、向后多冗余一些数据,保证数据只会多不会少,而具体的数据切分让下游根据自身不同的业务场景用不同的业务时间proc_time来限制。但是这种方式会有一些数据误差,例如一个订单是当天支付的,但是第二天凌晨申请退款关闭了该订单,那么这条记录的订单状态会被更新,下游在统计支付订单状态时会出现错误。
2.通过多个时间戳字段限制时间来获取相对准确的数据
1) 首先根据log-time分别冗余前一天最后15分钟的数据和后一天凌晨开始15分钟数据,并用modified_time过滤非当天数据,确保数据不会因为系统问题而被遗漏
2) 然后根据log_time获取后一天15分钟的数据;针对此数据按照主键根据log_time做升序排列去重,因为我们要获取的是最接近当天记录变化的数据(数据库日志将保留所有变化的数据,但是落地到ODS表的是根据主键去重获取的最后状态的数据)
3) 最后将前两步结果数据做全外连接,通过限制业务时间proc_time来获取我们所需要的数据.