伴鱼实时数仓建设案例

伴鱼实时数仓建设案例

文章目录

  • 伴鱼实时数仓建设案例
    • 伴鱼实时作业应用场景
    • 伴鱼实时数仓的建设体系
    • 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.mfbz.cn/a/317543.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JUC之CompletableFuture

Future接口理论 Future接口定义了异步任务执行的一些方法&#xff0c;包括异步任务执行结果&#xff0c;异步任务执行是否中断&#xff0c;异步任务是否完毕等。 Future接口常用实现类FutureTask异步任务 FutureTask<String> futureTask new FutureTask<String>…

企业网盘:实现数据跨境传输,助力企业出海的必备工具

今年是“一带一路”十周年。在这十年间&#xff0c;中国和“一带一路”共建国家携手并行&#xff0c;贸易持续增长发展。在如今经济全球化的大方向下&#xff0c;跨国经济合作将会是各国共识。 目前&#xff0c;中外合作企业、跨境企业已成为国际贸易发展趋势。不过&#x…

扩展欧几里得算法

文章目录 扩展欧几里得算法的内容及证明扩展欧几里得算法的代码实现扩展欧几里得算法的用途 本文的问题场景中&#xff0c;涉及到的变量均为整数。 扩展欧几里得算法的内容及证明 贝祖等式&#xff1a; a x b y g c d ( a , b ) c axby gcd(a, b) c axbygcd(a,b)c 其中 …

PLC数组队列搜索FC(SCL代码+梯形图程序)

根据输入数据搜索输入数据队列中和输入数据相同的数,函数返回其所在队列的位置。这里我们需要用到博途PLC的数组指针功能,有关数组指针的详细使用方法,可以参考下面文章: 博途PLC数组指针: https://rxxw-control.blog.csdn.net/article/details/134761364 区间搜索FC …

软件测试|Git:fatal: refusing to merge unrelated histories错误分析与解决

问题介绍 在使用Git时&#xff0c;有时我们可能会遇到以下错误消息&#xff1a; fatal: refusing to merge unrelated histories这个错误通常发生在尝试合并两个不相关的Git仓库历史时。在本文中&#xff0c;我们将详细解释为什么会出现这个错误以及如何解决它。 问题分析 …

代码随想录算法训练营第四天 | 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II

代码随想录算法训练营第四天 | 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II 文章目录 代码随想录算法训练营第四天 | 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II1 Le…

CSS样式学习

html超文本传输标签&#xff0c;属性等权重 outline 标签轮廓 <input type"text"> <textarea cols"30" rows"10"></textarea> outline: none; 表示无轮廓 &#xff08;开发时用的比较多&#xff09; CSS 轮廓&#xff…

大创项目推荐 深度学习疫情社交安全距离检测算法 - python opencv cnn

文章目录 0 前言1 课题背景2 实现效果3 相关技术3.1 YOLOV43.2 基于 DeepSort 算法的行人跟踪 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习疫情社交安全距离检测算法 ** 该项目较为新颖&#xff0c;适合作为竞赛…

【踩坑】flask_uploads报错cannot import name ‘secure_filename‘

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 背景说明 截至目前&#xff0c;用新版的flask实现文件上传(用到flask_uploads库)&#xff0c;会出现这个问题。 问题原因 版本问题&#xff0c;新的werkzeug已经把secure_filename的位置改了。 解决方法 手动修改…

第23集《佛法修学概要》

庚二、不偷盗分五&#xff1a;辛一、解释名义&#xff1b;辛二、具缘成犯&#xff1b;辛三、犯戒轻重&#xff1b;辛四、开缘情况&#xff1b;辛五、持犯得失 请大家打开讲义第六十五页。我们看庚二、不偷盗。 这一科&#xff0c;我们讲到人天乘的法门。五戒十善为什么叫人天…

【数模百科】距离美赛还有20天,不要忘了阅读往年获奖论文(附04-23年美赛获奖论文)

之前发了很多数模相关的知识&#xff0c;受到了一些人的关注&#xff0c;也有很多人私下问我&#xff0c;距离美赛还有20几天了&#xff0c;还来不来得及。 对此我想说&#xff0c; 来不来得及重要吗&#xff1f; 你名都报了&#xff0c;钱也交了&#xff0c;还是笔不小的钱…

OpenGL 网格拾取坐标(Qt)

文章目录 一、简介二、代码实现三、实现效果参考资料一、简介 有时候我们希望通过鼠标来拾取某个网格中的坐标,这就涉及到一个很有趣的场景:光线投射,也就是求取一条射线与网格的交点,这里如果我们采用普通遍历网格中的每个面片的方式,当网格的面片数据量很大时计算效率就…

H7303 无电感,线性恒流,低压差,大电流,车灯/台灯 9V 12V 24V 30V

线性恒流芯片是一种用于控制电流的电子元件&#xff0c;通常用于驱动LED等器件。它的工作原理是通过维持输出电流的恒定来保持被驱动器件的亮度或功率稳定。 具体来说&#xff0c;线性恒流芯片会监测输出电流并调整电压以保持恒定的电流流过被驱动器件。以下是其基本工作步骤&…

国内镜像:极速下载编译WebRTC源码(For Android/Linux/IOS)(二十四)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…

基础数据结构第九期 堆(数组+STL)

前言 堆是一种重要的数据结构&#xff0c;因此应该熟练掌握。 一、堆的基本概念 堆的基本&#xff1a; 堆的结构实际上是一棵完全二叉树&#xff0c;堆可以分为大根堆和小根堆 大根堆&#xff1a; 小根堆&#xff1a; 堆的储存&#xff1a; 若节点小标为i&#xff0c;则左子…

常用计算电磁学算法特性与电磁软件分析

常用计算电磁学算法特性与电磁软件分析 参考网站&#xff1a; 计算电磁学三大数值算法FDTD、FEM、MOM ADS、HFSS、CST 优缺点和应用范围详细教程 ## 基于时域有限差分法的FDTD的计算电磁学算法&#xff08;含Matlab代码&#xff09;-框架介绍 参考书籍&#xff1a;The finite…

three.js 学习笔记(学习中1.10更新) |

文章目录 three.js 学习笔记基础概念透视相机 第一个three.js应用threejs画布尺寸和布局canvas画布宽高度动态变化 坐标辅助器 THREE.AxesHelper实现动画效果requestAnimationFrame时间相关属性和方法 THREE.Clock类 相机控件 轨道控制器OrbitControls 灯光点光源点光源辅助观察…

基于python舆情分析可视化系统+情感分析+爬虫+机器学习(源码)✅

大数据毕业设计&#xff1a;Python招聘数据采集分析可视化系统✅ 毕业设计&#xff1a;2023-2024年计算机专业毕业设计选题汇总&#xff08;建议收藏&#xff09; 毕业设计&#xff1a;2023-2024年最新最全计算机专业毕设选题推荐汇总 &#x1f345;感兴趣的可以先收藏起来&…

怎么安装IK分词器

.安装IK分词器 1.在线安装ik插件&#xff08;较慢&#xff09; # 进入容器内部 docker exec -it elasticsearch /bin/bash ​ # 在线下载并安装 ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elastics…

4.4 千万 TOKEN 心理咨询语料库发布,专为大模型,让人工智能技术更好的服务人

2023 年&#xff0c;全网火爆聊天机器人&#xff0c;不同行业企业开始探索应用大模型于垂直领域&#xff0c;当算法和算力已经被证明是行之有效的&#xff0c;那么重头戏就是数据了&#xff0c;Chatopera 近日发布了心理咨询行业的又一大规模语料 - 包含 4.4 千万 TOKEN 的多轮…
最新文章