【原创】修改Sqoop1.4.6源码实现--fields-terminated-by选项支持多字节分隔符
修改Sqoop1.4.6源码实现--fields-terminated-by选项支持多字节分隔符
最近项目中需要使用sqoop实现oracle与hdfs的数据交换,从oracle数据表导入到hdfs集群,以及把hdfs数据导出到oracle数据表。客户要求Hdfs文本文件中,字段分隔符必须是“|@|”。然而发现sqoop的—fields-terminated-by选项只能支持单字节分隔符,无法支持多字节分隔符,难以满足要求。上网搜索了一下,并没有太多公开资料能较好的解决这个问题。这篇文章(http://www.cnblogs.com/YFYkuner/p/3748495.html)是通过修改codegen生成的Java代码,再编译实现多字节分隔。不过这种办法还不够通用,并不能完全满足我的需求。但通过这篇文章可以学习到,分隔符主要是在DelimiterSet这个类定义。所以,我打算修改sqoop的源代码,使其支持多字节分隔。
使用sqoop1.4.6,下载地址:http://www.apache.org/dyn/closer.lua/sqoop/1.4.6
1. Sqoop工作原理
Sqoop在进行导入导出任务时,都会先自动生成一个java文件,并编译打成jar包,再提交到hadoop集群真正执行MapReduce任务。可以先阅读sqoop自动生成的java文件,看看其中数据导入导出的接口,以及分隔符如何被使用。这样可以有一个整体的印象。参考http://www.cnblogs.com/YFYkuner/p/3748495.html
2. 核心代码修改
2.1. 分隔符DelimiterSet的修改
首先了解一下分隔符org.apache.sqoop.lib.DelimiterSet的定义。

第一个字段field就是 –fields-terminated-by 指定的字段分隔符。源文件中变量类型是char,只能支持单字节。因此,首先需要将其修改为String类型,以便支持多字节分隔。

同时,DelimiterSet类的成员变量fieldDelim也需要修改为String类型。

2.2. 从Oracle导入Hdfs的修改
Sqoop主要是使用org.apache.sqoop.orm.ClassWriter类来实现从Oralce导入数据到Hdfs的。ClassWriter通过generateClassForColumns函数自动生成对应的java代码,这些被生成的代码才是真正在hadoop集群上执行。

其中导出到hdfs文本文件这段代码,具体是generateToString函数生成。

由于我们把DelimiterSet的fieldDelim字段类型从char改成了String,因此ClassWriter自动生成的java源码,也需要对应的修改。所以,需要修改如下:


2.3. 从Hdfs导出到Oracle的修改
从Hdfs导出到Oracle数据表,主要改动在于对Hdfs文本记录的解析,能够识别多字节分隔符。文本解析是通过org.apache.sqoop.lib.RecordParser的parseRecord方法来实现的。

源码是通过一个有限状态机来解析文本。我这里用String的split方法做了个最简单的处理来替换。

2.4. 解析--fields-terminated-by参数
sqoop通过命令行参数--fields-terminated-by设置分隔符。所以需要在org.apahe.sqoop.tool.BaseSqoopTool中设置Input和Output的分隔符,修改为字符串类型。修改如下:


2.5. 变更源码文件一览
由于修改了变量类型,以及相关函数参数,为了解决编译错误,还需要修改一些其它java文件。所有被修改的java文件如下。

3. 编译和打包
在ubuntu下使用ant编译和打包。参考sqoop的README,我安装的是jdk1.8.0_121和ant1.10.1。
|
== Compiling Sqoop Compiling Sqoop requires the following tools: * Apache ant (1.7.1) * Java JDK 1.6 Additionally, building the documentation requires these tools: * asciidoc * make * python 2.5+ * xmlto * tar * gzip To compile Sqoop, run +ant package+. There will be a fully self-hosted build provided in the +build/sqoop-(version)/+ directory. |
执行ant package命令即可。

在build下得到构建产物。

BTW:这里我指定了hadoop版本是2.6.1,只要在build.xml中修改版本号即可。

4. 测试
从Oracle导入Hdfs:
sqoop import --connect jdbc:oracle:thin:@ip:port --username username --password password --target-dir /hdfs/cluster/sqoop/dir --table oracletable --fields-terminated-by \\\\\|@\\\\\|
从Hdfs导出Oracle:
sqoop export --connect jdbc:oracle:thin:@ip:port --username username --password password --table oracletable --fields-terminated-by \\\\\|@\\\\\| --export-dir /hdfs/cluster/sqoop/dir
验证发现hdfs文件中字段分隔符确实是“|@|”,测试通过。
最后抛出一个问题供思考:分隔符是“|@|”,但为什么测试命令中--fields-terminated-by 指定的却是“\\\\\|@\\\\\|”呢?
【原创】修改Sqoop1.4.6源码实现--fields-terminated-by选项支持多字节分隔符的更多相关文章
- 完美原创:centos7.1 从源码升级安装Python3.5.2
(原创)完美原创:centos7.1 从源码升级安装Python3.5.2 下载Python3.5.2源码:https://www.python.org/downloads/release/pytho ...
- es 修改拼音分词器源码实现汉字/拼音/简拼混合搜索时同音字不匹配
[版权声明]:本文章由danvid发布于http://danvid.cnblogs.com/,如需转载或部分使用请注明出处 在业务中经常会用到拼音匹配查询,大家都会用到拼音分词器,但是拼音分词器匹配的 ...
- 修改Java标准库源码
以下是摘抄,实际操作没有测试 先前我曾提到,原本想借由“改动Java标准库源码”来测知Class object的生成,但由于其ctor原始设计为private,也就是说不可能透过这个管道生成Cla ...
- 32.修改IK分词器源码来基于mysql热更新词库
主要知识点, 修改IK分词器源码来基于mysql热更新词库 一.IK增加新词的原因 在第32小节中学习到了直接在es的词库中增加词语,来扩充自已的词库,但是这样做有以下缺点: (1)每次添加完 ...
- 记一次在mac上源码编译curl,使其支持NSS的过程
一.背景 在一次学习https原理的过程中,希望客户端指定特定的cipher suites来抓包分析SSL/TLS的握手过程,就想到了使用curl工具,而不是使用浏览器. 接下来使用man curl找 ...
- 从源码解析Nginx对 Native aio支持_运维_youbingchen的博客-CSDN博客 https://blog.csdn.net/youbingchen/article/details/51767587
从源码解析Nginx对 Native aio支持_运维_youbingchen的博客-CSDN博客 https://blog.csdn.net/youbingchen/article/details/ ...
- Sqoop-1.4.6 Merge源码分析与改造使其支持多个merge-key
Sqoop中提供了一个用于合并数据集的工具sqoop-merge.官方文档中的描述可以参考我的另一篇博客Sqoop-1.4.5用户手册. Merge的基本原理是,需要指定新数据集和老数据集的路径,根据 ...
- 【原创】express3.4.8源码解析之中间件
前言 注意:旧文章转成markdown格式. 中间件(middleware)的概念来自于TJ的connect库,express就是建立在connect之上. 就如同connect的意思是 连接 一样, ...
- 【原创】angularjs1.3.0源码解析之directive
# Angular指令编译原理 前言 angular之所以使用起来很方便,是因为通常我们只需要在html里面引入一个或多个(自定义或内置的)指令就可以完成一个特定的功能(这也是angular推荐的方式 ...
随机推荐
- 理解webpack4.splitChunks之其余要点
splitChunks除了之前文章提到的规则外,还有一些要点或是叫疑惑因为没有找到官方文档的明确说明,所以是通过我自己测试总结出来的,只代表我自己的测试结果,不一定正确. splitChunks.ca ...
- Vue.js双向绑定原理
Vue.js最核心的功能有两个,一个是响应式的数据绑定系统,另一个是组件系统.本文仅仅探究双向绑定是怎样实现的.先讲涉及的知识点,再用简化的代码实现一个简单的hello world示例. 一.访问器属 ...
- 七、angularjs 倒计时
使用定时器时离开页面需要清除定时器,清除的方法有两种分别针对页面有缓存和没有缓存 1.页面有缓存 2.页面没有缓存 angularjs倒计时首先需要注入:$interval 60s倒计时 vm.sec ...
- Android开发精彩博文收藏——UI界面类
本文收集整理Android开发中关于UI界面的相关精华博文,共大家参考!本文不定期更新! 1. Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各 ...
- Stop-VM
stop-vm vm01 -force 正常关机,留给Guest 5分钟保存数据,然后关闭 stop-vm vm02 -turnoff 断电关机 Windows Server 2008 R2默认没有 ...
- Linux下调节CPU使用的几种方法
一,使用taskset充分利用多核cpu,让cpu的使用率均衡到每个cpu上 #taskset-p, 设定一个已存在的pid,而不是重新开启一个新任务-c, 指定一个处理,可以指定多个,以 ...
- Python学习---生成器的学习1210
在Python中,这种一边循环一边计算的机制,称为生成器: 结论: 生成器本质是一个函数,不同于函数的是它生成的是一个对象,不执行函数内的代码 1.1. 列表生成器 列表生成器: 列表是直接生成数字在 ...
- 用AutoHotkey实现Excel从表B提取匹配数据到表A
说明:为表述方便,待填的表为[表A],资料库的表称为[表B].该工具可以快捷地从[表B]中提取相关数据到[表A],顺序和列可自定义. 使用方法:1.打开[ExcelGetFromB.exe](如要打开 ...
- August 17th 2017 Week 33rd Thursday
Fate is responsible for shuffling, but the game of cards is our own! 命运负责洗牌,但是玩牌的是我们自己! Today, I upd ...
- 【解决方案】[XCUITest] WDA is not listening at 'http://localhost:8100/'
1. 使用Xcode 编译 WebDriver 发现端口为:serverurlhere->http://手机ip:0 <-serverurlhere 2. 解决方案: xcodebuild ...