- 话聊
建设数仓
- ETL
工具
面临的问题
- 分层
分层的出发点
分层设计
- 模型建设
为什么要建设模型
怎么建设模型
理清工作思路
实施步骤
建模方法及实施
- 规范建设
临时表管理
代码规范
流程规范
话聊
技术升级快于我们的想象,今天的故事在明天来看就是一种常识。对于数仓而言,又何尝不是?互联网的发展,导致大数据的人才缺口。互联网公司雨后春笋,传统行业机巧转身。短短几年,数据行业已沧海桑田。今天谈大数据已不复当年雾里看花的景象,它像一列更高速的快车,和老前辈们一样,向自己的终点加速。
回到主题,最近负责一个数据中台项目的建设,从0到1的建立数仓。模型建设,参考维度模型的方式。通过维度+事实,支持业务数据需求。走了不少弯路,在这里总结总结,更希望和大家交流
建设数仓
什么是数仓,为什么建设数仓,怎么建设数仓?(我是谁,我从哪里来,我到哪里去)
Inmon将数据仓库定义为:在企业管理和决策中面向主题的、集成的、与时间相关的、不可修改的数据集合。数据仓库的目标:数据资产、决策信息
系统层面
- etl过程:打通你的任督二脉(离线+实时),让数据在整个环节中流通起来
- 数据分层:一套(低耦合、高内聚)的层级,是十分重要的。总不想业务、数据等一变化,数仓像有投胎了一次
- 数据集成:多业务场景下,打破数据信息壁垒,避免数据歧义,统一数据服务
- 规范化:良好的流程化、规范化设计,会带来易维护、高扩展
- 监控与辅助:质量监控、调度管理、元数据管理、信息安全管理
- 走向服务:对外api服务/自助查询平台/OLAP分析平台
- 实时数仓:接触不多,有机会再写
协作层面
- 与后端开发协同:上游依赖,需要有一个良好的通道,保证信息共享和联动响应
- 与分析/业务握手:下游服务,需求方是多个的,即可能是分析,也可能是运营/boss,先理解他们,在让他们理解你
- 迭代数仓:只要业务在发展,数仓就需要不断更新;响应业务变化,丰富数据模型
个人角色
- 责任:做好数据集成,保持数据准确,树立数仓权威
- 工作安排:简单的事情复杂化,复杂的事情简单化(简单的事情想着系统化,复杂的事情想想流程化,标准化)
- 沟通:鲁迅说过,双赢才是真理。
- 掌握技能:优化查询、高效存储、模型理论
ETL
因为数据应用场景的不同,数据存储方案也有较大差异。内部常用的mysql/Mssql/oracle和hive/hbase/MongDB,外部数据交互的excel/csv/txt/api等。
要求
- 业务场景覆盖
业务数据往往涉及多种数据源,数据存储也常常会有多种选择。文本数据、日志数据、RMDB、Nosql等。则要求etl工具能够覆盖这些业务场景。 - 性能
业务特性在数据上,往往常有波峰波谷。在波峰是否能够hold住。比如常见的双11,618等消费节日。而且伴随业务脚步的扩展,能否面对后期的数据量增长 - 扩展性
从源端进行数据etl工作,当数据结构变化、数据删除、数据源变更、数据类型,在这样的情况下,就需要更好的扩展性,保持与数据质量监控、元数据管理的交互。
工具
datax/sqoop/kettle/informatica等等
应该要满足
- 连续性的数据,不应该从某个时间点进行数据删除;不应该修改已有的数据
- ETL一般为最开始的部分,凌晨之后的时间点。a:避免集中式的对某个jdbc海量同步,影响业务(部分从库可能提供查询服务)、b:明确调度的时间,应尽可能的在某个时间段内完成(不能仅依靠调度,实现任务流的串行;为后期的大作业空间,占用等待的系统资源)
- 应记录数据同步过程中,涉及的元数据。包括:作业详情、开始/结束时间、消耗资源量、过程状态等
面临的问题
- 当源数据结构变化(如mysql的一张表增加字段),如果低成本的扩展,实现业务零感知。应该在一开始的设计时,被考虑到。可通过元数据监控,自动实现动态的数据扩展。
- 数据加载错误(字段类型、数据缺失、多表同步、归档加载、空值异常)
分层
分层的出发点
我想用身边的房子来描述来描述分层设计。分层从直观的角度出发,是一种层次/功能关系。数仓中体现为: ods/dw/dm。每一层都干着自己的事情,像房子中的厨房、卫生间、客厅。你总不想还在睡眠中,被别人清晨的第一股清流所吵醒。
对于数仓而言,层一是解决功能界线,厨房只干着做饭炒菜的事情;二是解决问题隔离及快速定位,厨房的烟味不要跑到卧室去;如果有烟味请打开排气扇。
分层设计
设计原则
- 层级清晰
- 功能明确
- 内部无依赖
常用分层结构
- Stage缓冲层
事务性数据,每日增量方式进行数据同步。需要注意数据同步时的边界问题,避免脏数据。对于非事务性数据,一般通过快照/全量更新。不对外开放数据查询 - ODS层
一般场景下,我们认为该层数据与线上保持一致。实际处理过程中,为了处理时间维度上的数据变化,会记录数据的变化轨迹(缓慢变化维)。对于该部分数据,应该有选择性的实施,避免业务处理过程变得复杂和问题发生后难以回溯。 - DIM/DW层(模型层)
在ods层基础之上,设计一个宽表层/模型层,通过维度建模的方式,实现维度数据与事实数据的分离(星型模型)。此外,丰富宽表以弥补星型模型的未覆盖之处。以此高覆盖业务场景需求 - DA层(应用层)
面向不同的应用,聚合类的数据层。该层对于DIM/DW层的使用,是对模型层的一个检视维度
面临的问题
数据分层实际解决的是,不同层级之间的边界,做到井水不犯河水(高内聚低耦合)。实际工作中,应结合业务处理过程,对涉及的数据加工流程,确定相应的功能边界,并遵守和监控。虽如此,依然会面临一些问题。
- 历史数据重现: 所依赖的数据有误,如DIM依赖的ods层数据,有问题。问题数据可能是当日,也可能是一段时间内。DIM历史数据如何更新为正确数据
- 性能问题:对于日志数据、大型事务数据,在更新数据时存在的性能低下
- 分层重构:在一开始分层设计中,将某些流程冗余到另一个层级中。前期应怎么处理,以及后期如何进行低成本剥离
模型建设
数据仓库,是一个工程性的建设,而非独立的模块开发。从大局出发,看待数仓建设,要考虑与源数据的交互,质量的监控,如何对外提供数据服务等。而在这些工作中,模型的建设可以说是灵魂式的存在。满足集成性、历史性、分主题的要求,覆盖业务多场景需求,提供决策性企业数据。
水无定势,兵无常法。不同的行业,有不同的需求,不同的模型解决不同的问题。
为什么要建设模型
- 进行全面的业务梳理,改进业务流程。在业务模型建设的阶段,能够帮助我们的企业或者是管理机关对本单位的业务进行全面的梳理。通过业务模型的建设,我们应该能够全面了解该单位的业务架构图和整个业务的运行情况,能够将业务按照特定的规律进行分门别类和程序化,同时,帮助我们进一步的改进业务的流程,提高业务效率,指导我们的业务部门的生产。
- 建立全方位的数据视角,消灭信息孤岛和数据差异。通过数据仓库的模型建设,能够为企业提供一个整体的数据视角,不再是各个部门只是关注自己的数据,而且通过模型的建设,勾勒出了部门之间内在的联系,帮助消灭各个部门之间的信息孤岛的问题,更为重要的是,通过数据模型的建设,能够保证整个企业的数据的一致性,各个部门之间数据的差异将会得到有效解决。
- 解决业务的变动和数据仓库的灵活性。通过数据模型的建设,能够很好的分离出底层技术的实现和上层业务的展现。当上层业务发生变化时,通过数据模型,底层的技术实现可以非常轻松的完成业务的变动,从而达到整个数据仓库系统的灵活性。
- 帮助数据仓库系统本身的建设。通过数据仓库的模型建设,开发人员和业务人员能够很容易的达成系统建设范围的界定,以及长期目标的规划,从而能够使整个项目组明确当前的任务,加快整个系统建设的速度
怎么建设模型
怎么建设,可能是大家最关心的一点。让我们从另一个角度想想,谁应该建设模型?或者谁应该参与到模型的建设中?
理清工作思路
- 谁应参与模型建设
一个模型的成功好坏可能有很多层面。但模型不能解决某个或某一些问题,显然是失败的。那么,业务人员应该参与,应该他们是需求的出发者 - 模型建设人员要做什么
数仓人员的工作界定,到底在那里?他们负责哪些某块?是指导业务梳理,还是业务提出模型需求。企业的规模、组织架构都会影响到这个选择。但最终的模型落地,应由模型人员确定,并给出对应的设计。 - 哪些支持
没有高层的重视,模型建设就像盖烟囱
实施步骤
业务模型 --> 领域模型 --> 逻辑模型 --> 物理模型
业务建模 生成业务模型,主要解决业务层面的分解和程序化
| 划分整个单位的业务,一般按照业务部门的划分,进行各个部分之间业务工作的界定,理清各业务部门之间的关系
| 深入了解各个业务部门的内具体业务流程并将其程序化
| 提出修改和改进业务部门工作流程的方法并程序化
| 数据建模的范围界定,整个数据仓库项目的目标和阶段划分
领域建模 生成领域模型,主要是对业务模型进行抽象处理
| 抽取关键业务概念,并将之抽象化
| 将业务概念分组,按照业务主线聚合类似的分组概念
| 细化分组概念,理清分组概念内的业务流程并抽象化
| 理清分组概念之间的关联,形成完整的领域概念模型
逻辑建模 生成逻辑模型,主要是将领域模型的概念实体以及实体之间的关系进行数据库层次的逻辑化
| 业务概念实体化,并考虑其具体的属性
| 事件实体化,并考虑其属性内容
| 说明实体化,并考虑其属性内容
物理建模 生成物理模型,主要解决,逻辑模型针对不同关系型数据库的物理化以及性能等一些具体的技术问题
| 针对特定物理化平台,做出相应的技术调整
| 针对模型的性能考虑,对特定平台作出相应的调整
| 针对管理的需要,结合特定的平台,做出相应的调整
| 生成最后的执行脚本,并完善
建模方法及实施
建模的方法论,当前主流的Immon的范式建模,Kimball的维度建模,还有一个Data Vault(数据湖)。不同的建模方式,其实是从不同的角度来看待这个世界。由于实际过程中使用维度建模的方式较多,我们以维度建模来示例模型建设
- 选择业务过程
在确定业务过程前,应该了解企业经营范围,对各个业务线有较为清楚的了解。面对不同的业务过程,应该业务专家确定业务所涉及的过程,如电商,涉及下单、付款、发货、退货等。有一个业务主线架构。
基于主线结构,选择一个简单且重要的业务过程。明确核心指标(事实)和模型考评标准,为后期检视定下基调。 - 确定粒度
粒度,是一个不能再拆分的细分。如订单事实,还可以拆分为订单下的商品。最细粒度便于后期扩展,不用考虑因为统计口径变化时,模型不可用或要进行大改的担忧。 - 确定维度
维度,是描述事实的环境。是where、when、who、how的回答。而不同的业务过程,对于维度的考虑是不同的。订单事实关系,如订单量、订单金额、商品渗透等。如果是采购过程,更关系每个商品的采购价、采购量、库存周转问题了。 - 确定事实
事实,是对发生的事务的度量。如买条裤子35元,买了5斤牛肉等
实际的模型建设过程中,更多的问题像是在一个迷宫中,不知出路是哪一条。个人的建议,和业务专家握手,了解多少业务过程,将模型的主线结构划分清楚。 基于主线结构,选择最重要的业务过程,梳理当前业务需求中集中的问题和关切点。以此为出发点,进行需求扩展。
需求扩展时,应从维度表开始,如常见的时间维度、商品维度、自然人维度等。将维度表确认后对事实进行丰满,采用维度建模方式,事实表中仅储存维度的键。
规范建设
临时表管理
数据处理过程中,不得不用到临时表(中间表),一般认为临时表是没有储存意义的,但是又不能立马删除,或结束后删除(有时候过程有问题,你还得依靠过程表找原因呢!或是你想避免对功能库的污染,在temp库中进行数据备份)。如果没有一套生命周期去约束临时表的话,将不得不面临临时表的库储存爆炸问题。那么如何处理呢?
- 约定一套统一的临时表命名方式
如创建统一的临时库(如TEMP)。要求该库中的数据表全部删除并不影响业务。命名规则根据数据处理过程而定,不同的命名指定的含义不同。 - 表生命周期
针对不同的表,周期有限。制定统一的表删除策略
代码规范
- 脚本格式规范
脚本头部注释编写规范、注释规范、sql规范google规范参考 - 文件/表命名规范
一个文件中,只应该有一张表,其余只能是临时表;表名称应与文件名称相同 - 字段命名规范
去除多词同义,和同词多义问题。尤其是在模型层(一般也叫做一致性维度)
流程规范
最重要的就是流程了,明确各个步骤需要完成的事项,减少代码出错风险。
参考
- 浅谈数据仓库建设中的数据建模方法
- 数据仓库工具箱:维度建模权威指南(第三版)