sqoop 导入 hive

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mn_kw/article/details/90602320

sqoop 导入 Hive 分三步:
1. 先导入--target-dir 指定的 HDFS 的目录中
2. 在 Hive 中建表
3. 调用 Hive 的 LOAD DATA INPATH--target-dir中的数据移动到 Hive 中

import
--hive-import
--hive-table dw_hd.ods_store
--connect jdbc:oracle:thin:@<HOST>:1521:app
--username user
--password 123456
--query
select * from HD.STORE where $CONDITIONS and \
RCVTIME < TO_TIMESTAMP('2017-05-30 00:00:00','yyyy-mm-dd hh24:mi:ss.ff')
--split-by FLOWNO
--direct
--target-dir /user/root/store
--null-string '\\N'
--null-non-string '\\N'
--m 2
 

--hive-import :指定是导入 Hive
--hive-table:导入 Hive 中的数据库名和表名
--null-string和 --null-non-string:分别代表了 sqoop 对 字符串类型 null 值 和 非字符串类型 null 值 的处理。如果不指定的话,默认导入 Hive 后 字符串类型的 null 值是 ‘null’,非字符串类型 null 值是 ‘NULL’,这里用把这两种情况统一成了 ‘NULL’,sqoop 中用 ‘\N’,如果想要小写的 ‘null’  的话,使用 ‘\N’。
 

问题1:导入后从Hive中查到的数据条数比实际从关系数据库中查到的条数多?

解决:原因是使用--hive-import 会使用默认的 Hive 的分隔符,值分隔符^A和行分隔符\n

这样问题就来了,如果导入的数据中有’\n’,hive会认为一行已经结束,后面的数据被分割成下一行。这种情况下,导入之后hive中数据的行数就比原先数据库中的多,而且会出现数据不一致的情况。 
Sqoop也指定了参数 --fields-terminated-by和 --lines-terminated-by来自定义行分隔符和列分隔符。 
可是当你真的这么做时 坑爹呀! 
INFO hive.HiveImport: FAILED: SemanticException 1:381 LINES TERMINATED BY only supports newline ’\n’ right now.    也就是说虽然你通过--lines-terminated-by指定了其他的字符作为行分隔符,但是hive只支持\n作为行分隔符。
 

ORACLE中查询某个字段包含 回车 换行 符,||不是或,是 oracle 中的字符串连接符。%是通配符,代表任意字符串。 
  查看是否包含 回车换行 符,即:\r\n 
  select * from system.test_tab1 where name like '%'||chr(13)||chr(10)||'%' 
  单独查看是否包含 回车换行 符,即:\r 
  select * from system.test_tab1 where name like '%'||chr(13)||'%' 
  单独查看是否包含 换行 符,即:\n 
  select * from system.test_tab1 where name like '%'||chr(10)||'%'
 

解决方法:简单的解决办法就是加上参数--hive-drop-import-delims来把导入数据中包含的hive默认的分隔符去掉。这个最简单,如果确定数据中不该含有这些字符的话,或者确定去掉没影响的话,可以用这个。另外,使用这个就没法使用 --direct 选项了。

sqoop增量导入hive

问题1:导入后每一行所有数据都在第一个字段里? 
原因和解决:因为直接导入 HDFS 中 HIve 里的文件夹下的话,sqoop 默认给的 值分隔符 是逗号 ,,而 Hive 默认值分割符是\001,即:^A,所以 Hive 是不认的,所以 需要 把值分隔符改成 ^A,即加上下边的配置:

--fields-terminated-by \001

定义 sqoop job 增量导入

用 sqoop job 做增量更新,它会在它的 metastore 中管理 --last-value,很方便。

step 1 创建sqoop job
a.配置sqoop metastore服务
修改sqoop/conf/sqoop-site.xml文件

相关属性:

sqoop.metastore.server.location
sqoop.metastore.server.port
sqoop.metastore.client.autoconnect.url

<property>
 <name>sqoop.metastore.server.location</name>
 <value>/tmp/sqoop-metastore/shared.db</value>
</property>
<property>
 <name>sqoop.metastore.server.port</name>
 <value>16000</value>
</property>
<property>
  <name>sqoop.metastore.client.autoconnect.url</name>
 <value>jdbc:hsqldb:hsql://118.228.197.115:16000/sqoop</value>
</property>
<property>
  <name>sqoop.metastore.client.record.password</name>
  <value>true</value>
</property>
<!--注释掉这个属性
<property>
  <name>sqoop.metastore.client.enable.autoconnect</name>
  <value>false</value>
</property>
-->

b.启动metasotre,控制台执行sqoop metastore命令(如果没有配置前三个属性,请跳过此步骤)
c.创建sqoop job

(为了方便执行,将下面的脚本写入到文件保存,然后用chmod u+x FILENAME修改权限后,通过 ./FILENAME执行文件,创建job)

sqoop job --meta-connect jdbc:hsqldb:hsql://hostIP:16000/sqoop --create JOBNAME -- import --hive-import --incremental append --connect jdbc:oracle:thin:@DatabaseIP:1521/INSTANCENAME --username USERNAME --password PASSWD --verbose -m 1 --bindir /opt/sqoop/lib --table TABLENAME --check-column COLUMNNAME --last-value VALUE

注意:

1) 如果前面没有配置共享metastore(即”sqoop.metastore.server.location" 、”sqoop.metastore.server.port“、”sqoop.metastore.client.autoconnect.url“三个属性在配置文件中已经注释了),那就需要将上面的脚本中 ”--meta-connect jdbc:hsqldb:hsql://hostIP:16000/sqoop“ 去掉。

2) "--create JOBNAME -- import"中”--“后面加一个空格再写import命令,否则执行出错
3) --check-column列不能是char varchar等,可以是date,int,

step 2 执行sqoop job看是否可以顺利进行

<!--查看job列表,看是否成功创建-->

sqoop job --list

<!--执行job,测试能否正常执行,此处如果导入的数据量大,会很耗费时间-->

sqoop job --exec JOBNAME

step 3 确定sqoop job可以正常执行后,编写脚本定时执行

将下面的脚本写入一个文本文件,如 execJob,然后执行 chmod u+x execJob 命令添加可执行权限

source /etc/profile

rm TABLENAME.

java -f sqoop

job -exec JOBNAME

通过where 子句进行导入

sqoop import \ 
--connect jdbc:mysql://109.123.121.104:3306/testdb \ 
--username root \ 
--password 123456 \ 
--table user \ 
--where 'id > 5 and account like "f%"' \ 
--target-dir /sqoop/import/user_where \ 
--delete-target-dir \ 
--fields-terminated-by '\t' \ 
-m 1 \ 
--direct

table_name='WORK_DEVSTATETIME'
work_date='2018-05-14'
hive_database='test'

sqoop import --connect jdbc:oracle:thin:@10.60.127.64:1521:ORCL \
--username hhggk \
--password oracle \
--table ${table_name} \
--where "workdate= '${work_date}'" \
--fields-terminated-by "\t" \
--lines-terminated-by "\n" \
--delete-target-dir \
--hive-import \
--hive-database ${hive_database} \
--hive-overwrite \
--null-string '\\N' \
--null-non-string '\\N' \
-m 1 \
--direct \
--hive-drop-import-delims

这里 --direct 和 --hive-drop-import-delims参数不能同时出现,前一个参数可以增加导入的速度,后一个参数可以解决我们表中

有空格的问题,导致导入hive中行数增多

 


 

猜你喜欢

转载自blog.csdn.net/mn_kw/article/details/90602320