注文章参考公众号:大数据技术派
数仓工作中的常见问题及解决方案https://mp.weixin.qq.com/s/zMt6v80-Koge7J7K1D1g9w
目录
一.数据仓库现状
业务增长速度快,取数需求激增、下游应用场景对数据质量、响应速度、数据时效性的要求越来越高。根据数仓数据的流转链路,从业务系统侧[【上游】->数仓内部->数据应用【下游】、梳理各环节存在的问题。(数仓建设中遇到什么难题?业务方面,技术方面)
1.1业务系统侧【上游】
数据仓库首先需要对业务系统的结构化数据、日志数据及埋点数据等进行汇聚。在对接过程中,主要存在以下问题:
- 缺乏业务系统数据变更的通知机制:针对已经入仓的业务系统数据、后期结构发生变更(例如:表的schema信息变更)没有及时告知数仓,而是下游用数者发现问题后通知数仓(数仓很容易背锅)。
- 数据不一致:业务方不理解数仓数据清洗、治理过程,经常将业务库的数据和数仓ads层数据进行比较,数仓开发人员需要花费较多时间去解释数据加工的过程。
1.2数仓内部
公司创建初期,数据量小、数据需求不多、数据应用场景比较单一,只需要简单支撑下游的bi报表或数据大屏等。但随着业务迅速增加,数据量暴涨,数据应用场景多样化,逐渐暴露出以下问题:
- 缺乏数仓规范流程:缺少一套标准规范去指导开发者对数仓进行规范化建设,烟囱式开发、跨层引用等现象频繁出现,此外还存在命名不规范问题,例如同义不同名,同名不同义等。(数据规范)
- 缺少数据质量全链路保障(数据质量)
- 敏感数据表/列未做权限管控,风险数据对外暴露(数据安全)
- 未被使用/引用模型较多,有些表未设置生命周期(存储成本)
- 存在空跑任务,数据倾斜任务、运行时间过长任务(计算成本)
1.3数据应用侧【下游】
数仓需要为不同应用服务(风控、数分、BI看板、用户标签等)提供数据,下游主要存在以下问题:
- 不知道数据被访问:下游对数据使用情况缺乏监控与记录,数据价值无法量化。
- 没有自助取数工具:缺乏自主取数平台,数仓大部分的时间被临时取数的需求占据,无法专注数仓模型的构建。
二、如何解决问题
2.1业务系统侧【上游】
与业务系统侧协同配合、沟通协作流程让双方聚焦在公共目标上,从而一起去赋能数仓价值。以下是针对事前、事中、事后提出的解决方案。
- 事前:与上游建立通知机制、业务迭代或数据变更及时同步数仓;如果有平台的话,可以结合数据血缘去做,如果没有平台,可以通过wiki等进行变更记录和同步。此外,还需要制定一些业务标准,主要有以下几条原则:
(1)指标需求提出
由业务方负责指标需求提出及业务口径定义。在xx项目中,我们会定期和业务方、数据产品进行需求对接及需求评审,评估指标核算的可行性、任务优先级及任务排期。
(2)指标定义规范化
由研发辅助业务方进行指标的规范定义,拉齐口径以达成指标认知一致性这个目标。
(3)指标迭代:
研发负责指标管理及迭代,保障指标从创建、审核上线到消亡的整个生命周期。
- 事中:通过技术手段捕捉上游元数据信息(例如表的schema信息)与字典值变更,用于业务追踪溯源(这块指代的就是数据血缘)。
- 事后:复盘优化协同流程。
2.2数仓内部
数仓内部主要是从流程规范等几个维度去解决此类问题。
2.2.1制定数仓建设规范
主要包括数据模型设计规范、数仓公共开发规范、数仓各层开发规范、数仓命名规范。
2.2.1.1数据模型设计规范
2.2.1.1.1数仓分层原则
优秀的数仓体系需要清晰的数据分层结构,即要保证数据层的稳定又要屏蔽对下游的影响,并且要避免链路过长。数仓分层没有最好,只有最合适。一个好的分层架构,要有以下好处:
- 数据血缘追踪:厘清表/任务上下游依赖关系、方便问题溯源及bug定位。
- 屏蔽业务侧改造对下游的直接影响:
(1)一旦业务系统改造,涉及到ods原始层表变动,会导致下游依赖的数据链路级联改动。
(2)如果直接从ods原始层取数,存在业务侧数据质量问题污染下游的风险。
- 减少重复开发:公共的指标口径(ads层)下沉至dws层、提升逻辑复用性、减少后期不必要的开发,从而减少资源消耗,保障口径、数据统一。
- 复杂问题简单化:每一层都有他的作用域和职责,使用表的时能更方便的定位和理解;
数仓分层要结合公司业务进行,基于维度建模理论,一般将数仓架构分为:ods原始层、dwd明细数据层、dws汇总数据层、ads应用层。对于每一层的职责、边界、和建模标准进行了清晰地定义。如下图所示:
分层架构 | 层次职责 | |
原始层ods | 与业务系统基本同构;目的: 保留历史数据,解耦业务数据库 | |
明细数据层dwd | 1.一般和ods层一样的数据粒度,对数据进行清洗整合,字段统一,枚举统一,格式统一等,依照维度建模事实表。 2.为了提高数据明细层的易用性,该层会采用维度退化的手法,将维度退化到事实表中,减少维表和事实表之间的关联。 | 维度层dim 1.维度用于描述业务实体所处的环境 |
汇总数据层dws | 结合业务目标,基于明细层dwd做纵向汇总和横向汇聚,整合汇总成分析有一个主题域的服务数据,一般是宽表.目标:指标轻度汇总,通用逻辑沉淀。 | |
数据应用层ads | 1.该层级的主要目的是支持业务进行某些经营专题的分析。这里的数据指标会按照业务的具体需求进行设计和包装; 2.一般会根据特定的数据统计口径进行不同交叉维度的计算,用于其他系统的底层数据支持、数据看板可视化展示;3.一般该部分数据口径更加精准化,更贴切于用户经营目标的分析和监控。 |
2.2.1.1.2主题域划分原则
数仓主题域:主题域通常是联系较为紧密的数据主题的集合,根据业务需求分析的视角进行划分抽象归类。主题域划分的方法一般有以下几种:
- 按照业务过程划分
一个业务过程抽象出一个主题域,比如业务系统中的商品、交易、物流等
- 按照业务部门划分
一个业务部门抽象出一个主题域,比如中台部门、业务运营部门、供应链部门等
- 按照业务系统划分
一个业务系统抽象出一个主题域,比如搬家系统、erp系统等
2.2.1.1.3数据模型设计原则
数据模型:组织数据的方式,模型设计一般遵循以下几个原则:
- 高内聚、低耦合、强复用
主题内部高内聚、 不同主题间低耦合,适度通过中间表的方式实现逻辑复用。
- 核心模型和扩展模型要分离
建立核心模型与扩展模型体系,核心模型包括的字段支持常用的核心业务,扩展模型包括的字段支持个性化或少量应用的需要。尽量不要让扩展模型的字段过度侵入核心模型,以免破坏核心模型的架构简洁性与可维护性。模型健壮性评估:既能高效的呈现现有业务的数据组织方式,也能灵活的支撑新增业务接入时的主题扩展需求;
- 公共处理逻辑下沉及单一
将公共逻辑下沉到中间层(例如:dws,dwm层)开发udf函数的方式进行逻辑封装),不要让公共的处理逻辑暴露给应用侧,不要让公共逻辑在多处同时存在,避免数据不一致。
- 成本与性能平衡
适当的数据冗余可换取查询和刷新性能,不宜过度冗余与数据复制。
- 数据可回滚
处理逻辑不变,在不同时间多次运行数据结果确定不变。
2.2.1.1.4数据模型管理的目标
- 扩展性
提升模型变化的兼容性,让底层的业务变动与上层需求变动对模型冲击最小化,以业务需求支持效率和降低核心模型表数量为目标。
- 易用性
降低下游使用门槛,复杂逻辑前置;通过冗余维度和事实表,公共计算逻辑下沉,明细与汇总共存等为业务提供灵活性,以数仓丰富度为目标。
- 成本
避免烟囱式的重复建设,节约计算、存储成本,人力成本。
- 时效性
提升数据模型产出时效以及需求响应的速度。
2.2.1.2数仓公共开发规范
2.2.1.2.1层次调用规范
标准数据流向应当是ODS原始层–> DWD明细层–> DWS公共层–> ADS应用层,应用层应优先调用公共层数据,不允许应用层跨过公共层从 ODS 层重复加工数据,ODS穿透率是衡量数仓建设好坏的指标之一。(ODS穿透率:从ODS -> DWS 或 ODS ->ADS)
2.2.1.2.2数据类型规范
ODS层的数据类型应基于源系统的数据类型映射转换。StarRocks中的数据类型参见官网。 基于 ODS层的字段加工,衍生出来的字段按照以下标准执行:
- 金额:double或者decimal(28,6)控制精度等,明确单位还是分或者元。
- 字符串:string
- Id类和整形数值:bigint
- 时间类:一般string,如果有特殊的格式要求,可以选择性使用date、datetime
- 状态:string
2.2.1.2.3数据冗余规范
一个表做宽表冗余维度属性时,应该遵循以下建议准则:
- 冗余字段要使用高频,下游3个或以上原则
- 冗余字段引入不应造成本身数据产生过多的延迟
- 冗余字段和已有字段的重复率不应过大,原则上不应超过60%
2.2.1.2.4 空值处理原则
- 汇总指标的空值:空值处理、填充为零。
- 维度属性值为空:在汇总到对应维度上时,对于无法对应的统计事实、记录行会填充为-99(未知),对应维表会出现一条-99(未知)的记录。
2.2.1.3数仓各层开发规范
2.2.1.3.1 ODS层设计的规范
同步规范:
- 全量初始化同步和增量同步处理逻辑要清晰;
- 以统计日期和时间进行分区存储;
- 目标表字段在源表不存在时要自动填充处理。
数据质量:
- 全量表需要配置唯一性字段标识;
- ODS表数据量级和记录数做环比监控;
2.2.1.3.2 DIM层设计的规范
公共维度层设计准则有:
- 一致性
公共维度在不同的物理表中的字段名称、数据类型、数据内容需要保持一致(历史原因导致的不一致的话,需要做好版本控制)。
- 维度的组合与拆分
(1)组合原则
如果两个维度具有强关联性,可以将其组合后一起查询。
(2)拆分成核心表、扩展表原则
根据业务关联性及下游使用频率等因素,将维表分为核心表、扩展表进行设计;核心表相对字段较少,刷新产出时间较早。扩展表字段较多,且可以冗余核心表部分字段,刷新产出时间较晚,适合数据分析人员使用。
(3)适当冗余原则
数据记录数较大的维度表(例如:用户表),可以适当冗余一些子集合,以减少下游join次数(以空间换时间)
2.2.1.3.3 DWD层设计的规范
事实表可以分为:事务性事实表、累积性事实表、周期性事实表。(待补充)
- 事务型事实表设计准则
- 累积性事实表设计准则
- 周期性事实表设计准则
2.2.1.3.4 DWS公共汇总层设计规范
- 公共汇总层的设计原则
(1)不跨数据域
数据域是在较高层次上对数据进行分类聚集的抽象。
(2)区分统计周期
在表的命名上要能说明数据的统计周期,如_1d表示最近1天,_td表示截至当天、nd 表示最近n天。
- 汇总的步骤
(1)第一步:确定聚集维度
维度可以理解为指标分析的角度
(2)第二步:确定一致性上卷
“钻”相对于“维度”而言,作用在于其可以改变维度的层次,变换分析的粒度。向上钻取就是上卷,向下钻取就是下钻。举例:将下单金额按照时间维度向上聚集得到汇总数据,如最近一个月的GMV;把交易流水沿着时间维度向下细探到每个用户产生的明细流水数据,这就叫做下钻。
(3)第三步:确定聚集事实
确定聚集的度量值,例如:GMV交易额、商品销售总量等。
2.2.1.4数仓各层命名规范
2.2.1.4.1 ODS层的命名规范
表命名规则:{层次}.{源系统表名}.{时间单位与增全量},i表示增量,f表示全量,d表示天,h表示小时。
- 增量数据:{project_name}.s{源系统表名}_di
- 全量数据:{project_name}.s{源系统表名}_df
- ODS ETL过程的临时表:{project_name}.tmp{临时表所在过程的输出表}{从0开始的序号}
- 按小时同步的增量表:{project_name}.s{源系统表名}_hi
- 按小时同步的全量表:{project_name}.s{源系统表名}_hf
- 字段命名规范:字段默认使用源系统的字段名
- 字段名与关键字冲突时,在源字段名后加上_col,即源字段名_col
- 同步任务命名规范:任务名建议和表名保持一致
2.2.1.4.2 DIM层的命名规范
公共维度表的命名规则:{project_name}.dim{/pub}{维度定义},其中的pub与具体业务无关,代表公共维度在各个业务系统都可以共用,例如时间维度可以命名为dim_pub_time。
2.2.1.4.3 DWD层的命名规范
通常需要遵照的命名规范为:dwd_{业务板块/pub}{数据域缩写}{业务过程缩写}[_{自定义表命名标签缩写}] _{单分区增量全量标识},pub表示包括多个业务板块的数据。单分区增量数据用i表示,全量数据用f表示。例如承包地库的承包地块事实表(全量)可以命名为:dwd_cbd _cbdk _df
2.2.1.4.4 DWS层的命名规范
公共汇总事实表命名规范:dws_{业务板块缩写/pub}{数据域缩写}{数据粒度缩写}[{自定义表命名标签缩写}]{统计时间周期范围缩写}。关于统计实际周期范围缩写,离线计算包括最近一天(_1d),最近N天(_nd)和历史截至当天(_td)三个表。对于小时表(无论是天刷新还是小时刷新),都用_hh 来表示。对于分钟表(无论是天刷新还是小时刷新),都用_mm来表示。
总结:数仓建设的规范性评估从以下几个角度去衡量:
待补充~