数据库表中用来标识数据记录更新时间的时间戳字段(假设这类字段叫 modified time )。
数据库日志中用来标识数据记录更新时间的时间戳字段·(假设这类宇段叫 log_time)。
数据库表中用来记录具体业务过程发生时间的时间戳字段 (假设这类字段叫 proc_time)。
标识数据记录被抽取到时间的时间戳字段(假设这类字段extract time)。
理论上,这几个时间应该是 致的,但是在实际生产中,这几个时间往往会出现差异,可能的原因有以下几点
由于数据抽取是需要时间的, extract_ti me 往往会晚于前三个时间。
( l )多获取后 天的数据既然很难解决数据漂移的问题,那么就在 ODS 每个时间分区中向
前、向后多冗余 些数据,保障数据只会多不会少,而具体的数据切分让下游根据自身不同的业务场景用不同的业务时间 proc time 来限制但是这种方式会有一些数据误差,例如 个订单是当天支付的,但是第二天凌晨申请退款关闭了该订单,那么这条记录的订单状态会被更新,下游在统计支付订单状态时会出现错误。
(2 )通过多个时间戳字段限制时间来获取相对准确的数据首先根据 log_time 分别冗余前一天最后 15 分钟的数据和后一天凌晨开始 15 分钟的数据,并用 modified time 过滤非当天数据,
确保数据不会因为系统问题而遗漏。然后根据 log_time 获取后一天 15 分钟的数据 针对此数据,按
照主键根据 log_time 做升序排列去重。因为我们需要获取的是最接近当天记录变化的数据(数据库日志将保留所有变化的数据,但是落地到 DS 表的是根据主键去重获取最后状态变化的数据)。
最后将前两步的结果数据做全外连接,通过限制业务时间proc_time 来获取我们所需要的数据。下面来看处理淘宝交易订单的数据漂移的实际案例。我们在处理“双 ”交易订单时发现,有 大批在11 月11日23:59:59 左右支付的交易订单漂移到了 12 。主要原因是用户下单支付后系统需要调用支付宝的接口而有所延迟,从而导致这些订单最终生成的时间跨天了。即 modified time log_time 都晚于 proc_time如果订单只有一个支付业务过程,则可以用支付时间来限制就能获取到正确的数据。但是往往实际订单有多个业务过程 下单、支付、成
功,每个业务过程都有相应的时间戳字段,并不只有支付数据会漂移。如果直接通过多获取后 天的数据,然后限制这些时间,则可以获取到相关数据,但是后 天的数据可能已经更新多次,我们直接获取到的那条记录已经是更新多次后的状态,数据的准确性存在 定的问题。因此,我们可以根据实际情况获取后 15 分钟的数据,并限制个业务过程的时间戳字段(下单、支付、成功)都是“双11 ”当天的,然后对这些数据按照订单的 modified time 升序排列,获取每个订单首次数据变更的那条记录。此外,我们可以根据 log_time 分别冗余前 天最后 15 分钟的数据和后 天凌晨开始 15 分钟的数据,并用 modified time 过滤非当天数据,针对每个订单按照 log time 进行降序排列 ,取每个订单当天最后一次数据变更的那条记录。最后将两份数据根据订单做全外连接,将漂移数据回补到当天数据中。