高效改进!防止DataX从HDFS导入关系型数据库丢数据

在这里插入图片描述

高效改进!防止DataX从HDFS导入关系型数据库丢数据

针对DataX在从HDFS导入数据到关系型数据库过程中的数据丢失问题,优化了分片处理代码。改动包括将之前单一分片处理逻辑重构为循环处理所有分片,确保了每个分片数据都得到全面读取和传输,有效提升了数据导入的可靠性和效率。这些改动不仅解决了丢数据的问题,还显著提高了处理多分片数据的性能。

背景

我们数据中台设计,数据同步功能是datax完成,在orc格式时datax从hdfs导数据到关系型数据库数据丢失,而在textfile格式时丢失数据,当文件超过250M多时会丢数据。因想使用orc格式节省数据空间,提高spark运行效率,需要解决这个问题。

问题

在这里插入图片描述
在这里插入图片描述

只读取了256M 左右的数据,数据条数对不上,导致hdfs,orc格式导入数据到pg,mysql等关系型数据库,数据丢失。

解决

修改hdfsreader/src/main/java/com/alibaba/datax/plugin/reader/hdfsreader/DFSUtil.java

问题代码

 InputSplit[] splits = in.getSplits(conf, 1);RecordReader reader = in.getRecordReader(splits[0], conf, Reporter.NULL);Object key = reader.createKey();Object value = reader.createValue();// 获取列信息List<? extends StructField> fields = inspector.getAllStructFieldRefs();List<Object> recordFields;while (reader.next(key, value)) {recordFields = new ArrayList<Object>();for (int i = 0; i <= columnIndexMax; i++) {Object field = inspector.getStructFieldData(value, fields.get(i));recordFields.add(field);

修改后

 // OrcInputFormat getSplits params numSplits not used, splits size = block numbersInputSplit[] splits = in.getSplits(conf, -1);for (InputSplit split : splits) {{RecordReader reader = in.getRecordReader(split, conf, Reporter.NULL);Object key = reader.createKey();Object value = reader.createValue();// 获取列信息List<? extends StructField> fields = inspector.getAllStructFieldRefs();List<Object> recordFields;while (reader.next(key, value)) {recordFields = new ArrayList<Object>();for (int i = 0; i <= columnIndexMax; i++) {Object field = inspector.getStructFieldData(value, fields.get(i));recordFields.add(field);}transportOneRecord(column, recordFields, recordSender,taskPluginCollector, isReadAllColumns, nullFormat);}reader.close();

点击参考查看

重新打包替换hdfsreader.jar即可

解析

  1. 新增循环处理所有分片的逻辑: 之前的代码只处理了第一个分片(splits[0]),现在改为了处理所有的分片。新增的部分如下:

    java
    InputSplit[] splits = in.getSplits(conf, -1);
    for (InputSplit split : splits) {RecordReader reader = in.getRecordReader(split, conf, Reporter.NULL);Object key = reader.createKey();Object value = reader.createValue();
    

    旧的逻辑是:

    java
    InputSplit[] splits = in.getSplits(conf, 1);
    RecordReader reader = in.getRecordReader(splits[0], conf, Reporter.NULL);
    Object key = reader.createKey();
    Object value = reader.createValue();
    

    这样改动的目的是,同时处理多个分片,从而提升数据读取的效率。

  2. 移除了重复的分片处理逻辑: 不使用重复的分片处理逻辑:

    java
    // OrcInputFormat getSplits params numSplits not used, splits size = block numbers
    InputSplit[] splits = in.getSplits(conf, -1);
    
  3. 代码块的重构: 将读取分片、解析记录以及处理记录的逻辑放入一个循环中,使代码更简洁、更易读:

    改之前:

    java
    InputSplit[] splits = in.getSplits(conf, 1);
    RecordReader reader = in.getRecordReader(splits[0], conf, Reporter.NULL);
    Object key = reader.createKey();
    Object value = reader.createValue();
    

    改后使用循环:

    java
    InputSplit[] splits = in.getSplits(conf, -1);
    for (InputSplit split : splits) {RecordReader reader = in.getRecordReader(split, conf, Reporter.NULL);Object key = reader.createKey();Object value = reader.createValue();
    
  4. 处理每个记录字段并传输记录: 保持对每条记录的字段读取并将其传输转移到了新的循环处理逻辑中:

    改之前:

    while (reader.next(key, value)) {recordFields = new ArrayList<Object>();for (int i = 0; i <= columnIndexMax; i++) {Object field = inspector.getStructFieldData(value, fields.get(i));recordFields.add(field);}transportOneRecord(column, recordFields, recordSender,taskPluginCollector, isReadAllColumns, nullFormat);
    }
    reader.close();
    

    改后:

    for (InputSplit split : splits) {RecordReader reader = in.getRecordReader(split, conf, Reporter.NULL);Object key = reader.createKey();Object value = reader.createValue();List<? extends StructField> fields = inspector.getAllStructFieldRefs();List<Object> recordFields;while (reader.next(key, value)) {recordFields = new ArrayList<Object>();for (int i = 0; i <= columnIndexMax; i++) {Object field = inspector.getStructFieldData(value, fields.get(i));recordFields.add(field);}transportOneRecord(column, recordFields, recordSender,taskPluginCollector, isReadAllColumns, nullFormat);}reader.close();
    }
    
  5. 为什么是256M没有更改前他是按每个文件进行分割,而在datax的配置中Java heap size 即默认xmx设置时256M,所以当单个文件超过256M时,超过的部分就被丢掉了,造成数据缺失,而更改后的是按hdfs block size 块的大小进行分割,循环遍历,所以直接修改xmx也能解决问题,但是你要想万一文件超过128G那,你不可能一直调大Java heap size,所以按hdfs block size分割是合理的解决方案

reader单个分片(InputSplit)的大小

在DataX的数据读取过程中,reader单个分片(InputSplit)的大小通常取决于底层存储系统和具体的配置参数。对于HDFS(Hadoop Distributed File System)를的读取,分片大小主要由以下几个因素决定:

  1. HDFS块大小(Block Size): HDFS将文件分为多个块,每个块通常是64MB、128MB或256MB大小,具体大小可以通过HDFS的配置参数dfs.blocksize进行设置。DataX会根据这些块来创建分片,也就是一个分片通常对应一个或多个HDFS块。
  2. 文件本身的大小: 如果文件比HDFS块小,或者没有跨越多个块,则一个文件可能只对应一个分片。
  3. DataX的任务配置: DataX允许在其配置文件中指定一些与分片相关的参数,类似于Hadoop的mapreduce.input.fileinputformat.split.maxsizemapreduce.input.fileinputformat.split.minsize,这些参数可以影响分片的逻辑。
  4. InputFormat: DataX使用的Hadoop的InputFormat也能控制分片的逻辑,比如FileInputFormatTextInputFormatOrcInputFormat等。这些格式定义了如何分割输入数据,结合文件大小和块大小来决定分片。

总结

  • 主要改动是将之前只处理单个分片的逻辑重构为一个循环,处理所有分片。这使代码更具扩展性和效率,也适应不同的输入数据量。
  • 移除了无用且重复的注释和代码行,以保持代码清晰。

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

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

相关文章

Python 实现 excel 数据过滤

一、场景分析 假设有如下一份 excel 数据 shop.xlsx, 写一段 python 程序&#xff0c;实现对于车牌的分组数据过滤。 并以车牌为文件名&#xff0c;把店名输出到 车牌.txt 文件中。 比如 闽A.txt 文件内容为&#xff1a; 小林书店福州店1 小林书店福州店2 二、依赖安装 程序依…

TBWeb正式稳定版V3.4.0+AI+MJ绘画+免授权无后门+详细安装教程

TBWeb正式稳定版V3.4.0AIMJ绘画免授权无后门详细安装教程&#xff1b; 运行环境 Nginx1.22 PHP5.7 MySQL7.4 Redis7.0 Node.js&#xff08;16.19.1&#xff09; PM2管理器5.6 TBWeb系统是基于 NineAI 二开的可商业化 TB Web 应用&#xff08;免授权&#xff0c;无后门&a…

【隐私计算】隐语HEU同态加密算法解读

HEU: 一个高性能的同态加密算法库&#xff0c;提供了多种 PHE 算法&#xff0c; 包括ZPaillier、FPaillier、IPCL、Damgard Jurik、DGK、OU、EC ElGamal 以及基于FPGA和GPU硬件加速版本的Paillier版本。 本文我们会基于GPU运行HEU Docker容器&#xff0c;编译打包GPaillier并测…

算法的学习笔记—两个链表的第一个公共结点(牛客JZ52)

&#x1f600;前言 在链表问题中&#xff0c;寻找两个链表的第一个公共结点是一个经典问题。这个问题的本质是在两个单链表中找到它们的相交点&#xff0c;或者说它们开始共享相同节点的地方。本文将详细讲解这个问题的解题思路&#xff0c;并提供一种高效的解决方法。 &#x…

蓝牙资讯|iOS 18.1 正式版下周推送,AirPods Pro 2耳机将带来助听器功能

苹果公司宣布将在下周发布 iOS 18.1 正式版&#xff0c;同时确认该更新将为 AirPods Pro 2 耳机带来新增“临床级”助听器功能。在启用功能后&#xff0c;用户首先需要使用 AirPods 和 iPhone 进行简短的听力测试&#xff0c;如果检测到听力损失&#xff0c;系统将创建一项“个…

docker run 命令解析

docker run 命令解析 docker run 命令用于从给定的镜像启动一个新的容器。这个命令可以包含许多选项&#xff0c;下面是一些常用的选项&#xff1a; -d&#xff1a;后台运行容器&#xff0c;并返回容器ID&#xff1b;-i&#xff1a;以交互模式运行容器&#xff0c;通常与 -t …

【C++】string类 (模拟实现详解 下)

我们接着上一篇【C】string类 &#xff08;模拟实现详解 上&#xff09;-CSDN博客继续对string模拟实现。从这篇内容开始&#xff0c;string相关函数的实现就要声明和定义分离了。 1.reserve、push_back和append 在string.h的string类里进行函数的声明。 void reserve(size_…

JVM(HotSpot):GC之垃圾回收器的分类

文章目录 前言一、串行二、吞吐量优先三、响应时间优先四、常见垃圾回收器使用组合 前言 上一篇&#xff0c;我们学习了分代回收机制 它的主要内容是对JVM内存的一个划分&#xff0c;以及垃圾回收器工作时&#xff0c;区域运作顺序的一个规定。 所以&#xff0c;它是一个规范。…

Spring Boot论坛网站:开发、部署与管理

3系统分析 3.1可行性分析 通过对本论坛网站实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本论坛网站采用SSM框架&#xff0c;JAVA作为开发语言&#xff0c;是…

智慧楼宇平台,构筑未来智慧城市的基石

随着城市化进程的加速&#xff0c;城市面临着前所未有的挑战。人口密度的增加、资源的紧张、环境的恶化以及对高效能源管理的需求&#xff0c;都在推动着我们寻找更加智能、可持续的城市解决方案。智慧楼宇作为智慧城市建设的重要组成部分&#xff0c;正逐渐成为推动城市可持续…

MATLAB电化学特性评估石墨和锂电

&#x1f3af;要点 模拟对比石墨电池的放电电压曲线与实验数据定性差异。对比双箔、多相多孔电极理论和锂电有限体积模型实现。通过孔隙电极理论模型了解粗粒平均质量和电荷传输以及孔隙率的表征意义。锂电中锂离子正向和逆向反应速率与驱动力的指数以及电解质和电极表面的锂浓…

Docker 部署 EMQX 一分钟极速部署

部署 EMQX ( Docker ) [Step 1] : 拉取 EMQX 镜像 docker pull emqx/emqx:latest[Step 2] : 创建目录 ➡️ 创建容器 ➡️ 拷贝文件 ➡️ 授权文件 ➡️ 删除容器 # 创建目录 mkdir -p /data/emqx/{etc,data,log}# 创建容器 docker run -d --name emqx -p 1883:1883 -p 1808…

「Qt Widget中文示例指南」如何实现半透明背景?

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文将为大家展示如…

《Linux从小白到高手》综合应用篇:深入理解Linux常用关键内核参数及其调优

1. 题记 有关Linux关键内核参数的调整&#xff0c;我前面的调优文章其实就有涉及到&#xff0c;只是比较零散&#xff0c;本篇集中深入介绍Linux常用关键内核参数及其调优&#xff0c;Linux调优80%以上都涉及到内核的这些参数的调整。 2. 文件系统相关参数 fs.file-max 参数…

Excel 对数据进行脱敏

身份证号脱敏&#xff1a;LEFT(A2,6)&REPT("*",6)&RIGHT(A2,6) 手机号脱敏&#xff1a;LEFT(B2,3)&REPT("*",5)&RIGHT(B2,3) 姓名脱敏&#xff1a;LEFT(C2,1)&REPT("*",1)&RIGHT(C2,1) 参考&#xff1a; excel匹配替换…

STM32F103C8T6 IO 操作

1.开启相关时钟 在 STM32 微控制器中&#xff0c;开启 GPIO 端口的时钟是确保 IO 口可以正常工作的第一步。 查找 RCC 寄存器使能时钟 在 STM32 中&#xff0c;时钟控制的寄存器通常位于 RCC (Reset and Clock Control) 模块中。不同的 STM32 系列&#xff08;如 STM32F1、STM…

【单元测试】深入解剖单元测试的思维逻辑

目录 一、前言二、准备环境三、 常用的mock语句3.1 模拟指定类的对象实例&#xff0c;用于模拟依赖对象&#xff08;类成员&#xff09;3.2 定义被测试对象3.3 模拟枚举类型/静态方法3.4 模拟依赖方法3.5 模拟构造方法3.6 验证方法调用次数3.7 验证返回值3.8 验证异常对象 四、…

第十六周:机器学习笔记

第十六周周报 摘要Abstratc一、机器学习1. Pointer Network&#xff08;指针网络&#xff09;2. 生成式对抗网络&#xff08;Generative Adversarial Networks | GAN&#xff09;——&#xff08;上&#xff09;2.1 Generator&#xff08;生成器&#xff09;2.2 Discriminator&…

ssm企业库存管理微信小程序-计算机毕业设计源码82704

摘 要 本文基于SSM框架&#xff0c;设计与实现了一个企业库存管理微信小程序。该小程序主要包括用户登录、库存查询、入库操作、出库操作等功能模块。在设计过程中&#xff0c;采用了前后端分离的架构&#xff0c;前端使用了微信小程序原生开发工具进行开发&#xff0c;后端使用…

【C++篇】探索STL之美:熟悉使用String类

CSDN 文章目录 前言 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助吗&…