产品战略专家梁宁确认出席AICon北京站,分享AI时代下的商业逻辑与产品需求 了解详情
写点什么

伴鱼数仓演进

  • 2021-08-14
  • 本文字数:4674 字

    阅读完需:约 15 分钟

伴鱼数仓演进

伴鱼离线数仓建立,与伴鱼的业务一起快速发展,从一条业务线,到多条业务线。在演进的过程中,有很多总结和沉淀的内容。本篇文章主要介绍伴鱼离线数据仓库的发展历史,在发展过程中遇到的各种问题,以及针对问题的解决方案。

业务介绍



首先介绍伴鱼的主要业务线,流量型产品:伴鱼绘本,业务型产品:伴鱼 AI 课,伴鱼少儿英语等十几条业务线:

  • 伴鱼绘本:承担着给其他业务线导流的功能,其核心业务流程是,用户注册 app 为起点,app 内广告访问,app 内听读录绘本功能的使用,以及 VIP 的购买、转化。

  • 伴鱼少儿英语:用户核心链路涉及到的实体多,用户申请试听成为少儿英语用户,先触达到销售,然后分配老师,再完成上课,购买课程,然后分配班主任。

  • AI 课:用户购买体验课成为 AI 课的用户,通过分配到运营,运营转化用户购买正式课。


由于各个业务线有互相交叉的部分,比如:数学业务使用少儿业务的班主任作为销售售卖课程、业务线之间也可以互相引流等。导致实体数据之间的关系复杂度较高。


在伴鱼数据仓库部门主要的工作内容:


  • 各个业务线的产品需求支持。

  • 给算法、分析团队数据特征的加工与提供。

  • 公司指标体系的设计与搭建。

  • 数据仓库的底层建设与维护。

  • 全公司数据的收集与整合。

  • 研发团队数据需求提供。

数仓前世


在伴鱼数仓建设之前,数据部门会给各个业务线提供数据支持,当时的业务需求比较少,内容和形式也相对简单。


当时的做法:


  • 业务开发人员自己写 python 脚本。

  • 直连数据库,查询需要的数据。

  • 基于内存计算结果。

  • 将结果数据写出到对应存储 DB。

  • 开发报表展示页面,提供数据报表,或通过邮件将数据结果发送给业务方。


以上数据支持流程足以应对当时业务不太复杂的伴鱼公司,但是随着公司的发展和业务线的增加,对数据的需求量以及需求复杂度都在增加和提高,以上流程的开发效率就显得捉襟见肘,主要体现在以下问题:


  • 数据无法沉淀:脚本产生的中间结果都是存储内存,数据没有任何沉淀。

  • 脚本维护较为困难:不同开发人员写在不同目录下,文档缺失。

  • 数据稳定性得不到保证:脚本历史数据无沉淀,导致每次计算未必可以保证幂等。

  • 开发效率低:由于数据无沉淀,导致使用任何数据都需要重新开发,同一个数据,每个使用方都需要自己开发逻辑。


为了解决以上问题伴鱼开始构建自己的数据仓库。

数仓建设

数仓 1.0

2019 年 Q3 之前,整体数据情况是:数据体量小,团队人员不足,底层表调整频繁,业务灵活多变,要求响应速度快。建设目标:快速响应需求,以最少的人力支持全公司的业务决策需求。基于当时的背景和目标,数仓架构主要是基于 TIBD 构建的 3 层数仓结构,原始数据层、base 层、stat 层。数据整体架构如下图:



数据层级浅,针对主题只抽象出一个层级,保证底层数据可复用即可。其中数据源,出现了日志进入到 hive 的步骤是因为:


  • 数仓基于 TIDB 构建,所有数据都需要同步至 TIDB。

  • 业务形态导致,早期的流量数据不作为重点关注内容,日志数据主要在 hive 中存储,需要使用的数据同步至 TIDB。


随着业务的发展,数据量的增多,业务形态越发复杂。基于 TIDB 构建的数仓已经无法满足要求,主要体现在:


  • 数据口径难以保持一致,虽然基于原始数据构建了 base 层,但是在数据开发的过程中为了满足特殊的需求也经常直接使用原始数据。

  • 日志数据使用日益增多,导致计算能力无法达到要求。

  • 数据库报警频繁,维护成本过高。

  • 当时的 TIDB 版本不支持窗口函数,自定义函数等功能。

  • 难以配合大数据生态体系工具。

数仓 2.0

针对上述问题,从以下几个方面进行了调整:


  • 明确职责划分。

  • 数仓基础平台由 TIDB 更换为 HADOOP 生态体系。

  • 制定数仓建设规范、开发流程。

  • 数仓整体架构的调整,明确新的分层方式,进行更加细化的建模。

职责划分


目前伴鱼数仓团队,承接公司全部业务线的数仓建设工作,对接公司内部各个业务线,每条业务线的形态不同,数据的使用方式也不同。


基于当前能力该如何解决上述问题?调研后发现大体有如下几种方式:


方式一(分总形式):


​业务线或部门自建数仓,各个业务线分别建设自己的数仓,数仓与数仓之间无直接关系,使用其他业务线数据,通过权限申请拉取使用,或通过 FTP 文件的形式同步数据。例如运营商各个省份的数仓是独自建设的,可能由不同的厂商承接建设,在建设后以统一的格式推送至总部,再在总部进行进一步的数据清洗。


方式二(分层形式):


​ 划分基础数仓与应用数仓,基础数仓通过自下而上,面向于主题的方式进行设计,更加专注的做好底层建设。应用数仓通过自上而下,面向于应用的进行开发,更好的支持业务需求。很多大厂当前都是以这样的方式设计,集团总部负责总部的开发与设计,业务线使用总部加工的数据宽表或事实表进行业务开发,如果遇到新的数据表。需要给基础数仓提需求,由基础数仓排期开发。



方式三(总分形式):


​业务线内垂直建设,横向设计,纵向开发,统一设计并制定数仓整体规范,各个业务线按照统一的规范进行各自业务线的开发。跨业务线使用数据需要申请相应的数据权限,了解其表结构与口径,直接使用其他业务线数据。在中小型企业中,业务线杂而多,但是业务线内部也没有数据开发人员,使用这种方式成本较低,并且可以快速响应业务需求。



伴鱼内部也针对以上的部分方式进行思考与尝试:


方式一,自建数仓,这样会带来以下问题:


  • 如果每个团队自己都有一套小的数仓架构,对公司资产来说是资产冗余。

  • 没有一套专业的数据资产对外提供。

  • 每个团队对数仓的认知和理解程度不同,会导致数据无法公用并沉淀。

  • 数据口径、数据质量难以保障。


基于以上问题,数仓是由数据中台统一建设。未对此方式进行尝试。


方式二,分层建设,遇到的问题:


  • 响应及时度达不到业务要求:业务需求要求当天提供数据,如果遇到基础数仓未建模的业务,无法及时提供。

  • 沟通成本高:一个口径不同的研发人员需要反复沟通多次。

  • 不同层级的目标不一致:基础数仓的目标是合理的建设模型,模型排期是以周为单位,应用数仓则是快速响应业务需求。

  • 变动兼容时效性差:业务方对于数据表的调整往往是较为随意的,表有调整或改动基础数仓感知时效性差。

  • 应用数仓自建底层模型:为了快速响应业务需求,应用数仓研发自己开发了所需的 DW 层表,等基础数仓开发完后,无时间进行迁移改造,造成新的烟囱式问题。


方式二最主要的问题是,业务反馈数仓团队效率变低,无法快速响应需求。


方式三,横向设计,纵向开发,遇到的问题:


  • 规范细节统一问题:目前未通过统一的建模工具进行建模,很多新的名词未纳入统一设计的规范中。

  • 跨业务线使用数据 SLA 保障问题:使用其他业务线数据时,如果该表进行调整,可能影响整体调度时间。

  • 部分基础表建设出现重复:类似于烟囱式开发导致的问题,部分小的公共业务表被重复建设。

  • 对人员素质要求较高:需要所有人都可以从数据建模,到上层应用开发都可以高质高效的完成。


方式三最主要的问题是,规范的统一,烟囱式的开发问题。


综上,伴鱼内部确定了当前业务场景下较为合理的职责划分方式,以方式三为主,并进行了部分优化:


  • 公共数据统一建设:用户、设备、公众号、消息等 10+个公用业务数据,统一进行设计与建设,避免烟囱式开发。

  • 然后跨业务线数据关联:由于 DW 层是统一数仓建设层,如果在此层使用了其他业务数据,会导致模型不稳定,会依赖于其他业务线数据的稳定性。增加 DM 层用于跨业务线数据的关联,通过保证 DW 层的数据稳定,达到使用 DW 层数据链路的 SLA。

  • 统一建模工具:数据建模使用统一的工具可以保证公司内全域数据字段的统一。

  • 明确分析师的职责:多条业务线对于分析师的定位不同,边界划分不同。

数仓整体架构



ODS:贴源层,离线或准实时接入的数据,接入多种数据源。


DWD:明细数据层,整合原始数据,有两部分操作:

1)对 ODS 层的数据做一定的清洗和加工,规范化;

2)进行维度建模,对数据表进行单个业务过程的宽表化,冗余维度。


DWS:轻度汇总层,对单个主题的多行为进行宽表化处理(不跨主题)。

DM:数据集市层,对多个主题,跨主题,跨业务线的整合型数据表,面向挖掘,数据分析等。

ADS:应用层,高度汇总数据,面向业务的结果数据。

其中 ODS 层数据源由平台提供数据抽取能力,保证数据的同步,DW、DM、ADS 层统一由数据仓库团队负责。

层级规范


ODS:将各种源的数据接入到 HIVE 中,保留原始数据结构信息。主要数据来源:数据库数据、日志数据、外部数据。


数据库数据:主要两种数据源,一是 MONGODB;二 TIDB,分别通过 oplog 和 binlog 进行同步,可选择以增量或全量的方式进行。


日志数据:通过 Flink 消费 Kafka 中的数据,存储到 HDFS 中。使用较多的是埋点数据,中台统一了 Web 、安卓、Ios 三端的 SDK,保证不同端使用相同的上报形式,并可进行测试,监控来保证埋点的质量。

外部数据:通过统一的清洗,通过工具进行上传,存入 HIVE 表中。


DWD:先规范化数据,再进行维度建模。


对于第一步规范化,很多人认为没有必要,直接划分业务流程,做维度建模就可以完成 dwd 层的建设。思考以下几点:


  • 业务数据表的更换。

  • 业务逻辑变动的兼容。

  • 增量表数据的 merge。

  • 数据字段名称以及类型的一致性。


这些都是数据常见的操作,如果将这些动作与维度建模和合并成一个步骤,建模的物理模型将是混乱的,在伴鱼内部,将此步骤单独构建,产生标准化的表,方便下一步维度建模使用。如:用户级别变化表 ODS 层为增量拉取,DWD 层标准化:增量表 merge ,字段、类型标准化,兼容算法定级,模型定级数据表。保证用户级别变动可从一张表产出。


第二步维度建模,构建思路:


  • 业务建模:梳理业务过程,划分主题。

  • 逻辑建模:确定粒度、确定维度、确定事实。

  • 物理建模:产出单一主题的事实表。


DWS:融合多业务过程,形成对应主题的轻度汇总宽表。构建思路:


  • 确定主题包含的所有业务过程。

  • 丰富业务过程的维度属性。

  • 确定原子指标,建设指标体系。


注意:DWS 表虽然跨业务过程构建,但是不跨主题,保证每个主题下数据的完整性和准确性。

如:交易主体,仅包含与交易有关的业务过程,包括支付、退费等。


DM:面向于业务线、跨主题,构建思路:


  • 梳理业务相关的主题。

  • 确认粒度,构建跨业务的宽表。

  • 冗余其他业务线的相关数据指标。


如:用户行为数据,业务线内从用户注册到用户使用的行为数据汇总,到在其他 app 内的下单,支付等行为数据的冗余。该层面向于对应业务线分析挖掘等,更加方便使用。


ADS:数据应用,按照应用场景进行开发,构建思路:


  • 确认数据开发口径。

  • 确定查询引擎。

  • 产出相应需求。


下图是某业务线在此规范下的整体设计:



未来规划


未来,期望可以真正做到,通过数据赋能业务,驱动业务,更好的体现数据价值,主要体现在以下几方面:


  • 基础能力:保障数据链路的稳定,以及数据的 SLA,通过监控,提前发现异常的调度链路,及时优化。

  • 数据质量:通过数据质量监控体系,保证产出数据的质量,在数据异常波动时可以快速发现问题,定位问题。

  • 数据支持:更好的支持对接的各个业务系统,从而提高整体数据价值。

  • 建模工具:通过统一的建模工具,保证全场景建模,数据产出更加可靠,通过工具使模型的建设更加规范。

  • 指标管理工具:指标体系建设是数据高效使用的第一步,通过指标管理工具管理,原子指标,派生指标。减少沟通成本,保证指标口径。

  • 数据应用:用户画像系统,用户行为分析系统的提供可以简化很多分析工作,提高分析效率,使分析师更好的为分析决策提供支持。

参考资料



作者:彭旭冬

原文:https://tech.ipalfish.com/blog/2021/06/14/datawarehouse_devlopment/

原文:伴鱼数仓演进

来源:伴鱼技术博客

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2021-08-14 08:008671

评论

发布
暂无评论
发现更多内容

最新软件测试技术-2024

Geek_e575df

大公司的Java面试题集

程序员李木子

Java Java 面试题

2024-04-13:用go语言,给定一个整数数组 `nums`, 请编写一个函数,返回一个新的数组 `counts`。 满足以下条件:对于每个 `nums[i]`, `counts[i]` 表示在

福大大架构师每日一题

福大大架构师每日一题

C语言常见命名规范

百度搜索:蓝易云

Linux 运维 C语言 代码 云服务器

springmvc开启异步请求报错Java code using the Servlet API or by adding "true" to servlet and

百度搜索:蓝易云

云计算 Linux 运维 云服务器 Spring MVC

支付系统概述(六):收银台

agnostic

支付系统设计与实现

事业-最佳实践-编码-命名规范

南山

最佳实践 代码质量 命名规范 类命名 方法命名

鸿蒙HarmonyOS实战-ArkTS语言(基本语法)

蜀道山

typescript 鸿蒙 HarmonyOS 鸿蒙系统 ArkTS

《自动机理论、语言和计算导论》阅读笔记:p139-p171

codists

编译原理

Spring高手之路17——动态代理的艺术与实践

砖业洋__

spring aop JDK动态代理 CGLIB动态代理

事业-最佳实践-编码-日志输出规范

南山

最佳实践 日志 代码质量 日志规范 编码基础

对某个通用字段进行加解密或者是脱敏处理

想要飞的猪

数据脱敏 字段加密

一座计算“立交桥”,让新质生产力从湘江水畔到中国大地

脑极体

算力

内联和嵌套命名空间

爱分享

C++11 C++20 C++14 嵌套命名空间 内联命名空间

鸿蒙原生应用《隐私协议静态共享库》

坚果

HarmonyOS HarmonyOS框架

鸿蒙原生应用三方库《日历转换器》

坚果

HarmonyOS 坚果派 HarmonyOS框架

个人介绍-第一篇博文

Geek_e575df

事业-最佳实践-编码-类大小衡量方式

南山

最佳实践 代码质量 单一职责 类大小 编码最佳实践

PrismNET棱镜协议,十问十答让你少走“弯路”

PrismNET

区块链 人工智能 dapp PrismNET棱镜协议 PrismNET

一款基于AB32VG1的桌面智能坞

梦笔生花

程序设计 开发板 12864 OLED液晶显示屏

鸿蒙HarmonyOS实战-ArkTS语言(状态管理)

蜀道山

鸿蒙 HarmonyOS 鸿蒙系统 ArkTS

Vite配置环境变量以及反向代理请求

百度搜索:蓝易云

云计算 Linux 运维 vite 云服务器

JavaScript判断数组是否包含某个值的6种方法

百度搜索:蓝易云

JavaScript Linux 运维 代码 云服务器

十个小白问题,帮你快速了解Sora

蓉蓉

openai ChatGPT4 sora

一个“敏捷”项目复盘的思考

Bruce Talk

敏捷开发 Agile 回顾会 Retrospective

事业-最佳实践-编码-单元测试-提升代码可测试性

南山

最佳实践 测试 单元测试 代码质量 可测试性

MyBatis关联关系映射详解

百度搜索:蓝易云

云计算 Linux 运维 mybatis 云服务器

伴鱼数仓演进_架构_伴鱼技术团队_InfoQ精选文章