伴鱼离线数仓建设案例

2024-01-13 12:36

本文主要是介绍伴鱼离线数仓建设案例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

伴鱼数仓建设案例

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

业务介绍

datawarehouse_devlopment

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

  • 伴鱼绘本:承担着给其他业务线导流的功能,其核心业务流程是,用户注册 app 为起点,app 内广告访问,app 内听读录绘本功能的使用,以及 VIP 的购买、转化。
  • 伴鱼少儿英语:用户核心链路涉及到的实体多,用户申请试听成为少儿英语用户,先触达到销售,然后分配老师,再完成上课,购买课程,后分配班主任。
  • AI课:用户购买体验课成为AI课的用户,通过分配到运营,运营转化用户购买正式课。

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

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

  • 各个业务线的产品需求支持。
  • 给算法、分析团队数据特征的加工与提供。
  • 公司指标体系的设计与搭建。
  • 数据仓库的底层建设与维护。
  • 全公司数据的收集与整合。
  • 研发团队数据需求提供。

数仓前世

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

当时的做法:

  • 业务开发人员自己写 python 脚本。
  • 直连数据库,查询需要的数据。
  • 基于内存计算结果。
  • 将结果数据写出到对应存储 DB。
  • 开发报表展示页面,提供数据报表,或通过邮件将数据结果发送给业务方。

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

  • 数据无法沉淀:脚本产生的中间结果都是存储内存,数据没有任何沉淀。
  • 脚本维护较为困难:不同开发人员写在不同目录下,文档缺失。
  • 数据稳定性得不到保证:脚本历史数据无沉淀,导致每次计算未必可以保证幂等。
  • 开发效率低:由于数据无沉淀,导致使用任何数据都需要重新开发,同一个数据,每个使用方都需要自己开发逻辑。

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

数仓建设

数仓 1.0

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

datawarehouse_devlopment

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

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

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

  • 数据口径难以保持一致,虽然基于原始数据构建了 base 层,但是在数据开发的过程中为了满足特殊的需求也经常直接使用原始数据。
  • 日志数据使用日益增多,导致计算能力无法达到要求。
  • 数据库报警频繁,维护成本过高。
  • 当时的 TIDB 版本不支持窗口函数,自定义函数等功能。
  • 难以配合大数据生态体系工具。

数仓 2.0

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

  • 明确职责划分。
  • 数仓基础平台由 TIDB 更换为 HADOOP 生态体系。
  • 制定数仓建设规范、开发流程。
  • 数仓整体架构的调整,明确新的分层方式,进行更加细化的建模。
职责划分

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

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

方式一(分总形式):

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

方式二(分层形式):

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

datawarehouse_devlopment

方式三(总分形式):

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

datawarehouse_devlopment

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

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

  • 如果每个团队自己都有一套小的数仓架构,对公司资产来说是资产冗余。
  • 没有一套专业的数据资产对外提供。
  • 每个团队对数仓的认知和理解程度不同,会导致数据无法公用并沉淀。
  • 数据口径、数据质量难以保障。

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

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

  • 响应及时度达不到业务要求:业务需求要求当天提供数据,如果遇到基础数仓未建模的业务,无法及时提供。
  • 沟通成本高:一个口径不同的研发人员需要反复沟通多次。
  • 不同层级的目标不一致:基础数仓的目标是合理的建设模型,模型排期是以周为单位,应用数仓则是快速响应业务需求。
  • 变动兼容时效性差:业务方对于数据表的调整往往是较为随意的,表有调整或改动基础数仓感知时效性差。
  • 应用数仓自建底层模型:为了快速响应业务需求,应用数仓研发自己开发了所需的DW层表,等基础数仓开发完后,无时间进行迁移改造,造成新的烟囱式问题。

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

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

  • 规范细节统一问题:目前未通过统一的建模工具进行建模,很多新的名词未纳入统一设计的规范中。
  • 跨业务线使用数据 SLA 保障问题:使用其他业务线数据时,如果该表进行调整,可能影响整体调度时间。
  • 部分基础表建设出现重复:类似于烟囱式开发导致的问题,部分小的公共业务表被重复建设。
  • 对人员素质要求较高:需要所有人都可以从数据建模,到上层应用开发都可以高质高效的完成。

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

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

  • 公共数据统一建设:用户、设备、公众号、消息等10+个公用业务数据,统一进行设计与建设,避免烟囱式开发。
  • 延后跨业务线数据关联:由于 DW 层是统一数仓建设层,如果在此层使用了其他业务数据,会导致模型不稳定,会依赖于其他业务线数据的稳定性。增加DM层用于跨业务线数据的关联,通过保证 DW 层的数据稳定,达到使用 DW 层数据链路的 SLA。
  • 统一建模工具:数据建模使用统一的工具可以保证公司内全域数据字段的统一。
  • 明确与分析师的职责:多条业务线对于分析师的定位不同,边界划分不同。
数仓整体架构

datawarehouse_devlopment

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

DWD:明细数据层,整合原始数据,有两部分操作,1)对 ODS 层的数据做一定的清洗和加工,规范化,2)进行维度建模,对数据表进行单个业务过程的宽表化,冗余维度。

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

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

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

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

层级规范
ODS

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

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

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

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

DWD

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

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

  • 业务数据表的更换。
  • 业务逻辑变动的兼容。
  • 增量表数据的 merge。
  • 数据字段名称以及类型的一致性。

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

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

  • 业务建模:梳理业务过程,划分主题。
  • 逻辑建模:确定粒度、确定维度、确定事实。
  • 物理建模:产出单一主题的事实表。
DWS

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

  • 确定主题包含的所有业务过程。
  • 丰富业务过程的维度属性。
  • 确定原子指标,建设指标体系。

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

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

DM

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

  • 梳理业务相关的主题。
  • 确认粒度,构建跨业务的宽表。
  • 冗余其他业务线的相关数据指标。

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

ADS

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

  • 确认数据开发口径。
  • 确定查询引擎。
  • 产出相应需求。

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

datawarehouse_devlopment

未来规划

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

  • 基础能力:保障数据链路的稳定,以及数据的SLA,通过监控,提前发现异常的调度链路,及时优化。
  • 数据质量:通过数据质量监控体系,保证产出数据的质量,在数据异常波动时可以快速发现问题,定位问题。
  • 数据支持:更好的支持对接的各个业务系统,从而提高整体数据价值。
  • 建模工具:通过统一的建模工具,保证全场景建模,数据产出更加可靠,通过工具使模型的建设更加规范。
  • 指标管理工具:指标体系建设是数据高效使用的第一步,通过指标管理工具管理,原子指标,派生指标。减少沟通成本,保证指标口径。
  • 数据应用:用户画像系统,用户行为分析系统的提供可以简化很多分析工作,提高分析效率,使分析师更好的为分析决策提供支持。

这篇关于伴鱼离线数仓建设案例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/601476

相关文章

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

PostgreSQL的扩展dict_int应用案例解析

《PostgreSQL的扩展dict_int应用案例解析》dict_int扩展为PostgreSQL提供了专业的整数文本处理能力,特别适合需要精确处理数字内容的搜索场景,本文给大家介绍PostgreS... 目录PostgreSQL的扩展dict_int一、扩展概述二、核心功能三、安装与启用四、字典配置方法

Python中re模块结合正则表达式的实际应用案例

《Python中re模块结合正则表达式的实际应用案例》Python中的re模块是用于处理正则表达式的强大工具,正则表达式是一种用来匹配字符串的模式,它可以在文本中搜索和匹配特定的字符串模式,这篇文章主... 目录前言re模块常用函数一、查看文本中是否包含 A 或 B 字符串二、替换多个关键词为统一格式三、提

Python get()函数用法案例详解

《Pythonget()函数用法案例详解》在Python中,get()是字典(dict)类型的内置方法,用于安全地获取字典中指定键对应的值,它的核心作用是避免因访问不存在的键而引发KeyError错... 目录简介基本语法一、用法二、案例:安全访问未知键三、案例:配置参数默认值简介python是一种高级编

MySQL中的索引结构和分类实战案例详解

《MySQL中的索引结构和分类实战案例详解》本文详解MySQL索引结构与分类,涵盖B树、B+树、哈希及全文索引,分析其原理与优劣势,并结合实战案例探讨创建、管理及优化技巧,助力提升查询性能,感兴趣的朋... 目录一、索引概述1.1 索引的定义与作用1.2 索引的基本原理二、索引结构详解2.1 B树索引2.2

从入门到精通MySQL 数据库索引(实战案例)

《从入门到精通MySQL数据库索引(实战案例)》索引是数据库的目录,提升查询速度,主要类型包括BTree、Hash、全文、空间索引,需根据场景选择,建议用于高频查询、关联字段、排序等,避免重复率高或... 目录一、索引是什么?能干嘛?核心作用:二、索引的 4 种主要类型(附通俗例子)1. BTree 索引(

HTML中meta标签的常见使用案例(示例详解)

《HTML中meta标签的常见使用案例(示例详解)》HTMLmeta标签用于提供文档元数据,涵盖字符编码、SEO优化、社交媒体集成、移动设备适配、浏览器控制及安全隐私设置,优化页面显示与搜索引擎索引... 目录html中meta标签的常见使用案例一、基础功能二、搜索引擎优化(seo)三、社交媒体集成四、移动

六个案例搞懂mysql间隙锁

《六个案例搞懂mysql间隙锁》MySQL中的间隙是指索引中两个索引键之间的空间,间隙锁用于防止范围查询期间的幻读,本文主要介绍了六个案例搞懂mysql间隙锁,具有一定的参考价值,感兴趣的可以了解一下... 目录概念解释间隙锁详解间隙锁触发条件间隙锁加锁规则案例演示案例一:唯一索引等值锁定存在的数据案例二:

MySQL 表的内外连接案例详解

《MySQL表的内外连接案例详解》本文给大家介绍MySQL表的内外连接,结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录表的内外连接(重点)内连接外连接表的内外连接(重点)内连接内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我

Java Stream.reduce()方法操作实际案例讲解

《JavaStream.reduce()方法操作实际案例讲解》reduce是JavaStreamAPI中的一个核心操作,用于将流中的元素组合起来产生单个结果,:本文主要介绍JavaStream.... 目录一、reduce的基本概念1. 什么是reduce操作2. reduce方法的三种形式二、reduce