浅谈数据仓库 (三) 数据漂移处理

  前言

  我们是一个做传统会员管理CRM的团队,应用数据的级别比较高,过去会存在这样一种现象,T+1 财务报表,运营统计各类报表 的指标偶尔会和商户的自己记录用户消费储值记录会有出入,后来了解到,我们系统中存在很严重的数据漂移问题,这也是dw系统或者ods来说普遍存在的问题,今天我们好好聊下该如何解决数据漂移问题

   数据漂移产生的原因

  通常我们把从源系统同步进入数据仓库的第一层数据成为ODS层数据,我们公司目前只有ODS一层,虽说只有一层,但是仍然有有一个顽疾:数据漂移,简单来说就是ODS表的同一个业务日期数据中包含前一天或者后一天凌晨附近的数据或者丢失当天的变更数据。更新表来说会丢失变更数据,流水表一般会丢失上一天数据,或者说上一天数据漂移到下一天。

  由于ODS需要承接面向历史的细节数据查询需求,这就是需要物理落地到数据仓库的ODS表按时间段来进行分区存储,通常的做法是按某些时间戳字段来切分,二实际上往往由于时间戳字段的准确性问题导致发生数据漂移。当然我们目前切分的字段是datetime类型的updatetime字段。

  通常时间戳字段分为四类:

  (1)数据库表中用来表示数据记录更新时间的时间戳字段(假设这类字段叫modified_time);

  (2)数据库日志中用来表示数据记录更新时间的时间戳字段(假设这类字段叫log_time);

  (3)数据库表中用于记录具体业务过程发生时间的时间戳字段(假设这类字段叫proc_time);

  (4)标识数据记录被抽取到时间的时间戳字段(假设这类字段叫extract_time)当然这种还是比较少用的;

  理论上这几个时间应该是一致的,但是在实际生产中,这几个时间往往会出现差异,可能的原因有以下几点:

  (1)由于数据抽取是需要时间的,extract_time往往会万余前三个时间。当然这个应用的必要场景我所料及的不多;

  (2)前台业务系统手工订正数据时候未更新modified_time,在我们的系统中这种现象仍然没有杜绝;

  (3)由于网络或者系统压力问题,log_time或者modified_time 会晚于proc_time;

  通常的做法是根据其中的一个字段来切分ODS表,这就导致产生数据漂移,下面说下我所了解到数据漂移的几种场景:

  (1)根据extract_time来获取数据。这种情况数据漂移的问题最明显,当然实际生产中这种会发生在解析log的场景中,对于数据级别不高的分析业务来讲有可能是可以接受的;

  (2)根据modified_time限制。在实际生产中这种情况是最常见的,但是往往会发生不更新modified_time而导致的数据遗漏,或者凌晨时间产生的数据记录漂移到后一天,这是我们实际生产中更新表会存在的漂移问题。

  (3)根据log_time限制。由于网络或者系统压力问题,log_time会晚于proc_time,从而导致凌晨时间产生的数据记录漂移到后一天。例如周末节假日我们所服务的很多餐饮商户凌晨期间产生数据量还是比较大的,在掉我们收银,点餐等行为会调用我们多个接口,从而导致log_time晚于实际的支付或者点餐时间。

  (4)根据proc_time限制。仅仅根据proc_time限制,我们所获取的ODS表只是包含一个业务过程所产生的记录,会遗漏很多其他过程的变化记录,这违背了ODS和业务系统保持一致的设计原则

  解决方法

  解决方法先谈两种主要的:

  (1)多获取后一天的数据

  既然很难解决数据漂移的问题,那么就在ODS每个时间分区中向前、向后多冗余一些数据,保证数据只会多不会少,而具体的数据切分让下游根据自身不同的业务场景用不同的业务时间proc_time来限制。但是这种方式会有一些数据误差,例如一个订单是当天支付的,但是第二天凌晨申请退款关闭了该订单,那么这条记录的订单状态会被更新,下游在统计支付订单状态时会出现错误。

  (2)通过多个时间戳字段限制时间来获取相对准确的数据

  1> 首先根据log-time分别冗余前一天最后15分钟的数据和后一天凌晨开始15分钟数据,并用modified_time过滤非当天数据,确保数据不会因为系统问题而被遗漏

  2>然后根据log_time获取后一天15分钟的数据;针对此数据按照主键根据log_time做升序排列去重,因为我们要获取的是最接近当天记录变化的数据(数据库日志将保留所有变化的数据,但是落地到ODS表的是根据主键去重获取的最后状态的数据)

  3>最后将前两步结果数据做全外连接,通过限制业务时间proc_time来获取我们所需要的数据

  今天先到这里接下来还会补充我们具体解决的步骤;

posted @ 2018-12-18 23:46  ¥王大胖¥  阅读(2793)  评论(0编辑  收藏  举报