sqoop实现关系型数据库与hadoop之间的数据传递-import篇

由于业务数据量日益增长,计算量非常庞大,传统的数仓已经无法满足计算需求了,所以现在基本上都是将数据放到hadoop平台去实现逻辑计算,那么就涉及到如何将oracle数仓的数据迁移到hadoop平台的问题。

这里就不得不提到一个很实用的工具——sqoop,它是一款开源的工具,主要用于实现关系型数据库与hadoop中hdfs之间的数据传递,其中用的最多的就是import,export了。

sqoop的安装配置也是非常简单的,这里就不说明了,本文主要针对如何使用sqoop实现oracle到hive(hdfs)的数据传递进行试验。

对于比较全的参数使用,可以到sqoop的官方文档http://sqoop.apache.org/docs/ 查看,以下是这次会用到的一些参数讲解:

-m N :开启N个map来导入数据

--query : 从查询结果导入数据,注意,如果使用了该参数,那么必须指定--target-dir参数,并且查询条件中要包含$CONDITIONS

--target-dir :指定数据在HDFS中的存放目录

--hive-table :导入到hive的目标表名

--fetch-size :一次从数据库中读取的记录数

--hive-drop-import-delims :将数据导入到hive时,去掉其中的\n,\r,\001等特殊字符

--null-string <null-string> :对于string类型的字段,如果值为null,那么使用<null-string>替代

--non-null-string <non-null-string> :对于非string类型的字段,如果值为null,那么使用<null-non-string>替代

(通常我们使用的是

--null-string ‘\\N‘ \

--null-non-string ‘\\N’ \

Hive中null默认是使用\N来表示的,如果想要替换成\N,那么还要多加一个\来转义)

--hive-partition-key :hive表的分区字段

--hive-partition-value :指定导入到hive表的分区对应的分区值

--hive-overwrite :覆盖重写(这里注意,如果说没有使用到--hive-partition-key,hive-partition-value,那么--hive-overwrite的使用会将整个表的数据都覆盖,反之,则只是覆盖对应的 某个分区的数据)

--verbose :打印出详细的信息

================================================================================================

这里要注意,如果你要导入的数据里面包含\n,\r,\001之类的特殊字符,那么要使用--hive-drop-import-delims去掉这些特殊字符,否则,如果字符串中有换行,那么换行符之后的数据将会被识别为另一行,导致结果不正确。

另一个需要注意的地方,如果导入的数据有些字段值是null的,要加上--null-string,--null-non-string参数,否则,这些null值将会被错误的替换为‘null‘这个字符串。

为了更好的说明这几个参数的重要性,下面来做一下试验:

平台说明:

Oracle    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

Hadoop  hadoop-2.7.2

Hive     hive-2.1.0

Sqoop         sqoop-1.4.6

oracle中scott用户下的数据:

说明:empno为7000,8000,9000,9001的记录中,有的是JOB这个varchar2类型的值为null,有的是MGR这个number类型的值为null,而empno为9002的记录中,JOB为\nClERK\n(前后都有换行符)。

(1)不使用sqoop的相关参数进行处理:

 1 sqoop import --query "select a.empno,
 2                                a.ename,
 3                                a.job,
 4                                a.mgr,
 5                                a.hiredate,
 6                                a.sal,
 7                                b.deptno,
 8                                b.dname
 9                         from emp_t1 a
10                         left join dept_t1 b
11                         on a.deptno = b.deptno
12                         where /$CONDITIONS" 13             --connect jdbc:oracle:thin:@192.168.134.200:1521/orclwin 14             --username scott \
15             --password tiger \
16             -m 1 17             --hive-table test_db.emp_t1 \
18             --hive-overwrite \
19             --target-dir /sqoop/emp_t1 \
20             --hive-import 

到hive中查看数据:

可见,原来的19条数据导入到hive中之后变成了21条,有两条是因为empno为9002没有正确处理其中的换行符导致的一条数据被分割成多条。

而9000和9001这两条数据的job字段值也不是NULL,而是‘null‘字符串:

(2)使用--hive-drop-import-delims参数处理导入数据的特殊符号,--null-string,--null-non-string处理导入数据字段值为空的情况

 1 sqoop import --query "select a.empno,
 2                                a.ename,
 3                                a.job,
 4                                a.mgr,
 5                                a.hiredate,
 6                                a.sal,
 7                                b.deptno,
 8                                b.dname
 9                         from emp_t1 a
10                         left join dept_t1 b
11                         on a.deptno = b.deptno
12                         where /$CONDITIONS" 13             --connect \ jdbc:oracle:thin:@192.168.134.200:1521/orclwin \
14             --username scott \
15             --password tiger \
16             -m 1 17             --hive-drop-import-delims \
18             --null-string ‘\\N‘ \
19             --null-non-string ‘\\N‘ \
20             --hive-table test_db.emp_t1 \
21             --hive-overwrite \
22             --target-dir /sqoop/emp_t1 \
23             --hive-import

到hive中查看数据:

数据导入正常。

好啦,这个import的功能就说到这了,下一篇再说export~

时间: 2024-10-16 21:26:53

sqoop实现关系型数据库与hadoop之间的数据传递-import篇的相关文章

使用sqoop 在关系型数据库和Hadoop之间实现数据的抽取

(一)从关系型数据库导入至HDFS 1.将下面的参数保持为 import.script import --connectjdbc:mysql://192.168.1.14:3306/test--username root--password 1234 -m1--null-string''--table user--columns "id,username,age"--target-dir/user/root/sqoop_test  -- 此目录不能存在 2. 执行sqoop --opt

ES 译文之如何使用 Logstash 实现关系型数据库与 ElasticSearch 之间的数据同

译者前言近期的主要工作是在为公司的 APP 增加搜索功能.因为也遇到了需要把关系型数据库中的数据同步 ElasticSearch 中的问题,故抽了点时间翻译了这篇官方的博文.最近,在数据同步方面也有些思考.本篇文章的重点不在 Logstash 的 JDBC 插件的使用方法,而是数据同步会遇到的一些细节问题如何处理.我觉得,这些设计思想是通用的,无论你使用的何种方式进行数据同步.翻译正文 为了利用 ElasticSearch 强大的搜索能力,大部分的业务都会在关系型数据库的基础上部署 Elasti

sqoop导入关系型数据库-解密Sqoop

Sqoop作为Hadoop与传统数据库之间的桥梁,对于数据的导入导出有着重要作用.通过对Sqoop基本语法以及功能的阐述,深刻解密Sqoop的作用和价值.  一.什么是Apache Sqoop? Cloudera开发的Apache开源项目,是SQL-to-Hadoop的缩写.主要用于在Hadoop(Hive)与传统的数据库(mysql.postgresql...)间进行数据的传递,可以将一个关系型数据库(例如: MySQL ,Oracle ,Postgres等)中的数据导进到Hadoop的HDF

JSP、servlet、SQL三者之间的数据传递

JSP.servlet.SQL三者之间的数据传递 博客分类: web开发 JSPservletSQL数据库连接池web开发 前言: 最近一直在做WEB开发,现总结一下这一段时间的体会和感触. 切记,web开发重点在于前台数据交互,页面美化而不要太沉溺于底层数据. 浏览器时代来到,向我们召唤出更炫.更简洁.更方便.更大气的网站. 这篇博客目的在于为大家解决web开发中最基础的数据传递操作,让大家有一个好的起点,在web开放中更加游刃有余 背景: 目前业界很流行的WVC(model-view-con

ASP.NET MVC3中Controller与View之间的数据传递总结

</pre>在ASP.NET MVC<span style="font-family:宋体">中,经常会在</span>Controller<span style="font-family:宋体">与</span>View<span style="font-family:宋体">之间传递数据,因此,熟练.灵活的掌握这两层之间的数据传递方法就非常重要.本文从两个方面进行探讨:&

Intent 意图 用于Activity之间的数据传递

转自:http://blog.sina.com.cn/s/blog_83940dfb0100veas.html 用于Activity之间的数据传递 在起始Activity中,发送数据 protected void onCreate(Bundle saveInstanceState){ super.onCreate(saveInstanceState); setContentView(R.layout.thisactivity); Intent intent = new Intent(); //设

Vue 爬坑之路(二)—— 组件之间的数据传递

Vue 的组件作用域都是孤立的,不允许在子组件的模板内直接引用父组件的数据.必须使用特定的方法才能实现组件之间的数据传递. 首先用 vue-cli 创建一个项目,其中 App.vue 是父组件,components 文件夹下都是子组件. 一.父组件向子组件传递数据 在 Vue 中,可以使用 props 向子组件传递数据. 子组件部分: 这是 header.vue 的 HTML 部分,logo 是在 data 中定义的变量. 如果需要从父组件获取 logo 的值,就需要使用 props: ['lo

(Android review)Activity之间的数据传递

一.基本知识点 1.Activity之间传递数据1)传递基本类型或String intent.putExtra("username", username);  getIntent(); intent.getStringExtra("username"); 2)以bundle的形式传 Bundle bundle = new Bundle();    bundle.putString("username", username);    bundle.

Activity之间的数据传递

最常用的Activity之间的数据传递. 1 btnStartAty1.setOnClickListener(new View.OnClickListener() { 2 @Override 3 public void onClick(View v) { 4 Intent i=new Intent(MainActivity.this, Activity1.class); 5 //Activity之间的数据传递 6 //i.putExtra("txt", "这是第一种Activ