深入数仓离线数据同步:问题分析与优化措施

一、前言

在数据仓库领域,离线数仓和实时数仓是常见的两种架构类型。离线数仓一般通过定时任务在特定时间点(通常是凌晨)将业务数据同步到数据仓库中。这种方式适用于对数据实时性要求不高,更侧重于历史数据分析和报告生成的场景。

然而,采用离线同步方式可能会引发业务数据与数据仓库数据不一致的问题。本文的目标是深入分析这些问题的根本原因,并提供一些建议来优化同步流程,以确保数据的一致性。

二、场景

在大数据平台中,业务部门常常需要查看历史某一天的表数据。为了记录历史数据的变化,离线数仓常见的解决方案是拉链表和快照表。而由于拉链表的查询方式较为复杂不便直观的展现问题,因此在这里我选择使用快照表作为示例,以便更清晰地阐述离线数仓的数据一致性问题。

快照表是用来存储某个时间点的所有数据-通常粒度是天,相当于是对每天的业务数据做了一次快照,存储当天的全量数据;例如:快照表12号分区中的数据是从历史到11号的所有数据,13号分区中的数据是从历史到12号的所有数据,其他的以此类推,示例如下:

  1. [Mysql] 业务数据 - 用户表全量数据:
idnamephonegendercreate_timeupdate_time
1jack1112023-06-01 13:00:002023-06-01 13:00:00
2jason2222023-06-01 13:00:002023-06-01 13:00:00
3tom3332023-06-01 13:00:002023-06-01 13:00:00
  1. [数仓]由于离线数仓是T+1处理,故2023-06-02时数仓快照表数据如下:
idnamephonegendercreate_timeupdate_timedt[分区字段]
1jack1112023-06-01 13:00:002023-06-01 13:00:002023-06-01
2jason2222023-06-01 13:00:002023-06-01 13:00:002023-06-01
3tom3332023-06-01 13:00:002023-06-01 13:00:002023-06-01

加粗为分区字段

  1. [Mysql] 2023-06-02 业务数据新增了一名用户,且更改了tom的手机号,此时表数据如下:
idnamephonegendercreate_timeupdate_time
1jack1112023-06-01 13:00:002023-06-01 13:00:00
2jason2222023-06-01 13:00:002023-06-01 13:00:00
3tom4442023-06-01 13:00:002023-06-02 09:00:00
4tony5552023-06-02 10:00:002023-06-02 10:00:00

加粗为更新/新增数据

  1. [数仓]由于离线数仓是T+1处理,故2023-06-03时数仓快照表数据如下:
idnamephonegendercreate_timeupdate_timedt[分区字段]
1jack1112023-06-01 13:00:002023-06-01 13:00:002023-06-01
2jason2222023-06-01 13:00:002023-06-01 13:00:002023-06-01
3tom3332023-06-01 13:00:002023-06-01 13:00:002023-06-01
1jack1112023-06-01 13:00:002023-06-01 13:00:002023-06-02
2jason2222023-06-01 13:00:002023-06-01 13:00:002023-06-02
3tom4442023-06-01 13:00:002023-06-02 09:00:002023-06-02
4tony5552023-06-02 10:00:002023-06-02 10:00:002023-06-02

加粗为更新/新增数据

以上是快照表的表现形式,接下来我们看下具体实现

三、实现

离线数仓(T+1)中关于快照表的实现方式有两种:全量同步和增量同步。

值得强调的是,这些同步任务的执行方式并不局限于特定的工具或框架,例如sqoop/spark;因此在本文中我们将使用SQL语句来表达数据处理过程。

需要注意的是这两种实现方法都有可能导致数据不一致的问题,下一节将对此进行详细讨论和解释。

3.1、全量同步

  1. 全量同步顾名思义是将业务数据用户表全量同步一份到数仓快照表中的指定分区内,该方式简单粗暴,这里以:2.1、示例中的 2023-06-02业务数据新增了一名用户,且更改了tom的手机号为例;过程如下:

  1. sql语句:
# 2023-06-03凌晨执行的全量同步sql语句
INSERT INTO 数仓快照表 PARTITION (date='2023-06-02')
select * from 业务用户表 where update_time < '2023-06-03 00:00:00';

3.2、增量同步

增量同步顾名思义是将业务数据用户表按天为粒度将增量数据与数仓快照表中的前一天数据进行join对比后放入到指定分区内,关于增量同步的实现不在本文赘述,对此感兴趣的读者可参考笔者的另一篇文章:数仓日常维护:剖析每日增量同步的内部机制

四、数据一致性问题

以上述快照表为例,可能引发一致性问题的情况是指在执行层的Spark或Sqoop任务启动和执行期间,业务数据库表的数据发生了变化,从而导致快照表与业务表的数据不一致。这种不一致性问题可能会对数据处理和分析产生负面影响,示例如下:

假设业务表在2023年6月2日新增了“Tony”修改了“Tom”手机号这两条数据。在凌晨定时任务启动后,引擎初始化及加载数据时,业务数据中的“Tony”发生了变更,其“update_time”字段也随之变化。然后,执行引擎再次通过“update_time”字段读取业务数据时,由于变更,它可能会错过“Tony”这条记录。这将导致数仓快照表中2023年6月2日分区的数据缺失“Tony”用户信息,造成了当天数据不一致的问题,过程如下:

在这里插入图片描述

上图采用全量同步方式,增量同步同样会有此问题

以上问题的本质是数据同步执行层在启动或数据加载过程中,由于业务数据库表数据的动态变化,特别是在数据加载期间或引擎启动期间发生的数据更新操作,导致了读取到的数据无法准确地反映业务表在特定时间点的状态。这样的数据变化可能会使得快照表在某些情况下缺少或错误地反映了业务表的最新状态,导致了数据不一致的问题。

五、解决方案

4.1、加锁

同步任务在凌晨前启动,当时钟指向零点时,对需要同步的数据库表进行锁定,以防止其他更改操作干扰数据读取,确保数据一致性。

然而,这种方式存在明显弊端。首先,要求业务库支持锁操作,并且同步任务必须具备相应的锁权限。更重要的是,这种方式会对业务库产生较大影响,因此不推荐使用。值得一提的是,Flink-CDC 1.x版本的全量同步采用的就是使用了这种对表加锁的策略,不过该痛点已在2.x版本后改为增量快照读取机制从而解决了加锁问题

对此感兴趣的读者可参考笔者另一篇文章:深入解析 Flink CDC 增量快照读取机制

4.2、实时同步

实时同步是一种有效解决数据一致性问题的方法,因其同步方式大多是采用binlog + checkpoint分布式快照的形式故不会存在漏读情况,但这可能需要对现有技术架构做出较大的改变。实时同步具体实现不在本文赘述,感兴趣的同学可以看笔者另一篇文章:Flink实时数仓同步:拉链表实战详解

4.3、binlog修正

此思路灵感来源于 Flink-CDC 2.x 的增量快照读取机制。这种修正方式相对简单,且不会对现有的离线数仓架构产生改变,仍然可以使用 Spark 或 其他执行引擎。对此感兴趣的读者可参考笔者另一篇文章:深入解析 Flink CDC 增量快照读取机制

具体思路如下:相较于之前的离线同步,新增了一个读取 binlog 消息修正的步骤。当同步任务读取完业务数据后,它会读取从零点到当前时间内的 binlog 日志。如果发现了 update 操作的日志,则判断该条日志中 after 数据的 update_time 是否属于当前快照表的时间范围。若属于,则将 after 数据补充到已读取的业务数据中。

在这里插入图片描述

这种方法能够有效解决离线数仓同步数据一致性的问题,而且不需要修改现有的离线数仓架构。因此,对于那些不想对原有技术架构做出变更的人来说,这种方法值得推荐。

六、相关文档

  • 数仓日常维护:剖析每日增量同步的内部机制
  • 深入解析 Flink CDC 增量快照读取机制
  • Flink实时数仓同步:拉链表实战详解
  • 数据仓库表设计理论
  • 数据治理设计理论
  • 数据仓库设计理论
  • 数据仓库发展历史

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

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

相关文章

Excel新建文件打开后提示文件扩展名与文件格式不匹配

环境&#xff1a; Win10专业版 excel2016 问题描述&#xff1a; Excel新建文件打开后提示文件扩展名与文件格式不匹配 解决方案&#xff1a; 1.调出注册表编辑器&#xff0c;按层点击文件夹&#xff1a;HKEY_CURRENT_USER/Software/Microsoft/Office/12.0/Excel/Securit…

利用Anaconda安装pytorch和paddle深度学习环境+pycharm安装后不能调用pytorch和paddlepaddle框架

问题现象&#xff1a; 之前安装后不能在添加pytorch和paddlepaddle框架 原因&#xff08;疑似&#xff09;&#xff1a; 在终端中显示pytorch和paddle在C盘但是安装是安装在J盘 解决办法&#xff1a; 卸载、删除文件重新安装后可以看到文件位置在J盘中 但是选择时还是显示C…

【cucumber】cucumber-reporting生成测试报告

原始的cucumber report 比较粗糙 我们可以通过cucumber-reporting 插件对报告进去优化 在pom.xml里面添加cuccumber-reporting 插件 <!-- 根据 cucumber json文件 美化测试报告--><dependency><groupId>net.masterthought</groupId><artifactId>…

设计模式—行为型模式之观察者模式

设计模式—行为型模式之观察者模式 观察者模式(Observer Pattern)&#xff1a;定义对象间的一种一对多依赖关系&#xff0c;使得每当一个对象状态发生改变时&#xff0c;其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅&#xff08;Publish/Subscribe&#…

Java 基于 SpringBoot+Vue 的社区团购系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

【射影几何02-补】极点和极线,调和点列

一、说明 极点和极线&#xff08;Pole and polar&#xff09;对于几何学&#xff0c;是普遍的概念。可能高中就学过&#xff0c;问题是在双曲几何又用到这个概念。前面已经有写过一文&#xff0c;经过再次学习&#xff0c;逐渐感觉前文描述不很理想&#xff0c;这一文专门纠正前…

【视频媒体】深入了解直播视频流

深入了解直播视频流&#x1f3a5; YouTube、TikTok live和Twitch上的直播视频是如何工作的&#xff1f; 直播视频流与常规流媒体不同&#xff0c;因为视频内容通过互联网近乎实时发送&#xff0c;通常只有几秒钟的延迟。 下图解释了实现这一目标背后所发生的事情。 步骤1&…

何为PyTorch?

PyTorch的名字来源于它的功能和设计哲学。"Py"代表Python&#xff0c;因为PyTorch是一个基于Python的深度学习库&#xff0c;它充分利用了Python语言的灵活性和易用性&#xff0c;为开发者提供了简洁而强大的接口。“Torch”则代表其前身—— Torch&#xff0c;这是一…

51单片机电子密码锁Proteus仿真+程序+视频+报告

目录 视频 设计分析 系统结构 仿真图 资料内容 资料下载地址&#xff1a;51单片机电子密码锁Proteus仿真程序视频报告 视频 单片机电子密码锁Proteus仿真程序视频 设计分析 (1)能够从键盘中输入密码&#xff0c;并相应地在显示器上显示‘*’&#xff1b; (2)能够判断密码…

Mysql - 定点型(DECIMAL)的使用详解及练习

目录 &#x1f436;1. 前言&#xff1a; &#x1f436;2. DECIMAL类型简介 &#x1f436;3. Decimal使用实战 &#x1f96a;#结论1&#xff1a;小数位不足会自动补0 &#x1f96a;#结论2&#xff1a;小数位超出会截断 并按四舍五入处理。 &#x1f96a;#结论3&#xff1…

PyTorch各种损失函数解析:深度学习模型优化的关键(2)

目录 详解pytorch中各种Loss functions mse_loss 用途 用法 使用技巧 注意事项 参数 数学理论公式 代码演示 margin_ranking_loss 用途 用法 使用技巧 注意事项 参数 数学理论公式 代码演示 multilabel_margin_loss 用途 用法 使用技巧 注意事项 参数 …

ElasticSearch 7.x现网运行问题汇集3

问题描述 某现网ElasticSearch 故障&#xff0c;很长时间unassgined_shards的数量都不减少。 原因分析与解决方案&#xff1a; 先了解整体状态&#xff0c;使用Postman请求&#xff0c;如下几个请求命令&#xff1a; GET /_cat/indicesGET /_cat/shardsGET /_cluster/health…

Mac NTFS 磁盘读写工具选哪个好?Tuxera 还是 Paragon?

在使用 Mac 电脑时&#xff0c;我们经常需要读写 NTFS 格式的硬盘或 U 盘。然而&#xff0c;由于 Mac 系统不支持 NTFS 格式的读写&#xff0c;因此我们需要借助第三方工具来实现这个功能。而在市场上&#xff0c;Tuxera 和 Paragon 是两款备受推崇的 Mac NTFS 磁盘读写工具。那…

<信息安全>《1 国内主要企业网络安全公司概览(一)》

1 深信服科技股份有限公司 信息内容LOGO成立日期2000年12月25日成立。总部深圳市南山区学苑大道1001号南山智园A1栋是否上市深信服[300454]A股市值265亿主要产品企业级网络安全云计算IT基础设施数据通信物联网员工规模9000人分支机构全球50多个荣誉国家级高新技术企业、中国软…

JavaEE中的监听器的作用和工作原理

在JavaEE&#xff08;Java Platform, Enterprise Edition&#xff09;中&#xff0c;监听器&#xff08;Listener&#xff09;是一种重要的组件&#xff0c;用于监听和响应Web应用程序中的事件。监听器的作用是在特定的事件发生时执行一些自定义的逻辑。常见的监听器包括Servle…

Linux:使用for+find查找文件并cp到其他目录,文件名带有空格

一、场景描述 在终端窗口中&#xff0c;用shell命令&#xff0c;批量拷贝文件到指定目录。 我是在Windows系统上&#xff0c;通过git bash终端来执行shell命令的。 二、实现过程 命令1 for filepath in find /d/LearningMaterials/数学/数学/高中/一数/偏基础&#xff08;基…

JavaScript递归函数如何匹配上下级id和pid的数据(for...of,foreach.reduce)

目录 一、for...of 二、forEach 三、reduce 递归函数是一种在编程中常用的方法&#xff0c;用于解决一些需要重复操作的问题。在JavaScript中&#xff0c;递归函数可以用来匹配上下级id和pid的数据结构&#xff0c;例如树形结构或者父子关系的数据。 一、for...of 首先…

Django 图片上传与下载

写在前面 在Web开发中&#xff0c;文件上传和下载是常见的功能之一。 Django 是一位魔法师&#x1fa84;&#xff0c;为我们提供了 FileField 和 ImageField 等神奇得字段类型&#xff0c;以及相应的视图和模板标签&#xff0c;使得处理文件变得十分便捷。本文以图片上传作为…

Docker安装启动、常用命令、应用部署、迁移备份、Dockerfile、Docker私有仓库

目录 1.Docker安装与启动 1.1 安装Docker 1.2 设置ustc的镜像 1.3 Docker的启动与停止 2.常用命令 2.1 镜像相关命令 2.1.1 查看镜像 2.1.2 搜索镜像 2.1.3 拉取镜像 2.1.4 删除镜像 2.2 容器相关命令 2.2.1 查看容器 2.2.2 创建与启动容器 2.2.3 停止与启动容器 2.…

表白墙网站PHP源码,支持封装成APP

源码介绍 PHP表白墙网站源码&#xff0c;适用于校园内或校区间使用&#xff0c;同时支持封装成APP。告别使用QQ空间的表白墙。 简单安装&#xff0c;只需PHP版本5.6以上即可。 通过上传程序进行安装&#xff0c;并设置账号密码&#xff0c;登录后台后切换模板&#xff0c;适配…