Datax-Hdfs如何实现支持binary类型数据读写

Hive数据类型全解析:从基础类型到复杂结构,构建高效数据仓库的基石 在数据仓库与大数据处理领域,数据类型是构建数据模型的原子单元,它定义了数据的存储格式、计算方式和语义约束。理解数据类型的原理,是进行高效数据存储、查询和计算的基础。从关系型数据库的经典类型体系,到适应半结构化、非结构化数据的复杂容器,合理的数据类型设计能显著提升存储效率、计算性能和资源利用率。在Hadoop生态中,Hive作为核心的数据仓库工具,其丰富的数据类型体系(包括基本类型如INT、STRING、DECIMAL,以及复杂类型如ARRAY、MAP、STRUCT)为处理多样化的业务数据提供了强大支持。掌握 阅读详情

一、问题背景

      主要的源码思路还是按照这篇HdfsWriter如何实现支持decimal类型数据写入来,这里不再介绍。上篇说binary类型读取会有坑,因此这篇主要解释一下坑的地方以及解决的办法。

PS:虽说binary类型的字段读写Hive,本人没有想到对于数据仓库建设使用上有什么用处,但是本着好奇、学习的心态,就去研究了一下并集成到datax内。

开头附上github地址。

二. 环境准备

Datax版本:3.0

Hadoop版本:2.7.3

Hive版本:2.3.2

三. 源码

    在之前一篇文章中可以看到,hive底层源码对于binary类型字段是支持的,也提供了给定的class对象。

binaryTypeEntry = new PrimitiveObjectInspectorUtils.PrimitiveTypeEntry(PrimitiveCategory.BINARY, "binary", byte[].class, byte[].class, BytesWritable.class);

   因此我直接就使用了byte[].class作为了hdfs写入的序列化器。

HdfsHelper:

// orc需要获取对应的序列化器
public List<ObjectInspector>  getColumnTypeInspectors(List<Configuration> columns){
...
case BINARY:
   objectInspector = ObjectInspectorFactory.getReflectionObjectInspector(byte[].class, ObjectInspectorFactory.ObjectInspectorOptions.JAVA);
break;
...
}

// 字段从channel中读取转换真正类型
public static MutablePair<List<Object>, Boolean> transportOneRecord(
            Record record,List<Configuration> columnsConfiguration,
            TaskPluginCollector taskPluginCollector){
   String rowData = column.getRawData().toString();
   case BINARY:
     //  这里如果使用 rowData.getBytes() ==> 得到的是 byte数组字符串地址的字节数组
     //  即 "[B@74ad1f1f".getBytes(),所以得使用column.asBytes()
     recordList.add(column.asBytes());
   break;
}

在写入orc类型文件时,在hive中查询没有任何问题

而在text类型的文件查询中时,显示的是byte数组的内存地址

说明在hdfs在写入text文件时存在问题,接下来首先定位问题所在,在接着看如何改造。

HdfsHelper:

// text类型文件最终写入要转换为string类型进行字符串拼接
public static MutablePair<Text, Boolean> transportOneRecord(
            Record record, char fieldDelimiter, List<Configuration> columnsConfiguration, TaskPluginCollector taskPluginCollector) {
...
        if(null != transportResultList){
            // 调用column对象toString进行拼接
            Text recordResult = new Text(StringUtils.join(transportResultList.getLeft(), fieldDelimiter));
            transportResult.setRight(transportResultList.getRight());
            transportResult.setLeft(recordResult);
        }
...
    }

所以很明显的是,byte[]数组的toString方法肯定是取得内存地址。因此在做值转换的时候我们,不能采用直接用byte[]对象。观察到开头hive源码提供的BytesWritable对象,查看该对象,发现这个对象已经重写了toString方法,所以我们就采用这个对象去做类型转换。

public List<ObjectInspector>  getColumnTypeInspectors(List<Configuration> columns){
...
case BINARY:
   objectInspector = ObjectInspectorFactory.getReflectionObjectInspector(BytesWritable.class, ObjectInspectorFactory.ObjectInspectorOptions.JAVA);
break;
...
}



public static MutablePair<List<Object>, Boolean> transportOneRecord(
            Record record,List<Configuration> columnsConfiguration,
            TaskPluginCollector taskPluginCollector){
...
 case BINARY:
     recordList.add(new BytesWritable(column.asBytes()));
 break;
...
}

经过测试,text类型以及orc类型的文件全部写入正常。

      到这里肯定会有人和我有同样想法,那既然我已经写入了,我用datax去做读取数据的时候,重写写入Mysql还和原先的值是否能保持一致。因此直接看了下hdfsreader配置,发现不支持binary,统一用string方法去接数据,最终入库的数据,是一串数字+空格组成的数据。

   因为hdfs读取string时是不做处理的,直接将值拿过来,说明在hdfs里存的值就是这个,但是hive查出来又是正确的,就很神奇,这里就回想起之前BytesWritable对象的toString方法。

BytesWritable:

 /**
   * Generate the stream of bytes as hex pairs separated by ' '.
   */
  @Override
  public String toString() { 
    StringBuilder sb = new StringBuilder(3*size);
    for (int idx = 0; idx < size; idx++) {
      // if not the first, put a blank separator in
      if (idx != 0) {
        sb.append(' ');
      }
      String num = Integer.toHexString(0xff & bytes[idx]);
      // if it is only one digit, add a leading 0.
      if (num.length() < 2) {
        sb.append('0');
      }
      sb.append(num);
    }
    return sb.toString();
  }

      这就能解释为啥是数字加空格了,他将byte转为16进制数,在通过+空格的方式做转换了。看到这,那就马上想到,hdfsreader中我只要加上binary类型,然后重新将这个字符串转为byte数组问题不就解决了么。

orc类型文件需要改DFSUtil类:

private Record transportOneRecord(List<ColumnEntry> columnConfigs, List<Object> recordFields
            , RecordSender recordSender, TaskPluginCollector taskPluginCollector, boolean isReadAllColumns, String nullFormat) {
...
case BINARY:
    String [] array = columnValue.split("\\s");
    byte[] bytes = new byte[array.length];
    for (int i = 0; i<array.length;i++){
        bytes[i] = (byte) Integer.parseInt(array[i], 16);
    }
    columnGenerated = new BytesColumn(bytes);
break;
...
}

text类型文件需要改UnstructuredStorageReaderUtil:

public static Record transportOneRecord(RecordSender recordSender,
											List<ColumnEntry> columnConfigs, String[] sourceLine,
											String nullFormat, TaskPluginCollector taskPluginCollector) {
...
case BINARY:
    String [] array = columnValue.split("\\s");
    byte[] bytes = new byte[array.length];
    for (int i = 0; i<array.length;i++){
        bytes[i] = (byte) Integer.parseInt(array[i], 16);
    }
    columnGenerated = new BytesColumn(bytes);
break;
...
}

接着,在自己的job文件里将binary字段加上,再进行数据从hive同步到Mysql看结果,无论是orc文件还是text类型文件,结果显示都是正常的:

四、代码地址

github地址

【信息科学与工程学】计算机科学与技术——第七十七篇 系统架构设计02 编号类型模型配方企业资本运作的方法/规则/条件/依据及所有的步骤(​风险处理/异常处理/危机应对关联知识法律法规和裁决依据​​由发起人(通常是知名投资人、投行或产业资本)先设立一个只有现金、无实际业务的特殊目的收购公司(SPAC),通过IPO募集资金并在交易所上市。然后在规定时间内(通常24个月)寻找一家非上市公司进行合并(De-SPAC),使目标公司迅速实现上市,规避传统IPO的复杂流程和不确定性。1.:在开曼或特拉华注册空壳公司,注入少量种子资金。2. 阅读详情

相关推荐

奥比中光Gemini335L SDK实战:从标定参数到3D点云转换

本文详细介绍了奥比中光Gemini 335L深度相机的SDK实战应用,重点讲解如何跳过繁琐的棋盘格标定,直接调用出厂预标定参数实现高效的3D点云转换。通过解析内参、外参获取及四种核心坐标转换模式,并结合OpenCV等工具,指导开发者快速将相机集成到机器人抓取、三维测量等项目中,实现开箱即用的3D视觉解决方案。

raspberrypi5的博客 639

Datax-HdfsWriter如何实现支持decimal类型数据写入

一、问题背景 之前在做Datax数据同步时,发现源端binary、decimal等类型的数据无法写入hive字段。看了一下官网文档,DataX HdfsWriter 插件文档,是1-2年前的,当初看过部分源码其实底层hadoop是支持这些类型写入的,后来随着工作变动也忘了记录下来,借着近期datax群里又有人问起,勾起了回忆,索性改一下源码记录一下。 很重要的一点:我们其实要知道,datax只不过是个集成了异构数据源同步的框架,真正的读取和写入都是数据源底层本身支持功能才能用,所以要想知道某个功能支不支持

SOFT2030的专栏 1442

Halcon实战:5分钟搞定线序颜色检测(附完整代码解析)

本文详细介绍了如何使用Halcon在5分钟内实现工业级线序颜色检测的高效方案。通过机器视觉技术,结合实战项目经验,提供完整的代码解析和优化技巧,帮助开发者快速构建鲁棒性强、准确率高的检测系统,适用于电子制造和汽车线束等行业。

weixin_29098367的博客 440

Flink 维表异步查询的实现以及问题排查

本文基于Flink 1.13.3 Flink计算引擎VVR版本的hbase Connector 具体maven依赖如下: 在基于VVR版本的cloudHbase维表查询的时候,发现同步查询的速度很慢,所以我们打算做基于异步的维表查询。在运行的过程中发现了NPE问题,具体的报错堆栈如下: 先说结论 Flink计算引擎VVR版本的hbase Connector把hbase的数据转化为RowData的时候存在多线程问题,这种会导致NPE问题 相比Asynchronous I/O for External Dat

monkeyboy_tech的博客 2673

Android双目摄像头(RGB+IR)实时预览与人脸活体检测实战指南

本文详细介绍了Android双目摄像头(RGB+IR)实时预览与人脸活体检测的实战指南。通过双摄同步预览、人脸检测与活体判断等技术实现,提升安全认证的准确性和鲁棒性。文章还提供了开发环境搭建、常见问题解决方案及性能优化建议,帮助开发者快速掌握双目摄像头在Android平台的应用。

vulkan6gpu的博客 689

从零开始:用Kimi API和LangChain打造智能写作助手

本文详细介绍了如何从零开始,利用Kimi API提供的强大AI大模型能力,结合LangChain框架构建一个智能写作助手。通过实战演示了环境搭建、核心写作链构建、以及引入检索增强生成和智能体等进阶功能,旨在解决长文档创作、事实准确性等痛点,打造一个能理解意图、调用工具并保持记忆的智能创作伙伴。

weixin_29294395的博客 138

DataX系列2- 安装DataX

一.系统要求 Linux JDK(1.8以上,推荐1.8) Python(推荐Python 2.6.x) Apache Maven 3.x(编译DataX时才需要)   此处使用二进制安装包的方式安装,所以无需使用Maven,相关软件配置信息如下: [root@10-31-1-119 ~]# java -version openjdk version "1.8.0_242" OpenJDK Runtime Environment (build 1.8.0_242-b08) OpenJDK 64-Bit

只是甲的博客 548

MinerU在线API异步调用代码开发示例

本文展示了如何使用Python异步编程调用MinerU在线API进行文件批量上传。代码示例包含三个主要功能:1) 通过API密钥获取文件上传URL;2) 使用信号量控制并发上传多个文件;3) 获取提取结果。实现采用httpx异步客户端和asyncio库,支持文件存在性检查、错误处理和日志记录。示例中演示了如何上传PDF文件到MinerU平台,并提供了获取批量处理结果的接口。该代码可作为异步调用MinerU API的参考实现。

拥抱具身智能,昇腾Ascend C 351

ogg oracle到hive,利用Spark实现Oracle到Hive的历史数据同步

1、需求背景和上一篇文章Spark通过修改DataFrame的schema给表字段添加注释一样,通过Spark将关系型数据库(以Oracle为例)的表同步的Hive,这里讲的只是同步历史数据,不包括同步增量数据。2、Oracle和Hive的字段类型对应利用Spark的字段类型自动匹配,本来以为Spark匹配的不是很好,只是简单的判断一下是否为数字、字符串,结果经验证,Spark可以获取到Oracl...

weixin_31907307的博客 1027

Python爬虫实战:高效爬取法律法规数据库的完整指南

本文将详细介绍如何使用Python最新技术栈构建一个高效、稳定的法律法规数据库爬虫。我们将从爬虫的基本原理讲起,逐步深入到反爬机制应对、数据解析与存储、性能优化等高级话题。文章包含完整的代码实现,使用requests-html、aiohttp等现代库,以及应对法律数据库特殊结构的处理技巧。通过本文,您将掌握构建专业级法律数据采集系统的全套技能。关键词:Python爬虫、法律法规、数据采集、异步爬虫、反反爬本文详细介绍了使用Python爬取法律法规数据库的完整技术方案。

2201_76125261的博客 1274

实现敌人跟随玩家。(Unity)

首先和玩家设置一模一样,给敌人添加一个刚体,设置一个碰撞器,并设置一个触发器。然后在对场景里面的组件添加导航网格代理并且进行bake烘焙,那样的话敌人就可以在进行烘焙的位置进行移动。创建脚本,并且挂载脚本到敌人的组件上,用代码进行实现效果,并且要挂载目标对象。

weixin_57813136的博客 1868

MySQL类型定义 - 二进制类型

二进制类型 二进制数据和文本数据在mysql 中的最大区别在于: 二进制类型存储原始的二进制数据(如图片,视频,exe文件等)。文本类型(TEXT)用来存储字符字符串(如由英文字符、中文字符或其它语言字符组成的字符串)。 二进制类型没有字符集,并且排序和比较基于列值字节的数值。而TEXT类型有字符集,并且根据字符集的校对规则对值进行排序和比较。 二进制类型是存储二进制数据的数据类型,包括BINARY、VARBINARY、BIT、TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。二进制类

骆驼胡杨的博客 2511

故障诊断 | CNN-BiGRU-Attention故障诊断

故障诊断 | CNN-BiGRU-Attention故障诊断

机器学习之心的博客,关注并私信文章链接,获取对应文章源码和数据。 673

Datax抽取数据到hive中decimal类型操作

一、问题背景 之前在做Datax数据同步时,发现源端binary、decimal等类型的数据无法写入hive字段。看了一下官网文档,DataX HdfsWriter 插件文档,是1-2年前的,当初看过部分源码其实底层hadoop是支持这些类型写入的,后来随着工作变动也忘了记录下来,借着近期datax群里又有人问起,勾起了回忆,索性改一下源码记录一下。 很重要的一点:我们其实要知道,datax只不过是个集成了异构数据源同步的框架,真正的读取和写入都是数据源底层本身支持功能才能用,所以要想知道某个功能支不支持

hzp666的博客 2410

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

DataX在数据迁移中的应用

简介:DataX在数据迁移中的应用1. DataX定义首先简单介绍下datax是什么。DataX是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL、Oracle、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS)、DRDS 等各种异构数据源之间高效的数据同步功能。2. DataX 商业版本阿里云DataWorks数据集成是DataX团队在阿里云上的商业化产品,致力于提供复杂网络环境下、丰富的异构数

阿里云开发者 1660

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

DataX:高效离线数据同步工具的核心技术与实践

数据同步是ETL(Extract-Transform-Load)流程中的关键环节,用于实现异构数据源之间的高效数据传输。DataX作为阿里巴巴开源的高性能离线数据同步工具,采用插件化架构和分布式设计,支持MySQL、Oracle、HDFS等30+数据源的无缝对接。其核心原理通过Reader/Writer插件体系实现数据抽取与加载,配合Channel并行机制显著提升传输效率,实测可达200MB/s。在金融风控、电商大促等需要TB级数据迁移的场景中,DataX的断点续传和任务状态持久化机制保障了数据一致性。针对

weixin_34408624的博客 313

hive和mysql传输数据类型_hive的数据类型

1. 基本数据类型新增数据类型TIMESTAMP的值可以是:• 整数:距离Unix新纪元时间(1970年1月1日,午夜12点)的秒数• 浮点数:距离Unix新纪元时间的秒数,精确到纳秒(小数点后保留9位数)• 字符串:JDBC所约定的时间字符串格式,格式为:YYYY-MM-DD hh:mm:ss:fffffffffBINARY数据类型用于存储变长的二进制数据。2.复杂数据类型3.数据类型应用举例#...

weixin_39963853的博客 537

解决报错:Failed to locate the winutils binary in the hadoop binary path

项目要使用spark查询ElasticSearch中的数据。在使用spark时(创建spark context)出现这样一个错误: 报错信息: ERROR Shell: Failed to locate the winutils binary in the hadoop binary path java.io.IOException: Could not locate executable nu...

sugar_HIT的博客 7616

阿里云 EMR Delta Lake 在流利说数据接入中的架构和实践

背景 流利说目前的离线计算任务中,大部分数据源都是来自于业务 DB,业务DB数据接入的准确性、稳定性和及时性,决定着下游整个离线计算 pipeline 的准确性和及时性。同时,我们还有部分业务需求,需要对 DB 中的数据和 hive 中的数据做近实时的联合查询。 在引入阿里云 EMR Delta Lake 之前,我们通过封装 DataX 来完成业务 DB 数据的接入,采用 Master-Slave 架构,Master 维护着每日要执行的 DataX 任务的元数据信息,Worker 节点通过不断的以抢占的

数据库技术 327

Hive bitmap udf

Hive bitmap udf - 简书

xingyuelhb的博客 582

Apache Doris 实时分析数据库:从零部署到实战应用

在数据量激增的背景下,传统关系型数据库难以应对海量数据的实时分析与复杂聚合查询需求。列式存储与MPP(大规模并行处理)架构成为解决这一挑战的核心技术原理,它们通过按列组织数据、并行计算节点协同工作,实现了对PB级数据的高效处理与亚秒级查询响应。这种架构的技术价值在于能够显著提升数据分析性能,同时支持高并发写入与查询,为构建统一数据仓库、实时报表系统等场景提供了强大支撑。Apache Doris作为一款高性能的实时分析型数据库,正是基于这些技术构建,它兼容MySQL协议,简化了技术栈,并支持从Kafka等数据

weixin_30448603的博客 501

DataStream API【3】

例如,如果上游算子的并行度为2,而下游算子的并行度为4,那么一个上游算子实例将把元素均匀分配给两个下游算子实例,而另一个上游算子实例将把元素均匀分配给另外两个下游算子实例。相反,如果下游算子的并行度为2,而上游算子的并行度为4,那么两个上游算子实例将分配给一个下游算子实例,而另外两个上游算子实例将分配给另一个下游算子实例。转发分区策略只将元素转发给本地运行的下游算子的实例,即将元素发送到与当前算子实例在同一个TaskManager的下游算子实例,而不需要进行网络传输。每个下游算子的实例都具有相等的负载。

Poor - Because you have no ambition 738

Flink中的 BinaryRowData 以及大小端

本文基于Flink 1.17.0分析其内存管理机制与BinaryRowData优化。Flink同时使用堆内内存(存储用户对象和运行时数据)和堆外内存(包括网络通信用的直接内存和RocksDB等第三方库用内存),均通过MemorySegment封装,并提供不同分配方法。BinaryRowData设计可减少GC压力、降低内存占用及序列化开销。此外,MemorySegment通过判断系统字节序(大小端)确保数据在网络传输和持久化时的正确解析,保障数据处理一致性。

monkeyboy_tech的博客 480

Datax-HdfsWriter如何实现支持Map,List,Set等符合类型数据写入

一、问题背景 之前分析hdfswriter时,看到过api支持map,list,set类型的数据写入,因此,想将其合入到datax里,使得源数据端有类似json,array等这种数据可以直接导入到hive中。 二. 环境准备 Datax版本:3.0 Hadoop版本:2.7.3 Hive版本:2.3.2 三. 源码 hdfs写入时,最重要的是获取字段对应类型的ObjectInspector,因此直接从ObjectInspectorFactory类入手看: Obje...

Shadow_Light的博客 902

HDFS写入和Hive ORC写入HDFS流程解析

图片来源《Hadoop权威指南第四版》

abcCL6的专栏 1493
上一篇: Datax-HdfsWriter如何实现支持decimal类型数据写入
下一篇: Datax-HdfsWriter如何实现支持Map,List,Set等符合类型数据写入
Shadow_Light
博客等级 码龄11年 24粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值