首先介绍一下爱奇艺公司整体的业务情况以及数据仓库 1.0 的设计和出现的问题,针对数仓 1.0 的缺陷,是如何演进到数仓 2.0 架构以及数仓 2.0 需要解决的问题和需要达成的目标。
这张图非常清晰的展示了爱奇艺的产品矩阵,早期爱奇艺是视频业务,后来从视频业务周边衍生出来一些新的业务,以视频业务为主围绕着核心 IP,衍生出短视频、小视频、奇巴布、爱奇艺阅读、叭哒、泡泡、奇秀直播、爱奇艺知识、体育、电商等众多业务,从苹果树到苹果园构建了泛娱乐生态矩阵。
可以看到产品矩阵中涉及的业务很多,每个业务都会产生自己的数据,同时也有着自己独特的产品形态。既要满足在某个特定业务场景下进行面向业务的数据探查和分析,还要基于跨多个业务场景下,从多个业务共性的角度去提取、淬炼通用的数据,实现跨业务横向的探索分析,从而实现指导业务、对业务进行数据赋能的目标。同时,每个业务之间也会相互辅助、作用,导致每个业务之间会有频繁的数据交互。
数据仓库 1.0
数据仓库 1.0 的架构图如上,整体分层分为 5 个部分,最下面是原始数据层,再上面分别是明细层,聚合层以及应用层,右边是面向整个数仓的维度层,用于管理一致性维度。
-
原始数据层用于保存原始数据,数据来源于各种数据生产系统,主要分三个部分:Pingback投递,在每个业务产品进行统一规范的埋点,然后将采集到的数据进行上报,最后通过自动化处理将埋点数据进行解析、存储;业务数据库,主要是业务后端产生的数据,例如会员订单、文学订单等等,经过数据集成的手段将业务库的数据直接同步到原始数据层进行保存;第三方外部数据,主要来自企业外部的数据源。
-
明细层用于还原业务过程,保存最细粒度的数据,对原始数据按照不同的模式进行ETL处理,完成数据清洗和部分业务逻辑处理等过程。
-
聚合层存放的是非明细的数据,通常是经过各种计算以后得到的轻度聚合和重度聚合数据,主要采用维度建模方法进行构建。
-
应用层是为了满足业务需要而产生的结果化数据,具有很强的定制性,主要提供给相关数据应用、外部系统,以及对特定数据有需求的人员使用。是数据仓库和外部的接口,主要对接其他系统,如业务库、报表系统等。
纵观数仓 1.0 架构,整个数仓的体系其实还是按照业务的角度去建设,每个业务都会建立符合自己业务特点的一个小型数据仓库,可以快速的响应业务需求,同时做到灵活多变,支撑业务决策。但随着数据增长、业务场景更加复杂,缺少公共数据的提炼和汇总,出现烟囱式重复建设、指标口径不统一、数据有二义性、生产/使用效率低下等问题,同时也缺乏工具平台的有利支撑。
当不同业务之间有数据交叉的场景时,为了尽快响应业务需求,直接从其他业务明细层甚至原始数据层获取数据,这个时候很容易出现指标统计口径的不一致。缺少公共聚合数据的沉淀和积累,出现很多数据重叠的现象,导致烟囱式重复建设,资源消耗成本高居不下。在数仓 1.0 建设过程中,虽然有一套比较完整的数据仓库规范,但是缺少工具平台的支持和管控,经常出现同名不同义,或者指标口径有二义性的现象,加重了下游的使用成本和开发效率。比较典型的场景是在业务线 A 下有一个维度,在业务线 B 下也有一个维度,但是这两个维度拥有相同的名字,而且在每个业务线下代表的含义或者属性是不同的,这个时候如果想面向这两个业务去做一些数据的交叉探查会消耗很多的线下沟通和排查成本。
数据仓库 2.0
针对 1.0 的缺陷,我们对数仓架构进行了升级,并逐渐向数据仓库 2.0 时代演进。在数仓 2.0 设计之初,首先需要明确大方向和目标。
-
明确分层和组成,以及不同部分的定位和相互关系。
-
规范化、标准化整个数据建模流程,之前因为缺少工具支持,无法体现数据建模工作的必要性和重要性,因此提供一套完整的工具平台实现从0到1辅助数据仓库2.0的整体建设。
-
这是个永远绕不开的话题,数据一定要保持口径统一。不管从哪个产品线或者业务线出来的数据,统计口径要一致、明确,没有二异性。
-
提高效率,结合前三点,将整个数仓架构梳理清晰,尽量降低数据之间横向的复杂交互,保持数据流向的清晰、简洁,解决烟囱式重复建设,从而提高生产、使用效率,降低成本。
数仓 2.0 的诞生,是为了解决 1.0 时代面临的各种数据问题,使数据工作产生更大的价值。通过统一口径、规范命名、建立统一的指标和维度体系、使用标准化的建模方式等手段,打通和标准化公司数据,同时下沉通用逻辑来提升计算效率,降低使用成本;配套多种数据中台工具,可以让更多的人员参与到数据使用和分析工作中来,使数据决策深入到公司的每一个角落,达到数据驱动发展的最终目标。
纵观整个数据仓库 2.0 架构,从分层来讲跟 1.0 的区别不大,主要分为原始数据层、明细层,汇总层、应用层以及统一的维度层,上图可以看出,对整个数仓组成做了较大调整,划分为三个部分,分别为统一数仓、业务集市和主题数仓,同时也明确了每个组成部分的分工、定位以及相互之间的数据引用流向。
最底层是统一数仓,主要分为统一明细数据层和统一聚合数据层。明细层负责对接下层所有的原始数据,百分之百还原所有业务域和业务过程的数据,同时屏蔽底层原始数据变动对上层造成的影响,是整个数仓 2.0 的底层基础。通过明细层完成业务关系到数据关系逻辑转换,并补充相关的维度,保存最细粒度数据,进行复杂业务逻辑分离、数据清洗、统一规范化数据格式等 ETL 过程。聚合层负责对通用的指标进行沉淀,向上提供统一口径的计算指标,同时避免重复计算。除此之外,还会提供基于 OneID 体系的统一累计设备库和新增设备库供上层使用。
业务集市主要以业务诉求为主,建设满足业务分析的各种数据集合。在业务集市建设过程中,我们按照尽可能细的粒度去划分业务集市,且每个业务集市之间不会出现数据依赖和横向引用,在应用层可以跨集市进行汇总计算对外提供数据服务。这样做的好处是,如果出现一些组织架构调整或者工作职责的变更等情况,每个业务集市无需调整,只需在应用层做相应的修改即可,同时也避免因为计算任务代码混在一起、数据权限拆分等问题带来的数据变更成本。
主题数仓以公司范围内公共的主题域/主题角度,以一致性维度为基础,跨各业务做数据的整合分析和相关建设,包括流量数仓、内容数仓、用户数仓等。
应用层包括业务报表、内容分析、用户运营等数据应用产品,按照具体的场景和需求,从业务集市和主题数仓获取数据。
说完数仓 2.0 整体架构,再来明确和总结下数仓各个组成部分的定位。
-
统一数仓提供底层全面且通用的数据并作为规范的制定者和约束者,为上层提供数据和底层模型,是数据仓库建设的基础。
-
业务集市是基于统一数仓的数据和模型,结合业务数据分析目的,按照业务的特色去建设满足各个业务的数据集合。
-
主题数仓也是基于统一数仓的数据和模型,面向不同实体的分析,建设用户、内容等领域的数据集合。
业务集市跟主题数仓建设时,尽量保持高内聚和低耦合的原则,防止数据流向过于复杂、层次过于深、不同层次之间依赖混乱而导致后期的维护成本、开发成本越来越大。
数仓建设
下面介绍如何基于数仓 2.0 架构和一致性维度/指标体系,构建数仓平台,规范化数仓建模流程。
数据仓平台的架构如上图,最底层的是基础服务,最终生成的物理表可能会有 Hive、MySQL、Kafka,ClickHouse 等。再往上一层是工单管理、权限管理、资源管理,作为平台的辅助功能。工单管理用来对维度/指标的创建/修改操作进行审批,我们专门成立了数据仓委员会来对维度/指标的制定进行把控,同时结合实际情况,对数仓建设进行相应调整。权限管理对不同用户的操作权限进行管理,根据开发者权限展示相应的入口。
数仓管理和数据模型模块是整个数仓平台的核心。数仓管理负责对数仓建设过程中需要的原子组成部分进行抽象的整合管理,主要包括业务管理、主题管理、维度管理、指标管理等。只有在这些基础环节准备好的情况下,才能进行后续的数仓建模工作。我们把数据建模分为三个环节,分别为业务建模、数据建模和物理建模,在后面会针对每个环节进行详细阐述。
数仓平台对外提供统一的 API,包括维度和指标,用于对接其他周边系统以及最上层的产品应用。例如在报表系统对指标定义、计算口径、说明进行统一的展示,确保指标在数据生产-使用的流转过程中传达准确的信息。数仓平台将数据建模过程产生的元数据信息统一推送到元数据中心,用于数据图谱服务进行数据发现和数据理解。
在介绍数据建模流程之前,先讲下一致性维度和指标体系的建设。目前数仓建设主要基于维度建模理论,所以一致性维度是底层的基石。在数据仓平台中,我们把维度分为三种类型,分别是普通维度、枚举维度和虚拟维度。
普通维度,最常见的维度类型,通常有一张对应的维表存在,每个维度都由一个主键和多个维度属性组成,如用户维度,内容维度等;枚举维度,是普通维度的一种特例,也称为字典维度,列举以及标准化枚举值以表示维度对象,以 Key-Value 的形式存在,例如:是否 XX,0 代表否,1 代表是;虚拟维度没有具体业务实体承载、没有可固化数据范围逻辑定义的维度对象,例如随机数、会话 ID 等。
创建维度时,需要补充一些标签属性,例如维度的英文名、中文名、描述、通用性,它所属的实体(例如:时间、空间、应用等),其中通过“通用性“把维度分为业务维度和通用维度:如果某个维度只能被一个业务使用,定为业务维度,也就是说它的适用范围只能在某一个业务下,其他业务不可用;会被两个及以上的业务使用,定义为通用维度。实际上,两种类型会随着时间而产生变化,一个维度在开始阶段只被一个业务使用,但随着业务的发展,后期会被多个业务使用,当业务维度升级成通用维度时,构建业务维度的通用维度镜像。
一个维度会包含若干维度属性,每个维度属性包含英文名、中文名、数据类型、说明等,同时需要定义维度属性最终在物理表中的字段名称,以此来实现数仓范围内的同名同义和全局唯一性。
关于维度建设理论,这里不再详细展开,有兴趣的同学可以网上搜索相关文章和书籍进行了解和学习。
指标体系
指标体系由指标元数据(原子指标元数据和复合指标元数据)、修饰词、时间周期、统计指标(原子指标和复合指标)组成。
指标元数据: 是统计指标的一种抽象,所有的指标必须派生于某个指标元数据。
原子指标元数据/度量: 是业务过程中不可再拆解的最小单元,一般是由 动作 + 计量组成,同时,原子指标元数据等同于度量,是描述一个事实的计量单位;元数据是指针对某种业务过程事实的一种抽象,如果不加修饰词和时间周期,不能代表具体的统计意义。
复合指标元数据: 是多个原子指标元数据或复合指标元数据通过计算处理得到的,是对复合指标的一种抽象,如果需要作为统计指标使用需要增加对应的时间周期和修饰词,如点击率、占比、转化率等。
修饰词: 修饰词可以被理解为统计指标存在的环境,用于明确统计指标的具体含义、细化口径的描述,每个统计指标可以有一个或者多个修饰词存在,和维度属性可以相互转化,如:北京的用户、电影频道页等。
时间周期: 时间周期是用来描述统计指标的时间范围,可以认为是一种特殊的修饰词,并且在统计指标中,这个特殊的修饰词是必须明确的,如:当日、最近 30 天等。
统计指标: 分为原子指标和复合指标,是指标元数据的实例化,代表了具体的事实衡量指标。
原子指标: 原子指标=一个元指标+多个修饰词(可选)+时间周期,是描述一个业务过程的统计意义,如:最近一天播放次数等。
复合指标: 是通过多个原子指标或复合指标计算获得的,描述多个业务过程的关系,如:最近一天播放完成率,最近 30 天人均启动次数等。
指标体系在数据仓平台中的管控非常严格,指标相关的构建一般需要经过开发、产品、分析师、业务多方合作,结合实际场景需求系统化、规范化总结和提炼出来的。
建模流程
统一数仓建模是业务层建模的基础,需要涵盖尽可能多的业务过程和维度,包括业务建模、数据建模和物理建模三个阶段。
业务建模是基于业务已有信息,结合建模同学对业务的理解,对业务进行梳理,此时不会面向具体的分析细节,确认范围主要是业务域、业务过程和实体之间的关系,输出业务总线矩阵。业务建模的目的是为了对业务需求进行分解,转化为数据理解,包括的具体流程有:划分业务域、确认业务过程、设计事件事实,确认相关实体、关联事件、构建业务总线矩阵。
▇ 业务域划分,业务域是业务过程的集合,是对业务各个环节的粗粒度划分,将相关的业务过程聚集到一个业务域下,例如播放域。
▇ 确认业务过程,业务过程是业务中的原子行为,不能再进行拆解,我们需要在业务建模过程中,确认有哪些业务过程,并明确业务过程所属的业务域,一个业务过程只能属于一个业务域。
▇ 设计事件事实。
▇ 确认相关实体,从较粗的粒度确认一个业务过程涉及到的实体范围,防止遗漏分析角度,同时为关联事件实体提供联接节点。
▇ 关联事件事实,统一数仓建模需要将已有的事件事实字段都涵盖到,并通过实体进行更多维度的关联。
▇ 构建业务总线矩阵,横纵坐标分别为描述事实本身的业务域、业务过程,以及描述事实环境的维度和实体。
数据建模阶段主要是为了将业务总线矩阵进行细化,完成业务关系到数据关系逻辑转换,并补充相关的维度,输出星型(雪花)模型。
▇ 确认业务,一般不跨业务,针对单个业务进行建模。
▇ 确认业务过程,可以面向单个或者多个业务过程。
▇ 确认维度,业务过程中包含的维度。
▇ 确认度量,业务过程中涉及到的度量。
▇ 退化维度属性,为了下游使用更加高效,把一些通用的维度属性退化到明细层模型,尽量减少与维表之间的 join 操作,提高效率。
▇ 构建星型模型,指导后续开发操作。
物理建模实际上是对数据模型的物化过程,物化过程会根据不同引擎在流程上有细微差别,最终将数据模型物化成 Hive 的物理表/视图,甚至是带有 Schema 结构的 Kafka Topic,下面以 Hive 物理表为例描述整个过程。
▇ 确认数据模型,选择需要物化的数据模型。
▇ 确认表名,根据数仓规范补充完善表名信息,例如计算周期、表类型、业务信息等。
▇ 确认描述/使用说明,补充对表信息的中文描述以及使用注意事项。
▇ 确认分区字段,例如天级、小时级。
▇ 确认生命周期,根据数据重要性,设置数据保留的时间范围,例如 30 天、1 年等。
▇ 生成物理表,同时将表的业务元数据信息录入到元数据中心,与模型完全对应,表名、字段名、字段类型等信息标准化、统一化。
如之前所述,统一数仓作为底层模型和数据的基础来源,业务集市/主题数仓基于已有的底层模型进行建模,主要包括数据建模,物理建模(当然,可以通过统一数仓业务建模阶段输出的业务总线矩阵更加了解业务)。
业务层数据建模的目标是输出主题的数据星型模型,根据不同的主题和分析场景,选取相关的业务过程,使用合理的建模手段进行数据建模,主要流程包括:确认主题、选取业务过程、确认粒度、确认维度、确认统计指标,最终输出星型模型。
▇ 根据具体的分析需求确认主题。
▇ 确认需要分析的业务以及业务过程。
▇ 确认统一数仓模型,系统自动推荐相关的模型,选择满足条件的模型,并在此基础上进行后续建模工作。
▇ 确认粒度,相同粒度模型可以进行指标的合并。
▇ 确认维度,选取后续需要下钻分析的维度,选取过程是在业务过程的范围内进行,不能超出维度能够关联的范围。
▇ 确认统计指标,选取业务过程相关的度量(原子指标元数据)派生的统计指标。
▇ 构建星型模型。
物理建模流程与之前所述相同,不再重复介绍。
下图是数据建模阶段产出的星型模型实例,在模型图中,将关联的业务信息和数据逻辑进行清晰的表达,辅助后续数据开发工作。
数据图谱
数据图谱以元数据为中心,提供完整、标准的元数据查询能力,降低数据发现和数据理解的成本,构建核心数据资产目录,提高数据使用效率。
下图是元数据中心的架构图,在底层使用开源框架 Atlas,并针对性的进行二次开发,JanusGraph 存储元数据信息和数据血缘,ES 提供统一的元数据搜索服务。
元数据中心主要负责元数据的采集管理,以及数据血缘的构建。元数据可以分为技术元数据+业务元数据,通过不同的平台或者不同的底层基础服务组件进行自动化同步和采集,例如通过 HiveHook 方式,自动采集 Hive 表的技术元数据信息,同时数仓平台负责将建模过程中的业务元数据信息同步到元数据中心。与此对应,数据血缘构建通过两部分实现,第一部分通过 HiveHook、SparkHook 机制,当 SQL/计算任务运行完成后,自动解析输入表和输出表,同时截取 SQL/计算任务提交时的工作流任务信息,自动化注入血缘;另外,在大数据开发平台中,公司内部有自研的一套数据集成产品(BabelX),也实现了 Hook 机制,对数据血缘进行了集成支持。第二部分是向周边系统服务定期拉取输入/输出关系实现的。我们已经打通了从 Pingback-BI 报表的全链路血缘,实现通过任何一个节点向上/向下追溯整条血缘链路的源头/末端。
在以往,开发或者使用过程中,如果需要数据,大部分都是通过线下沟通的方式,找产品、找开发,经过若干轮的不懈努力才能找到,这种方式会消耗很大的沟通成本和人力成本。当找到数据后,又面临着如何理解数据、如何正确使用数据,即使有着良好的文档规范,也难免出现更新不及时、信息表达不准确甚至某种信息无法在文档中进行表达。如果命不好或者信息传递不准确,还会出现找到的数据和预期不符,需要重新进行沟通寻找。基于元数据中心,我们建设了数据图谱服务,用于数据发现和数据理解,在数据图谱建设时,有着清晰和明确的目标:创建高效的环境,支持快速的“找数据”,直观的理解和使用数据,实现指导数据开发、提高开发效率等“用数据”需求。
“找数据“,也就是数据发现,需要提供基于“某种共识”的关键字搜索能力,比如维度组合、指标组合,自动呈现匹配符合目标维度+指标矩阵的数据,并结合排序、二次筛选功能,逐渐缩小目标范围,进行最终定位。如果搜索非标准化的信息,例如描述,可能出现的现象是表达不准确/二义性造成的误导。同时,也需要结构化目录或者向导式查询的功能,能够以简单、快捷的方式看到业务的全景展示以及业务下面有哪些数据。例如,数仓地图提供列表模型和图谱模型:列表模式以目录方式展示数据表、维度、指标,展示数据表所属业务、主题等信息,经过简单筛选进行浏览定位;图谱模式以拓扑图形式对所有业务和业务过程/主题进行图形化汇总,展示业务和数据模型全景,根据向导进行逐层筛选,最终定位目标数据。
“用数据”,也就是找到数据之后,如何高效的理解数据体现的业务信息并正确的加以利用。因此,面向数据使用场景构建一个元数据的知识图谱,获取相关的技术元数据和业务元数据并进行友好分类展示,例如:基础信息包括数据所属项目、负责人、权限审批人员等;业务信息包含数据所属业务、业务域、主题域等;数仓标签包括中文名、说明、主题模型、维度/指标等;数据资产信息包括资产等级、SLA、质量分数等。
以 Hive 表为例,将 Hive 所有相关的信息全部采集到元数据中心里面,并按照标签方式进行分类,让数据使用者可以通过搜索、目录浏览等方式快速的找到数据,同时全方位的理解数据表达的业务含义,方便使用。
数据血缘
如之前所述,我们构建了从 Pingback-BI 报表的全链路血缘,在每个对应的环节都注入了输入/输出信息以及对应的工作流任务信息,数据血缘的价值不再过多阐述。通过数据血缘可以进行影响评估、故障排查、链路分析等工作。例如,当数据链路中某张表出现了质量问题需要进行修复回溯数据或者表进行了大的升级,需要下游配合迁移,可以通过数据血缘导出所有的下游表、对应的工作流任务以及 Owner,能够帮助数据的生产者或者管理者快速协调下游进行变更操作。新员工可以通过血缘更加清晰的了解整个数仓构建流程,对此,数据血缘工具提供了链路剪枝和过滤功能,当数据下游过多时,通过根据某些条件进行剪枝和过滤,方便清晰的查看某条分支链路。当 BI 报表达到下线标准时,可以通过全链路血缘找到对应链路的计算任务进行下线,解决上线容易下线难的问题,提高资源利用率和节省成本的目的。
基于全链路数据血缘的另一个应用是资产定级,在数据治理环节,我们首先要对数据进行资产定级打标,从而根据不同级别指定相应的治理策略,级别越高,对 SLA、数据质量的要求越高。资产定级打标通过自动化+手动打标实现,在数据血缘的末端,也就是数据应用,以 BI 报表为例,每张报表会有重要级别标签,结合数据血缘,向上回溯,实现对数据资产自动化打标工作。因为所有数据并不是都会生成报表,所以只能通过人工标注的方式。在后续的工作中,我们希望通过数据服务进行收口,也就是对数据 API 进行等级划分,将数据 API 集成到全链路血缘,打通数据 API-数据应用的血缘,从而更加全面的自动化覆盖数据资产等级标签。
总结和展望
最后,简单做下总结和展望,介绍下我们目前正在进行以及后续的一些工作方向,在后续数据中台的建设中,我们希望能够做到智能化、自动化、服务化、模型化。
智能化
用数据质量平台建设举例说明,以往通常的做法是,平台提供自定义质量规则校验和稽查能力,开发者通过人工方式进行规则和阈值设置,当表数量越来越多时,会消耗大量人力成本,即使凭借专家经验,也无法做出将节假日因素计算在内的动态阈值方案。我们目前正在尝试的一种方案是,采集数仓核心字段并制定通用的数据质量规则(例如表行数、去重数、空值率等),自动采集历史数据进行样本收集和训练,对未来走势进行预测,设置动态阈值,实现数据质量的自动化覆盖,一方面节省人力,另外一方面在智能预测的过程中可以考虑节假日因素,提高数据质量监测的准确性,减少由于节假日出现的误报。
自动化
基于数仓平台将数据建模的工作进行规范化、流程化,在后续的工作中,积累沉淀出一些通用的模型和流程,实现自动化代码生成。
服务化
在以往,数据对接数据应用/业务时,大部分都是直接访问底层数据源,这就造成了数据接入方式多种多样,接入效率低下、数据和接口无法共享、底层数据变更,影响数据应用等问题。在现有数据中台建设过程中,我们建设统一的数据服务,数据以 API 方式作为与数据应用/业务中台进行统一交互,来解决上述问题。
模型化
数据模型屏蔽了底层物理实现,同时以标准、规范的方式阐述了业务信息和数据关系逻辑。在未来,我们希望面向用户的不是各种物理表,而是模型。用户只需要选择对应的业务、筛选需要的维度和指标,就可以自动路由到模型上,再依据模型和底层物理表的依赖关系,结合联邦查询的能力,自动生成查询任务,访问最合适的物理表,将数据输出给终端用户。