400-0380-010
申请试用
免费预约演示
让我们的咨询顾问用最短 20分钟 的讲解,来帮助您
更高效的评估大数据+RPA
如何优雅的的做“数据仓库分层”
发布时间:2021-06-25 浏览:1

参考引用


特别鸣谢 36 大数据的佚名作者的文章。



引用&文章结构


最初在做数据仓库的时候遇到了很多坑,由于自身资源有限,接触数据仓库的时候,感觉在互联网行业里面的数据仓库成功经验很少,网上很难找到实践性比较强的资料。而那几本经典书籍里面又过于理论,折腾起来真是生不如死。还好现在过去了那个坎,因此多花一些时间整理自己的思路,帮助其他的小伙伴少踩一些坑。


文章的结构如下:

1.为什么要分层?这个问题被好几个同学质疑过。因此分层的价值还是要说清楚的。


2.分享一下经典的数据分层模型,以及每一层的数据的作用和如何加工得来。


3.分享两个数据分层的设计,通过这两个实际的例子来说明每一层该怎么存数据。

 


为什么要分层?


我们对数据进行分层的一个主要原因就是希望在管理数据的时候,能对数据有一个更加清晰的掌控,详细来讲,主要有下面几个原因:

  • 清晰数据结构:每一个数据分层都有它的作用域,这样我们在使用表的时候能更方便地定位和理解。

  • 数据血缘追踪:简单来讲可以这样理解,我们最终给业务诚信的是一能直接使用的张业务表,但是它的来源有很多,如果有一张来源表出问题了,我们希望能够快速准确地定位到问题,并清楚它的危害范围。

  • 减少重复开发:规范数据分层,开发一些通用的中间层数据,能够减少极大的重复计算。

  • 复杂问题简单化。讲一个复杂的任务分解成多个步骤来完成,每一层只处理单一的步骤,比较简单和容易理解。而且便于维护数据的准确性,当数据出现问题之后,可以不用修复所有的数据,只需要从有问题的步骤开始修复。

  • 蔽原始数据的异常。

  • 蔽业务的影响,不必改一次业务就需要重新接入数据。

  • 据体系中的各个表的依赖就像是电线的流向一样,我们都希望它是规整、流向清晰、便于管理的,如下图

 



但是,最终的结果大多却是依赖复杂、层级混乱,想梳理清楚一张表的声称途径会比较困难,如下图:

 


 


怎么分层?


1. 理论

我们从理论上来做一个抽象,可以把数据仓库分为下面三个层,即:数据运营层、数据仓库层和数据产品层。

 


1、ODS 全称是 Operational Data Store,操作数据存储,数据运营层,也叫 ODS  层,是数据源中的数据,经过 ETL 后装入本层。本层的数据,总体上大多是按照源头业务系统而分类的。但这一层的数据却不等同于原始数据。在源数据装入这一层时,要进行诸如去噪(例如有一条数据中人的年龄是 300 岁,这种属于异常数据要提前做一些处理)、去重(例如在个人资料表中,同一 ID 却有两条重复数据,在接入的时候需要做一步去重)、字段命名规范等一系列操作。


2、数据仓库层(DW),是数据仓库的主体.在这里,从 ODS 层中获得的数据按照主题建立各种数据模型。这一层和维度建模会有比较深的联系。


3、数据产品层(APP),这一层是提供为数据产品使用的结果数据。

 

2. 技术实践


这三层技术划分,我们先看一看每一层的数据一般都是怎么流向的。

2.1. 数据来源层→ ODS 层

这里其实就是我们现在大数据技术发挥作用的一个主要战场。 我们的数据主要会有两个大的来源:

1、业务库:这里经常会使用 Sqoop 来抽取,比如我们每天定时抽取一次。在实时方面,可以考虑用 Canal 监听 Mysql 的 Binlog,实时接入即可。


2、埋点日志,线上系统会打入各种日志,这些日志一般以文件的形式保存,我们可以选择用 Flume 定时抽取,也可以用用 Spark Streaming 或者 Storm 来实时接入,当然,Kafka 也会是一个关键的角色。

 


在这层,理应不是简单的数据接入,而是要考虑一定的数据清洗,比如异常字段的处理、字段命名规范化、时间字段的统一等,一般这些很容易会被忽略,但是却至关重要。

2.2. 数据来源层→ ODS 层

这里面也主要分两种类型:

1、每日定时任务型:比如我们典型的日计算任务,每天凌晨算前一天的数据,早上起来看报表。 这种任务经常使用 Hive、Spark 或者生撸 MR 程序来计算,最终结果写入 Hive、Hbase、Mysql、Es 或者 Redis 中。


2、实时数据:这部分主要是各种实时的系统使用,比如我们的实时推荐、实时用户画像,一般我们会用 Spark Streaming、Storm 或者 Flink 来计算,最后会落入 ES、Hbase 或者 Redis 中。

2.3. 过去是怎么分层的?

早起的数仓设计会分很多层,本例就分了 6 层,其中去掉元数据后,还有 5 层。下面分析一下这个设计思路。

 


1、缓冲层(buffer)

又称为接口层(stage),用于存储每天的增量数据和变更数据,如 Canal 接收的业务变更日志。


2、明细层(ODS, Operational Data Store,DWD: data warehouse detail)是数据仓库的细节数据层,是对 STAGE 层数据进行沉淀,减少了抽取的复杂性,同时 ODS/DWD 的信息模型组织主要遵循企业业务事务处理的形式,将各个专业数据进行集中,明细层跟 stage 层的粒度一致,属于分析的公共资源。


3、轻度汇总层(MID或DWB, data warehouse basis)

轻度汇总层数据仓库中 DWD 层和 DM 层之间的一个过渡层次,是对 DWD 层的生产数据进行轻度综合和汇总统计(可以把复杂的清洗,处理包含,如根据 PV 日志生成的会话数据)。轻度综合层与 DWD 的主要区别在于二者的应用领域不同,DWD 的数据来源于生产型系统,并未满意一些不可预见的需求而进行沉淀;轻度综合层则面向分析型应用进行细粒度的统计和沉淀。


4、主题层(DM,data market 或 DWS, data warehouse service)

又称数据集市或宽表。按照业务划分,如流量、订单、用户等,生成字段比较多的宽表,用于提供后续的业务查询,OLAP 分析,数据分发等。


5、应用层(App)

应用层是根据业务需要,由前面三层数据统计而出的结果,可以直接提供查询展现,或导入至 Mysql 中使用。

 

2.4. 如何更优雅一些?

前面提到的一种设计其实相对来讲已经很详细了,但是可能层次会有一点多,而且在区分一张表到底该存放在什么位置的时候可能还有不小的疑惑。我们在这里再设计一套数据仓库的分层,同时在前面的基础上加上维表和一些临时表的考虑,来让我们的方案更优雅一些。

下图,做了一些小的改动,我们去掉了上一节的 Buffer 层,把数据集市层和轻度汇总层放在同一个层级上,同时独立出来了维表和临时表。

 


1、DWS轻度汇总层,从 ODS 层中对用户的行为做一个初步的汇总,抽象出来一些通用的维度:时间、ip、id,并根据这些维度做一些统计值,比如用户每个时间段在不同登录 ip 购买的商品数等。这里做一层轻度的汇总会让计算更加的高效,在此基础上如果计算仅 7 天、30 天、90 天的行为的话会快很多。我们希望 80% 的业务都能通过我们的 DWS 层计算,而不是 ODS。


2、DWD这一层主要解决一些数据质量问题和数据的完整度问题。比如用户的资料信息来自于很多不同表,而且经常出现延迟丢数据等问题,为了方便各个使用方更好的使用数据,我们可以在这一层做一个屏蔽。


3、DIM这一层比较单纯,举个例子就明白,比如国家代码和国家名、地理位置、中文名、国旗图片等信息就存在 DIM 层中。


4、TMP每一层的计算都会有很多临时表,专设一个 DWTMP 层来存储我们数据仓库的临时表。

 

 


Q&A

问答一: dws 和 dwd 的关系

问:dws 和 dwd 是并行而不是先后顺序?

答:从图中看出,他们是并行的

 

问:那其实对于同一个数据,这两个过程是串行的?

答:dws 会做汇总,dwd 和 ods 的粒度相同,这两层之间也没有依赖的关系

 

问:那这样 dws 里面的汇总没有经过数据质量和完整度的处理,或者单独做了这种质量相关的处理,为什么不在 dwd 之上再做汇总呢?我的疑问其实就是,dws 的轻度汇总数据结果,有没有做数据质量的处理?

答:ods 直接到 dws 就好,没必要过 dwd,我举个例子,你的浏览商品行为,我做一层轻度汇总,就直接放在 dws 了。但是你的资料表,要从好多表凑成一份,我们从四五份个人资料表中凑出来了一份完整的资料表放在了 dwd 中。然后在 app 层,我们要出一张画像表,包含用户资料和用户近一年的行为,我们就直接从 dwd 中拿资料, 然后再在 dws 的基础上做一层统计,就成一个 app 表了。当然,这不是绝对,dws 和 dwd 有没有依赖关系主要看有没有这种需求。

 

问答二: ods 和 dwd 的区别

问:还是不太明白 ods 和 dwd 层的区别,有了 ods 层后感觉 dwd 没有什么用了。

答:我是这样理解的,站在一个理想的角度来讲,如果 ods 层的数据就非常规整,基本能满足我们绝大部分的需求,这当然是好的,这时候 dwd 层其实也没太大必要。但是现实中接触的情况是 ods 层的数据很难保证质量,毕竟数据的来源多种多样,推送方也会有自己的推送逻辑,在这种情况下,我们就需要通过额外的一层 dwd 来屏蔽一些底层的差异。

 

问:我大概明白了,是不是说 dwd 主要是对 ods 层做一些数据清洗和规范化的操作,dws 主要是对 ods 层数据做一些轻度的汇总?

答:对的,可以大致这样理解。

 

问答三:app 层是干什么的?

问:感觉数据集市层是不是没地方放了,各个业务的数据集市表是应该在 dwd 还是在 app?

答:这个问题不太好回答,我感觉主要就是明确一下数据集市层是干什么的,如果你的数据集市层放的就是一些可以供业务方使用的宽表表,放在 app 层就行。如果你说的数据集市层是一个比较泛一点的概念,那么其实 dws、dwd、app 这些合起来都算是数据集市的内容。

 

问:那存到 Redis、ES 中的数据算是 app 层吗?

答:算是的,我个人的理解,app 层主要存放一些相对成熟的表,能供业务侧使用的。这些表可以在 Hive 中,也可以是从 Hive 导入 Redis 或者 ES 这种查询性能比较好的系统中。

 


总结

数据分层是数据仓库非常重要的一个环节,它决定的不仅仅是一个层次的问题,还直接影响到血缘分析、特征自动生成、元数据管理等一系列功能的建设。


另外,每一层的名字不必太过在意,自己按照喜好就好。

本文分享了对数据仓库的一些理解和想法,不一定准确也不一定通用,但是可以作为一个参考的思路。有什么问题欢迎多交流。