Sqoop操作实践-阿里云开发者社区

开发者社区> xiaohei.info> 正文

Sqoop操作实践

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1010885678/article/details/50504925 Sqoo...
+关注继续查看
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1010885678/article/details/50504925

Sqoop操作实践

@(Hadoop)


Sqoop常用参命令

序号 命令/command 说明
1 impor ImportTool 从关系型数据库中导入数据(来自表或者查询语句)到HDFS中
2 export ExportTool 将HDFS中的数据导入到关系型数据库中
3 codegen CodeGenTool 获取数据库中某张表数据生成Java并打成jar包
4 create-hive-table CreateHiveTableTool 创建Hive表
5 eval EvalSqlTool 查看SQL执行结果
6 import-all-tables ImportAllTablesTool 导入某个数据库下所有表到HDFS中
7 job JobTool
8 list-databases ListDatabasesTool 列出所有数据库名
9 list-tables ListTablesTool 列出某个数据库下所有表
10 merge MergeTool
11 metastore MetastoreTool
12 help HelpTool 查看帮助
13 version VersionTool 查看版本

通用参数

序号 参数 说明 样例
1 connect 连接关系型数据库的URL jdbc:mysql://localhost/sqoop_datas
2 connection-manager 连接管理类,一般不用
3 driver 连接驱动
4 hadoop-home hadoop目录 /home/guoyun/hadoop
5 help 查看帮助信息
6 password 连接关系型数据库的密码
7 username 链接关系型数据库的用户名
8 verbose 查看更多的信息,其实是将日志级别调低

–where和–query导入部分表数据

Sqoop的–import使用–table指定表之后,默认是导入该表的全部数据,有时候我们可能只需要表其中一部分的数据,或者仅仅是导入小部分数据作为测试,那么可以使用–where和–query参数来进行条件限定。

–where:例如”id<100”,只导入该表id小于100的数据,和sql的where条件是一样的。

–query:引号中的是SQL语句,SQL执行的结果就是要导入的数据,必须和–target-dir一起使用。

增量导入

以下三个参数必须同时指定:

–check-column (col):检查指定的列,根据此列判断哪些记录是新数据且需要导入的,列不能是字符相关类型(CHAR/NCHAR/VARCHAR/VARNCHAR/ LONGVARCHAR/LONGNVARCHAR),一般为数据库中的关键字。
–incremental (mode):指定增量模式,mode包含两种方式,append和lastmodified。

  • 当表中的记录是以id持续增加导入新的记录的时候,可以使用append模式,–check-column id 用于检查id。
  • lastmodified: 表有时候也会执行更新操作,此时可以使用lastmodified导入。

–last-value (value): –check-column的某个值,将大于该值的检查列记录导入,以确定仅将新的或者更新后的记录导入新的文件系统。

和–append参数的区别:
–append导入的时候不会再次创建新的HDFS目录(使用普通命令的话,会创建一个新的HDFS目录,如果该目录已存在则会失败),该命令会直接在已存在的目录下继续导入数据,但是不管数据是否重复。

-import-all-tables导入多表

导入的每个表数据被分别存储在以表名命名的HDFS上的不同目录中。
使用该命令以下三个条件必须同时满足:

  • 1、每个表必须都只有一个列作为主键;
  • 2、必须将每个表中所有的数据导入,而不是部分;
  • 3、必须使用默认分隔列,且WHERE子句无任何强加的条件

–table, –split-by, –columns, 和 –where参数在sqoop-import-all-tables命令中是不合法的。

也就是说,使用-import-all-tables就无法使用增量导入和部分导入了。

–exclude-tables:默认是导入该数据库的全部表,如果只想导入部分表,可以使用该参数将不想导入的表排除掉。

map并行任务数

Sqoop并行导入原理:
默认情况下map的任务数是4,假设导入的表主键为id,那么Sqoop会先进行下面这样一个查询。

select max(id) as max, select min(id) as min from table [where 如果指定了where子句];

通过这个查询,获取到需要拆分字段(id)的最大值和最小值,假设分别是1和1000。

然后,Sqoop会根据需要并行导入的数量,进行拆分查询,比如上面的这个例子,并行导入将拆分为如下4条SQL同时执行:

select * from table where 0 <= id < 250;
select * from table where 250 <= id < 500;
select * from table where 500 <= id < 750;
select * from table where 750 <= id < 1000;

注意,这个拆分的字段需要是整数,使用–split-by参数进行指定。
从上面的例子可以看出,如果需要导入的表没有主键,我们应该如何手动选取一个合适的拆分字段,以及选择合适的并行数。

map的任务数不超过集群可以用的mr并行度(节点数),不超过数据库能性能影响的极值。

测试

#测试增量导入
#第一次导入RECORD_NO<100的数据
sqoop import --connect jdbc:oracle:thin:@ip:port:database --username uid --password pwd --target-dir /oracle/$database -m 1 --table tableName  --fields-terminated-by '\001' --where "RECORD_NO<100"

#第二次增量导入RECORD_NO<200的数据,从RECORD_NO=99开始
sqoop import --check-column RECORD_NO --incremental append --last-value 99 --connect jdbc:oracle:thin:@ip:port:database --username uid --password pwd --target-dir /oracle/$database -m 1 --table tableName  --fields-terminated-by '\001' --where "RECORD_NO<200"

#第三次增量导入全部数据,从RECORD_NO=199开始
sqoop import --check-column RECORD_NO --incremental append --last-value 199 --connect jdbc:oracle:thin:@ip:port:database --username uid --password pwd --target-dir /oracle/$database -m 1 --table tableName  --fields-terminated-by '\001' --split-by RECORD_NO

#测试多表导入
sqoop import-all-tables --connect jdbc:oracle:thin:@ip:port:database --username uid --password pwd --target-dir /oracle/$database -m 8 --fields-terminated-by '\001' --exclude-tables excludeTablesName

#单表导入全部数据,使用并行导入,指定分割列
sqoop import --connect jdbc:oracle:thin:@ip:port:database --username uid --password pwd --target-dir /oracle/$database -m 1 --table tableName  --fields-terminated-by '\001' --split-by PAYMENT_ID

测试失败,待重试

定时导入脚本实现

#!/bin/bash

#Oracle的连接字符串,其中包含了Oracle的地址,SID,和端口号
url=jdbc:oracle:thin:@ip:port:database
#使用的用户名
uid=username
#使用的密码
pwd=password
#需要从Oracle中导入的表名
tableName=tableName
#需要从Oracle中导入的表中的字段名
columns=columns
#将Oracle中的数据导入到HDFS后的存放路径
hdfsPath=path/$tableName

#执行导入逻辑。将Oracle中的数据导入到HDFS中
sqoop import --connect $url --username $uid --password $pwd --target-dir $hdfsPath  --m 1 --table $tableName --columns $columns --fields-terminated-by '\001'

设置定时执行

#编辑cron文件,设置定时执行
crontab -e

#文件内容,每天凌晨1点执行数据导入脚本
* 1 * * * 脚本所在路径

#保存退出之后即可

关于crontab一些知识请看:
linux设置定制器自动执行任务

注意事项

  • 导入关系型数据库的数据时,确保集群上的所有节点都能连接到对应数据库服务器的IP和端口号!
  • 用户名和表名一定要大写!

可以先使用list-tables测试能否连通再执行mr导入数据
统计导入的数据行数:

hadoop fs -cat  /导入的文件 | wc -l 

导入HBase示例

#使用query参数自定义结果集,全量导入测试通过: 
sqoop import  --connect jdbc:oracle:thin:@ip:port:database --username UID --password pwd --query 'select reverse(t.op) as ROWKEY from  table t WHERE (1=1)  and $CONDITIONS ' --hbase-table test  --column-family test  --hbase-row-key ROWKEY --hbase-create-table -m 8 --split-by ORDER_ID

增量导入测试通过:
sqoop import  --connect jdbc:oracle:thin:@ip:port:database --username UID --password pwd --query 'select reverse(t.op) as ROWKEY from  table t WHERE (1=1)  and $CONDITIONS and t.ID<23' --hbase-table testapp  --column-family test  --hbase-row-key ROWKEY --hbase-create-table -m 8 --split-by ID --hbase-create-table

sqoop import  --connect jdbc:oracle:thin:@ip:port:database --username UID --password pwd --query 'select reverse(t.op) as ROWKEY from  table t WHERE (1=1)  and $CONDITIONS and t.ID<227840' --hbase-table test  --column-family test  --hbase-row-key ROWKEY --hbase-create-table -m 8 --split-by ID --check-column ID --incremental append --last-value 22

注意事项:

  • 使用query参数时,如果sql中包含单引号,那么整个sql需要用双引号包裹起来,$CONDITIONS参数需要用\进行转义,变为\$CONDITIONS,否则会报错。
  • 增量导入的时候check-column指定为数字类型的字符串失败,需要使用数字类型。

1.27更新

检查发现导入hdfs的很多数据和oracle中的对不上,排查了很久发现是-m 8,这个并行量设置的问题(-m 1使用一个map进行导入是正确的数据)。

猜测,可能是–split-by设置的字段造成导入的时候有的数据没有导入,有的数据重复导入,但是我使用的是rownum这个内置的变量,理应是没错的,不得其解。

作者:@小黑

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
python3操作pymsql模块
pymysql是python中操作mysql的模块。 1.pymysql模块的安装 pip3 install pymysql 也可以使用pycharm这个IDE工具来安装pymysql这个模块。 2.pymysql模块的使用 1.
943 0
Hadoop I/O操作原理整理
I/O操作中的数据检查   校验和方式是检查数据完整性的重要方式。一般会通过对比新旧校验和来确定数据情况,如果两者不同则说明数据已经损坏。比如,在传输数据前生成了一个校验和,将数据传输到目的主机时再次计算校验和,如果两次的校验结果不同,则说明数据已经损坏。
552 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
4480 0
open文件操作
基本方式: r = 只读不写 w = 只写模式,文件不存在则创建,文件存在则清空 x = 只写模式,不可读,文件不存在可以创建,文件存在直接报错。 a = 追加 , 不可读,不存在则创建,存在可在尾部追加 假如:文件名是:db 内容:123456 f = open("db","r") #r:只读 date = f.
683 0
Java操作wkhtmltopdf实现Html转PDF
做java开发的都知道,java生成pdf大部分都是用itext,itext的确是java开源组件的第一选择。不过itext也有局限,就是要自己写模版,系统中的表单数量有好几百个,为每个表单做一个导出模版不现实。 所以找了个直接可以调用的工具wkhtmltopdf,将生成好的html直接转换成pdf。功能很强大。   wkhtmltopdf是一个使用webkit网页渲染引擎开发的用来将
4271 0
阿里云服务器远程登录用户名和密码的查询方法
阿里云服务器远程连接登录用户名和密码在哪查看?阿里云服务器默认密码是什么?云服务器系统不同默认用户名不同
443 0
+关注
121
文章
1
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载