伴鱼实时数仓建设案例

伴鱼实时数仓建设案例

文章目录

  • 伴鱼实时数仓建设案例
    • 伴鱼实时作业应用场景
    • 伴鱼实时数仓的建设体系
    • DWD 层复杂场景数据处理方案
      • 1. 数据的去重
      • 2. join场景
        • 两条实时数据流相关联
        • 对于关联历史数据
      • 3. 从数据形态观查join
    • DWS 数据层数据处理方案
    • 未来与展望

随着伴鱼业务的快速发展,离线数据日渐无法满足运营同学的需求,数据的实时性要求越来越高。之前的实时任务是通过实时同步至 TiDB 的数据,利用 TiDB 进行微批计算。随着越来越多的实时场景涌现出来,TiDB 已经无法满足实时数据计算场景,计算和查询都在一套集群中,导致集群压力过大,可能影响正常的业务使用。

根据业务形态搭建实时数仓已经是必要的建设了。伴鱼实时数仓主要以 Flink 为计算引擎,搭配 Redis ,Kafka 等分布式数据存储介质,以及 ClickHouse 等多维分析引擎。

伴鱼实时作业应用场景

基于平台提供了稳定的环境(统一调度方式,统一管理,统一监控等)。我们构建了一些实时服务,通过服务化的方式去支持各个业务方。

  • 实时数仓:数据同步,业务数据清洗去重,相关主题业务数据关联拼接,以及数据聚合提炼等,逐步构建多维度,多覆盖面的实时数仓体系。

  • 实时特征平台:实时数据提取,计算,以及特征回写。

    简单介绍下:目前数据在伴鱼内的流动架构图:

    fink-practice

伴鱼实时数仓的建设体系

  • ODS 层数据平台统一进行数据解析处理,写入 Kafka 。
  • DWD 比较关键,会将来自同一业务域数据表对应的多条数据流,按最细粒度关联成一条完整的日志,并关联相应维度,描述一个完整事实。
  • DWS 将每个小业务域数据按相同维度进行聚合,写入 TiDB 和 ClickHouse 。在 TiDB ,ClickHouse ,再次进行关联,形成跨业务域聚合数据。供业务和分析人员使用。

如图:

fink-practice

DWD 层复杂场景数据处理方案

数据从 ODS 层采集后,数据的处理和加工主要集中在 DWD 层,我们的场景中面临了很多复杂的加工逻辑,本章重点对 DWD 层数据处理方案进行详细的阐述。

1. 数据的去重

由于伴鱼内部业务大面积使用 MongoDB ,MongoDB 本身存储的是半结构化的数据,它不具有固定的 schema 。

在同步 Mongo 的 oplog 时,实时数仓的 dwd 层并不需要所有字段参与,我们只会抽取日常使用率相对较高的字段进行表建设。这就可能由于不相干的数据发生变化,我们也会收到一条相同的数据记录。

例如在对用户订单金额进行分类分析时,如果用户订单地址发生了变化,我们同样也会收到一条业务日志,因为我们并不关注地址维度,所以这条日志是无用的重复数据。这种未经处理的数据是不方便BI工程师直接使用的,甚至直接影响计算结果的准确性。

所以我们针对这种非 Append-only 数据,我们进行了定制化的日志格式。在经由平台方解析后的 binlog 或者 oplog ,我们仍然定制化加入了一些元数据信息,用来让 BI 工程师更好的理解这条数据进入实时计算引擎时,对应的时间点到底发生了什么事情,这件实事到底是否参与计算。所以,我们加入了 metadata_table (原始表名), metadata_changes(修改字段名) , metadata_op_type (DML类型) ,metadata_commit_ts (修改时间戳)等字段,辅助我们对业务上认为的重复数据,做更好的过滤。

如图:

fink-practice

2. join场景

实时计算相较于离线不同,因为数据具有一过性,流过的数据,如果不做特殊记录,很难在找回,从而降低了实时作业准确性,这是实时计算的一个痛点问题,这个问题主要表现在多流关联时,数据难以关联准确,下面叙述一下在伴鱼内部,多流 join 的场景是如何解决的。

数据关联常用的inner join ,left join 。inner join 近似可以看做 left join + where 的操作。

从时间角度来讲分为:

  • 两条实时数据流相关联。
  • 实时流与过去发生的事实数据相关联。
两条实时数据流相关联

利用 Redis 基于内存,支持单位时间大量 QPS ,快速访问的特性:

  • 首先我们应观察一定范围内数据,观察数据在时间维度上的乱序情况.设定数据延迟的时间和数据缓存时间。
  • 伴鱼的服务都相对较稳定,数据乱序最多就是秒级差异,我们通常选择数据量相对大的流做主流,对主数据流加窗口等待(窗口时间不必太长,如10s),右边数据流将数据写入 Redis 缓存(分钟级),当主流的窗口到期,确保右边流数据以及缓存在 Redis 中了。实现在 Flink job 内部多 Operator 之间的内存共享。这种方式的优点是:足够简单,通用; Flink job 无需维护业务状态,job 轻量化、运行稳定。缺点是,随着数据量的上升,以及 job 的增多,会对 Redis 集群造成较大压力。

如图:

fink-practice

Flink 作业内部,提供了完整的 user-state 状态管理,包括状态初始化,状态更新,状态快照,以及状态恢复等:

  • 将数据 leftStream 与 rightStream 分别打上不同的 tag ,将 leftStream 与 rightStream 用 contect 算子联合在一起。
    对 join 的条件进行 group by 操作,相同分组的数据,在 precess 算子内进行数据的 state 缓存与输出。下游得到的即为能关联上的数据。
  • 对状态操作的同时,调用定时器,比如我们可以按天为单位,每天凌晨设置定时器,清空状态,具体定时器触发策略,看业务场景。
  • **优点:**整个作业所有处理逻辑不依赖其他外部存储系统,均在 Flink 内部计算。
  • **缺点:**如果多个数据流关联,整体作业 code 量较大,开发成本相对较高;数据交由 Flink 状态维护,整个作业内存负载较高,数据量大的情况下,checkpoint 很大,对作业整体稳定运行有影响。

Flink 社区已经认识到多流join的痛点问题,提供了区别于离线sql的特殊join方式:

  • 对 leftStream 与 rightStream 分别注册 Watermark (最好用事件时间)。

  • 将 leftStream 与 rightStream 进行 Interval Join。

    在流与流的 join 中, window join 只能关联两个流中对应的 window 中的消息,跨窗口的消息关联不上,所以摒弃。

    Interval Join 则没有 window 的概念,直接用时间戳作为关联的条件,更具表达力。Interval join 的实现基本逻辑比较简单,主要依靠 TimeBoundedStreamJoin 完成消息的关联,其核心逻辑主要包含消息的缓存,不同关联类型的处理,消息的清理,但实现起来并不简单。一条流中的消息,可能需要和另一条流的多条消息关联,因此流流关联时,通常需要类似如下关联条件:)。

  • 优点: 编码简单;整个作业 state 的修改访问由 Flink 源码自动完成,整体 state 负载与用户手动编码相对较小。

  • 缺点: 特殊join方式受场景限制较大。

如图:

fink-practice

Flink Table & SQL 时态表Temporal Table:

  • 在 Flink 中,从1.7开始,提出了时态表(即 Temporal Table )的概念。Temporal Table 可以简化和加速此类查询,并减少对状态的使用 Temporal Table 是将一个 Append-Only 表中追加的行,根据设置的主键和时间(如上 productID 、updatedAt ),解释成Chanlog,并在特定时间提供数据的版本。

  • 在使用时态表( Temporal Table )时,要注意以下问题。

    Temporal Table 可提供历史某个时间点上的数据。
    Temporal Table 根据时间来跟踪版本。
    Temporal Table 需要提供时间属性和主键。
    Temporal Table 一般和关键词 LATERAL TABLE 结合使用。
    Temporal Table 在基于 ProcessingTime 时间属性处理时,每个主键只保存最新版本的数据。
    Temporal Table 在基于 EventTime 时间属性处理时,每个主键保存从上个 Watermark 到当前系统时间的所有版本。
    Append-Only 表 Join 右侧 Temporal Table ,本质上还是左表驱动 Join ,即从左表拿到 Key ,根据 Key 和时间(可能是历史时间)去右侧 Temporal Table 表中查询。
    Temporal Table Join 目前只支持 Inner Join。
    Temporal Table Join 时,右侧 Temporal Table 表返回最新一个版本的数据。
    

例如:

temporal_join

对于关联历史数据
  • 我们首先要分析历史数据的过期性,例如伴鱼业务场景中,用户约课行为和用户在线上课两条数据流关联到的数据,可能相差几天(用户提前约下周的课程)。
    此时数据的过期时间就需要我们特殊关系与处理,我们可以精确的计算发生的事件,它的准确过期时间,例如:例如正式上课时间为三天后,所以,我们可将他们放入 Redis 中缓存(3+1)*24 h,以确保用户上课时,他们的约课记录还仍然在我们内存中预热。
  • 如果无法判断出历史数据的过期性。例如在伴鱼的业务场景中,经常会关联用户某个重要行为(下单)时,对用的用户等级,以及绑定的教师等细节信息,类似这种常用且重要的维度,我们只能将它们永久缓存在 Redis 中,供事实数据去访问关联。

3. 从数据形态观查join

从数据join的方式来看,共分为三种,一对一,多对一,多对多三种情形。

  • 对于一对一,多对一,我们只需要用 Redis 或者 state 缓存住单一一方的数据流。
  • 对于多对多的join情形:
    多对多的 join。我们只能将 leftStream 与 rightStream 先 connect 连接起来,天级别的 将数据分别缓存至 Redis 或者 job momery中。无论 left Steam 还是 right Stream,数据来了都是统一先缓存,去遍历另一方的所有已经到来的数据,输出到下游。
  • 对于多对多的 left join 情形:
    多对多的 left join的场景,是比较复杂的,我们也只能将 leftStream 与 rightStream 先 connect 连接起来,将其缓存在 job momery 或者 Redis 中,leftSteam或者 rightStream 数据来了就先统一先缓存,再去遍历另一方的所有已经到来的数据,输出到下游。只不过此时,对于下游没有join上的数据,并不能很好的判断 数据到底是真的没有 join 上,还是因为数据进入 Operator 的时间性的差异,没有 join 上。此时我们会将数据写入 TiDB ,或者 ClickHouse 中,在这种可以基于天级别数据量快速计算的 OLAP 引擎中,对因进入 Operator 算子时间差异而导致没有 join 上的数据进行过滤。
  • 注意如果用 Flink Operator State,需要设置定时器,或者使用 Flink TTL,对 state 定时清理,不然程序会 OOM 。如果使用 Redis ,需要对数据设置失效或者定时调用离线脚本对数据进行删除。

DWS 数据层数据处理方案

我们在离线数仓中通常存放的是跨业务域的粗粒度数。在伴鱼的实时数仓内部,我们也同样是这样存储的。
只不过跨业务域的数据之间的关联,我们不在 Flink 实时处理引擎中做计算。而是把它们放到 TiDB 或者 ClickHouse 中做计算了。
在 Flink 内存,我们只计算当前业务域的聚合指标,以及会对数据进行 tag 标记,标记出数据是按哪些维度聚合而来,聚合粒度是如何的。(例如时间粒度上,我们通常会以 5min 或者 10min 为小单位对数据进行聚合),如果要查询当天跨业务的联合数据时,会基于 TiDB 或者 ClickHouse 预先定义好视图,在视图内先对当天单个业务域主题内数据先做聚合 sum ,再将不同业务域的数,按提前在数据中标记的维度 tag 进行关联,得到跨业务的聚合指标。

未来与展望

  • 未来我们仍会继续对比 Spark Streaming, Flink 等多种技术栈产品在使用和性能上的利弊。期待Flink生态的丰富,我们会尝试让Flink CDC,Flink ML,Flink CEP等一些特性发挥在我们的数仓建设中。
  • Flink SQL最近几个版本的迭代也是相当频繁的。由于阿里对 Flink planner 的支持,使Flink的批流一体的概念更加趋近于现实,我们会尝试使用 Flink 作为离线数仓的处理引擎,在公司数据组推开 Flink SQL 。
  • 继续完善实时平台对Flink任务的监控,以及资源管理的优化。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在 Windows 10、11 上恢复删除、未保存或覆盖的 Excel 文件?

我们中的大多数人可能都经历过其中一种情况——关闭电源时未保存 Excel 文件或误点击“不要保存”,不小心删除了重要的 Excel 文件,或覆盖了 Excel 文件而未保存原始副本。在遇到这些情况时,我们都会为没有采取适当的措施而感到内疚&#xff…

计算机毕业设计----Springboot超市订单管理系统

项目介绍 该超市订单管理毕业设计基于jdk8版本开发,在部署时需要使用jdk8以上的版本。使用了目前流行的框架组合springbootmybatis的框架技术, 实现了供应商管理对供应商实现增删改查、订单管理对超市订单实现增删改查、用户管理等功能,适用…

都是取所有行的某列数据,这个array[:,2]和array[:,2:3]有什么不同呢

效果图 代码 import numpy as nplist [[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20],[21,22,23,24,25] ] array np.array(list) print(array) 输出: [[ 1 2 3 4 5][ 6 7 8 9 10][11 12 13 14 15][16 17 18 19 20][21 22 23 24 25]]a arr…

【上分日记】第369场周赛(分类讨论 + 数学 + 前缀和)

文章目录 前言正文1.3000. 对角线最长的矩形的面积2.3001. 捕获黑皇后需要的最少移动次数3.3002. 移除后集合的最多元素数3.3003. 执行操作后的最大分割数量 总结尾序 前言 终于考完试了,考了四天,也耽搁了四天,这就赶紧来补这场周赛的题了&a…

【Linux实用篇】项目部署 基于Shell脚本自动部署

目录 1. 项目部署 1.1 手动部署项目 1.2 基于Shell脚本自动部署 1.2.1 介绍 1.2.2 推送代码到远程 1.2.3 Git操作 1.2.4 Maven安装 1.2.5 Shell脚本准备 1.2.6 Linux权限 1.2.7 授权并执行脚本 1.2.8 设置静态IP 1. 项目部署 之前我们讲解Linux操作系统时&#xff0…

Dcoker构建部署Java项目过程

目录 前言 一、打包 二、Docker File文件编写 一个简单的Docker File文件 三、上传文件 四、构建镜像 五、运行 六、端口开放 前言 使用Dcoker构建部署Java项目,发布到服务器 一、打包 我这里打包的是item-service这个module,clean-cpmpile-pa…

uniapp 查找不到uview-ui文件怎么办?

用官方的方式总是报:文件查找失败:uview-ui at main.js 解决方案: 1.先安装uview-ui npm install uview-ui 下载成功是这样的: 而不是这样的: 这样的原因是你的项目里没有package.json包,先执行 npm …

Qt 调试系统输出报警声以及添加资源

文章目录 前言一、方法1 使用 Qsound1.添加都文件 直接报错2.解决这个错误 添加 QT multimedia3. 加入代码又遇到新的错误小结 二、第二种方法1.引入库2.添加资源2.1依次点击Qt--->Qt Resource File--->Choose2.2给资源文件起个名字,如:res&#…

【每日一题】构造限制重复的字符串

文章目录 Tag题目来源解题思路方法一:贪心空间复杂度: O ( ∑ ) O(\sum) O(∑)。 写在最后 Tag 【贪心】【字符串】【2024-01-13】 题目来源 2182. 构造限制重复的字符串 解题思路 方法一:贪心 思路 解题思想比较简单,利用贪…

【MySQL】:掌握SQL中DDL的数据库定义与操作

🎥 屿小夏 : 个人主页 🔥个人专栏 : MySQL从入门到进阶 🌄 莫道桑榆晚,为霞尚满天! 文章目录 📑前言一. SQL的分类二. DDL数据库操作2.1 查询所有数据库2.2 查询当前数据库2.3 创建数…

[足式机器人]Part2 Dr. CAN学习笔记-Advanced控制理论 Ch04-8 状态观测器设计 Linear Observer Design

本文仅供学习使用 本文参考: B站:DR_CAN Dr. CAN学习笔记-Advanced控制理论 Ch04-8 状态观测器设计 Linear Observer Design

虚幻引擎nDisplay教程:如何同步nDisplay节点与Switchboard + Helix Core

对于使用大型LED屏幕进行拍摄的虚拟制作团队来说,虚幻(Unreal)的nDisplay是一个重要的工具。但是,在nDisplay中将正确版本的文件发送到每个节点会非常耗时。立即阅读本文,您将了解到如何使用Perforce Helix Core版本控…

Linux 系统之部署 ZFile 在线网盘服务

一、ZFile 介绍 1)ZFile 简介 官网:https://www.zfile.vip/ GitHub:https://github.com/zfile-dev/zfile ZFile 是一款基于 Java 的在线网盘程序,支持对接 S3、OneDrive、SharePoint、又拍云、本地存储、FTP 等存储源&#xff0…

【Go】excelize库实现excel导入导出封装(三),基于excel模板导出excel

前言 大家好,这里是符华~ 关于excelize库实现excel导入导出封装,我已经写了两篇了,我想要的功能基本已经实现了,现在还差一个模板导出,这篇文章就来讲讲如何实现用模板导出excel。 前两篇: 【Go】excel…

爬虫-5-数据提取-正则,xpath

#免责声明:本文仅供学习,请遵纪守法。 ԅ(ㅂԅ)

Leetcode 剑指 Offer II 061. 查找和最小的 K 对数字

题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 给定两个以升序排列的整数数组 nums1 和 nums2 , 以及一个整数 k…

使用CloudCompare对obj网格模型转换为pcd/ply点云模型

1.打开CloudCompare,点击文件夹图标,首先先把文件类型选择为.obj,然后再去找预处理的obj网格模型,点击打开。 2.测试打开的obj网格模型如下图: 3.选中obj文件,点击网格上样本点的图标,输入预生成…

探索 C# 中的程序运行目录获取方法

探索 C# 中的程序运行目录获取方法 引言 在 C# 开发中,有时需要确定您的应用程序的运行目录。这可能是为了读取配置文件、存储日志,或者访问与应用程序位于同一目录的其他资源。C# 提供了几种方法来获取当前程序的运行目录。本文将探讨这些方法及其使用…

群晖Synology Drive同步文件时过滤指定文件夹“dist“, “node_modules“

群晖Synology Drive同步文件时过滤指定文件夹"dist", “node_modules” mac用户 安装Synology Drive创建同步任务修改Synology Drive配置 打开/Users/[用户名]/Library/Application Support/SynologyDrive/data/session/[同步任务序号,第一个同步任务就…

【Maven】003-基于 IDEA 创建 Maven 工程

【Maven】003-基于 IDEA 创建 Maven 工程 文章目录 【Maven】003-基于 IDEA 创建 Maven 工程一、关于 Maven 工程的 GAVP1、GAVP 简介2、GAV 坐标规范3、Packaging 定义规则 二、基于 IDEA 创建 Maven 工程1、创建 Maven 项目2、创建结果3、项目结构说明 一、关于 Maven 工程的…