Sqoop从Oracle导入表到Hive

        最近甲方项目希望建立大数据平台,需要将保存在Oracle中的表和记录全部导入到大数据平台中。原计划是将表导入到HBase中,作为Hive外部表,但甲方对如何使用还没有明确想法,HBase行键不好设计,但甲方又急于将数据导入试用。于是决定先将数据导入到Hive中,方便他们做统计分析试验。调研一番后,决定采用Sqoop。现将使用过程总结如下。

一、软件版本

1、Oracle
Linux Oracle 11g r2 x86_64
2、Hive
Hive 1.1.0+cdh5.4.3+151
3、Sqoop
Sqoop 1.4.5+cdh5.4.3+100

注:这里使用的是Cloudera管理平台,Sqoop的安装不再介绍,感兴趣的可以查看下网络资料。

二、导入表描述

        Oracle中的表主要来自三个库,总共有大概600多个。其中,一个库中有400多张表,表有主键外键,表中记录较少,不超过万条;另外两张表,没有主键或主键仅为递增id,表中记录较多,最多的可能有几千万条。表中字段的类型有Number、Date、Float、Integer、Varchar、Char等,没有大字段类型。

三、导入过程

        由于待导入表数量较多,写sqoop命令以及等待执行的时间太长。于是就写代码创建了一个简单的shell脚本,将需要执行导入的sqoop命令全写入shell文件。生成导入脚本主要有两个步骤:
        1)生成待导入的表名,保存在文件中。使用“select table_name from dba_tables where Owner=user”语句将用户表筛选出来,保存在文本里,然后人工检查,剔除不需要的表。
        2)准备好oracle连接参数,读取文件,逐个生成sqoop命令,默认hive表名与oracle一致。
#!/bin/bash
sqoop import --hive-import --connect jdbc:oracle:thin:@192.168.55.5:1521:orcl --username XXX --password xxx --table SRC_TABLE --hive-database db --hive-table DEST_TABLE -m 2
...
sqoop import --hive-import --connect jdbc:oracle:thin:@192.168.55.5:1521:orcl --username YYY --password xxx --table SRC_TABLE-N --hive-database db --hive-table DEST_TABLE-N -m 2
echo "database xxx OK!"
         脚本创建好后,在终端上执行该脚本,等待执行结果即可。

四、问题

       1、Sqoop依赖
      导入关系型数据库时需要驱动,CDH5.4.3中自带了mysql的,oracle的驱动需要从官网上下载,放在sqoop/lib下。
 
       2、用户名表名大写问题
      网上说,sqoop命令中,用户名以及表名需要大写,否则会导入失败。但在该版本中试验发现,用户名小写无所谓,但表名需大小,否则出现找不到列错误。

       3、"user does not belong to hive"警告
      导入结束后,可能出现上述警告。这是因为CDH在hdfs中为hive建立了一个/user/hive目录,用户和组都是hive。当你在终端用其它用户(比如root)执行sqoop命令时,会在/user/hive/warehouse下创建一个以目标表名命名的目录,所属用户为root用户,而不是hive。为避免此警告,可在执行sqoop命令时指定用户。
sudo -u hive sqoop import....

       4、通过分区增加列
       用户数据是训练数据,每次训练结果都需要导入到hive里,但需要区分记录是哪次训练的,而原表中没有关于训练ID的字段。出于方便,我们与甲方设计了训练标识作为hive分区执行sqoop命令,在hive表中将会增加一列作为训练标识。在hdfs中,每个分区是一个单独的文件夹。
sqoop import --hive-import --connect jdbc:oracle:thin:@192.168.55.5:1521:orcl --username XXX --password xxx --table SRC_TABLE --hive-database db --hive-table DEST_TABLE -m 2 --hive-partition-key practiceid --hive-partition-value 00001
       
       5、增量导入的误解
       sqoop命令有--incremental参数可以做增量导入,可以根据指定列的某个值或者最后修改时间,将表中新插入的记录导入到目标表。我开始以为可以利用增量导入的方式将各场训练的数据逐个导入到hive中。后来才发现理解错了sqoop增量导入的含义,sqoop的增量导入针对的是同一张表,而用户那里不同训练的数据保存在不同的库中,不能采用这种方式。

       6、sqoop日志在哪?
        脚本执行过程中,发现个别表导入报异常,由于刷新比较快也没来得及看,查找日志时却悲催地发现找不到sqoop命令的日志,只能导完查看哪些表没有再单独导入试试了。解决方法:改写下脚本文件,增加参数,允许将命令执行信息重定向到指定文件。

五、后续

        导入完成后,经查看发现,有部分表导入出错。在尝试重新导入时发现以下问题。
1、import出错,会创建临时目录
       Sqoop的import命令出错,可能会在hdfs的“/user/用户名”下创建以表名命名的目录,重新导入时必须将该目录删掉才可以。
2、-m 缺省值为4
       在单独导入出错表时,发现之前的错误是由于-m的参数被误写为-1导致。Sqoop的输出信息显示:“WARN mapreduce.JobBase: Invalid mapper count; using 4 mappers”,应该是-m参数不支持负值,默认按4个处理,切分任务时建议以整型字段切分。
3、Oracle字段名最好大写
       使用Navicat建了张表测试,包含两个字段,类型都为VARCHAR2,字段名小写输入,表中只插入了一条记录。执行Sqoop import命令后,报"ORA-00904: "INFO": invalid identifier“错误。在网上查找资料后发现,oracle词典中默认为大写,如果字段为小写必须加上双引号才能区分,而Sqoop只认大写,没办法。
4、哪种类型的表在做切分时会出错,原因暂时还没找到
       导入出错的表,在将-m 改为1后可以导入成功。但从甲方回来后想复现错误时,发现没有成功。记得出错的几张表共有特点是没有记录或记录数很少,字段比较少,没有主键或主键为VARCHAR2类型。复现时,创建了一张包含两个字段的表,字段类型都为VARCHAR2,只有一条记录,发现导入没有问题。只能等下次去时再解决了。

你可能感兴趣的:(oracle,sqoop)