Sqoop是连接传统关系型数据库和Hadoop的桥梁。把关系型数据库的数据导入到 Hadoop 系统 ( 如 HDFS、HBase 和 Hive) 中;把数据从 Hadoop 系统里抽取并导出到关系型数据库。利用MapReduce,批处理方式进行数据传输。
本篇文章主要是根据Sqoop导入导出到Hive的实际示例,对Sqoop中的import与export进行简要介绍:
========================一、sqoop数据导入import===========================
--先在Hive建表(oracle库有已建好的表TESTDB.TEST_PLANSIGN_CONF)
CREATE TABLE mydatabase.test_plansign_conf(
id decimal(38,6),
plan_sign string,
remark string,
state decimal(38,6),
create_time timestamp,
update_time timestamp
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\001'
STORED AS TEXTFILE
LOCATION '/user/hive/mydatabase/test_plansign_conf';
1、导入oracle数据到HDFS中(注:oracl的表名和字段名要大写)
sqoop import \
--connect jdbc:oracle:thin:@192.168.30.1:1521/orcl_test \
--username admin \
--password admin123 \
--table TESTDB.TEST_PLANSIGN_CONF \
--target-dir /user/hive/mydatabase/test_plansign_conf \
--delete-target-dir \
--fields-terminated-by '\0x01' \
--compress \
--compression-codec org.apache.hadoop.io.compress.GzipCodec \
-m 4 \
--split-by id \
;
2、导入oracle数据到HDFS(同时创建hive表,同时load数据到hive中)sqoop import \
--connect jdbc:oracle:thin:@192.168.30.1:1521/orcl_test \
--username admin \
--password admin123 \
--table TESTDB.TEST_PLANSIGN_CONF \
--fields-terminated-by '\0x01' \
--compress \
--compression-codec org.apache.hadoop.io.compress.GzipCodec \
-m 4 \
--split-by id \
--hive-import \
--create-hive-table \
--hive-database mydatabase \
--hive-table test_plansign_conf \
--map-column-hive ID=String,PLAN_SIGN=String,STATE=String \
;
注意:
–create-hive-table 生产上不建议使用,字段类型和我们自己预想会有差别
而且只能执行一次(再执行一次,会报表已经存在的错误)
–hive-import 在导入的时候,会默认去读Hive的default数据库,最好指定--hive-database
–hive-table 不需要自己先去Hive中创建表,执行的时候,会自动帮我们去创建相应的表
3、导入oracle数据到HDFS中(使用where条件导入)
(-P从控台提示手动输入密码)
sqoop import \
--connect jdbc:oracle:thin:@192.168.30.1:1521/orcl_test \
--username admin \
-P \
--table TESTDB.TEST_PLANSIGN_CONF \
--target-dir /user/hive/mydatabase/test_plansign_conf \
--delete-target-dir \
--fields-terminated-by '\0x01' \
--compress \
--compression-codec org.apache.hadoop.io.compress.GzipCodec \
-m 4 \
--split-by id \
--where "PLAN_SIGN='M1'" \
;
4、导入oracle数据到HDFS中(使用query查询语句 )
(注:使用-query参数不能与--table参数一起使用,且where语句的最后必须跟$CONDITIONS,$CONDITIONS就是标记当前mapper从哪个数据段开始读。--query后边如果是双引号,$CONDITIONS必须加\,避免shell识别为自己的变量。)
sqoop import \
--connect jdbc:oracle:thin:@192.168.30.1:1521/orcl_test \
--username admin \
--password admin123 \
--table TESTDB.TEST_PLANSIGN_CONF \
--delete-target-dir \
--fields-terminated-by '\0x01' \
--compress \
--compression-codec org.apache.hadoop.io.compress.GzipCodec \
-m 4 \
--split-by id \
--query 'select * from TESTDB.TEST_PLANSIGN_CONF where id < 3200000663615020 and $CONDITIONS' \
;
5、导入oracle数据到HDFS中(导入部分指定字段,其他未指定字段值为null)
sqoop import \
--connect jdbc:oracle:thin:@192.168.30.1:1521/orcl_test \
--username admin \
--password admin123 \
--table TESTDB.TEST_PLANSIGN_CONF \
--delete-target-dir \
--fields-terminated-by '\0x01' \
--compress \
--compression-codec org.apache.hadoop.io.compress.GzipCodec \
-m 4 \
--split-by id \
--columns ID,PLAN_SIGN,STATE\
;
6、导入oracle数据到HDFS中(追加导入)
(注:–incremental append 与 –delete-target-dir之间不能同时使用)
(Append方式--按递增列的增量数据导入)
sqoop import \
--connect jdbc:oracle:thin:@192.168.30.1:1521/orcl_test \
--username admin \
--password admin123 \
--table TESTDB.TEST_PLANSIGN_CONF \
--target-dir /user/hive/mydatabase/test_plansign_conf \
--fields-terminated-by '\0x01' \
--compress \
--compression-codec org.apache.hadoop.io.compress.GzipCodec \
-m 4 \
--split-by id \
--incremental append \
--check-column id \
--last-value 3200000663615020 \
;
(LastModified方式--按时间列的增量数据导入)
sqoop import \
--connect jdbc:oracle:thin:@192.168.30.1:1521/orcl_test \
--username admin \
--password admin123 \
--table TESTDB.TEST_PLANSIGN_CONF \
--target-dir /user/hive/mydatabase/test_plansign_conf \
--fields-terminated-by '\0x01' \
--compress \
--compression-codec org.apache.hadoop.io.compress.GzipCodec \
-m 4 \
--split-by id \
--incremental lastmodified \
--merge-key id \
--check-column UPDATE_TIME \
--last-value "2019-03-06 00:00:00" \
;
=========================二、sqoop数据导出export=========================
7、导出HDFS数据到postgresql库
(--update-mode模式有两种updateonly(默认)和allowinsert
updateonly:用于同步Hive表与目标表中有更新过的记录,对于新插入的记录并不能同步到。
allowinsert:用于同步Hive表与目标表中有更新过的记录,但同时也会同步新插入的记录。)
sqoop export \
--connect jdbc:postgresql://192.168.60.1:5432/test \
--username admin \
--password admin123 \
--update-mode allowinsert \ (update-mode模式有两种updateonly(默认)和allowinsert)
--table test_plansign_conf \
--fields-terminated-by '\001' \
--export-dir '/user/hive/mydatabase/test_plansign_conf' \
--input-null-string '\\N' \
--input-null-non-string '\\N' \
;
注:导入可以不用提前在hive建好表,可以根据指定参数create-hive-table来自动生成表。但是导出必须提前在关系库中建好导出目标表。
========================三、sqoop eval=============================
8、eval执行一个SQL语句,并将结果展示出来在控制台上
(在导出前常用来删除目标表中数据,防止数据重复。也可以做更新或插入操作。)
sqoop eval \
--connect jdbc:postgresql://192.168.60.1:5432/test \
--username admin \
--password admin123 \
--query "delete from test_plansign_conf" \
;
========================四、sqoop job================================
9、创建Sqoop job
sqoop job \
--create myjob \
-- import \
--connect jdbc:oracle:thin:@192.168.30.1:1521/orcl_test \
--username admin \
--password admin123 \
--table TESTDB.TEST_PLANSIGN_CONF \
--target-dir /user/hive/mydatabase/test_plansign_conf \
--delete-target-dir \
--fields-terminated-by '\0x01' \
--compress \
--compression-codec org.apache.hadoop.io.compress.GzipCodec \
-m 4 \
;
sqoop job --list 查看sqoopjob列表
sqoop job --show myjob 查看某一job明细
sqoop job --exec myjob 执行job
=====================五、导入导出常遇到的问题总结===================
1、导入数据读取异常--分隔符问题
Hive默认的字段分隔符为'\001'(八进制的ASCII码字符Ctrl-A),每条记录末尾是换行分隔符 '\n';Sqoop默认分隔符是换行符'\n'。在做导入时,需要将Hive的字段默认分隔符告知sqoop(--fields-terminated-by '\0x01' )
2、查询表不存在
先确认表是否存在,若表存在则大多是因为使用的用户对表没有查询权限,需要先授权
3、sqoop导入源表没有主键,且num-mappers(-m)任务数大于1
一定要加split-by来指定任务分割要依据的字段
4、使用上述第2条导入数据,查询某个字段值都为null
增加参数--map-column-hive ID=String后解决,猜测应该是映射类型不匹配问题
5、未完待续。。。