Sqoop 概述(SQL to Hadoop)
作用 :将数据从RDBMS 和Hadoop 之间进行导入导出,底层采用的是MapReduce实现
两大版本:
1.4.* Sqoop1
1.99.* Sqoop2
1 2 3 4 5 6 基于Hadoop作为参考点/基准点 导入: import RDBMS ==> Hadoop 导出: export Hadoop ==> RDBMS
Sqoop 的安装
下载 cdh5
wget http://archive.cloudera.com/cdh5/cdh/5/sqoop-1.4.6-cdh5.16.2.tar.gz
解压
tar -zxvf sqoop-1.4.6-cdh5.16.2.tar.gz -C ~/app/
配置系统环境变量
export SQOOP_HOME=/home/hadoop/app/sqoop-1.4.6-cdh5.16.2
export PATH=$SQOOP_HOME/bin:$PATH
source
配置文件:
$SQOOP_HOME/conf/
cp sqoop-env-template.sh sqoop-env.sh
export HADOOP_COMMON_HOME=/home/hadoop/app/hadoop-2.6.0-cdh5.16.2
export HADOOP_MAPRED_HOME=/home/hadoop/app/hadoop-2.6.0-cdh5.16.2
export HIVE_HOME=/home/hadoop/app/hive-1.1.0-cdh5.16.2
驱动包
cp mysql-connector-java-5.1.27-bin.jar $SQOOP_HOME/lib/
测试是否可用:
列出所有数据库
sqoop list-databases
–connect jdbc:mysql://bigdata01:3306
–password 123456
–username root
列出所有表
sqoop list-tables
–connect jdbc:mysql://bigdata01:3306/sqoop
–password 123456
–username root
RDBMS TO HDFS(Import)
全表导入
参数:
–table :指定被导入的表名
–target-dir:指定导入路径
–delete-target-dir:如果目标目录存在就删除它
–fields-terminated-by:指定字段分隔符
–columns :指定需要导入的列
-m:mapTask的个数
–fields-terminated-by :指定字段之间的分隔符
导入指定列
1 2 3 4 5 6 7 8 9 sqoop import \ --connect jdbc:mysql://bigdata01:3306/sqoop \ --password ruozedata --username root \ --table emp \ --columns "id,name" \ --target-dir /user/company \ --delete-target-dir \ --num-mappers 1 \ --fields-terminated-by "\t"
参数:
–columns :指定要导入的列多个列之间用逗号分隔
查询导入
1 2 3 4 5 6 7 8 9 sqoop import \ --connect jdbc:mysql://bigdata01:3306/sqoop \ --password ruozedata --username root \ --table emp \ --target-dir /user/company \ --delete-target-dir \ --num-mappers 1 \ --fields-terminated-by "\t" \ --query 'select id,name from student where id <=1 and $CONDITIONS;'
参数:
–query :指定查询SQL where条件要有$CONDITIONS
注意: must contain ‘$CONDITIONS’ in WHERE clause.
如果query后使用的是双引号,则$CONDITIONS前必须加转义符,防止shell识别为自己的变量。
筛选导入
1 2 3 4 5 6 7 8 9 sqoop import \ --connect jdbc:mysql://bigdata01:3306/sqoop \ --password ruozedata --username root \ --table emp \ --target-dir /user/company \ --delete-target-dir \ --num-mappers 1 \ --fields-terminated-by "\t" --where "id > 400"
增量导入数据
1 2 3 4 5 6 7 8 9 10 11 12 sqoop import \ --connect jdbc:mysql://bigdata01:3306/sqoop \ --password ruozedata --username root \ --table emp \ --target-dir /user/company \ --null-string "" \ --null-non-string "0" \ --check-column "id" \ --incremental append \ --fields-terminated-by '\t' \ --last-value 0 -m 1
参数:
–null-string:字符串为null怎么处理
–null-non-string:其他类型为null怎么处理
–check-column:根据哪一行做增量导入
–last-value:开始增量导入的上个位置
RDBMS To Hive(Import)
1 2 3 4 5 6 7 8 9 10 11 12 13 sqoop import \ --connect jdbc:mysql://bigdata01:3306/sqoop \ --password ruozedata --username root \ --table emp \ --hive-overwrite \ --delete-target-dir \ --null-string "" \ --null-non-string "0" \ --hive-import \ --hive-database default \ --hive-table staff \ --fields-terminated-by '\t' \ --num-mappers 1
参数:
–hive-import:数据从关系数据库中导入到hive表中
–hive-overwrite:覆盖掉在hive表中已经存在的数据
–hive-table:后面接hive表,默认使用MySQL的表名 如果导入的是分区表,需要指定分区的key和value
–hive-partition-key key \
–hive-partition-value value \
HDFS To RDBMS(Export)
先保证MySQL创建了一张和Hive一样表结构的表用来接收数据
注意表结构和分隔符都要一样
1 2 3 4 5 6 7 8 9 10 11 12 sqoop import \ -Dsqoop.export.records.per.statement=10 \ --connect jdbc:mysql://bigdata01:3306/sqoop \ --password ruozedata --username root \ --table emp \ --table staff \ --export -dir /user/company/ \ --null-string "" \ --null-non-string "0" \ --columns "id,name" \ --fields-terminated-by '\t' \ -m 1
参数:
–Dsqoop.export.records.per.statement:批量更新,每隔10条提交一次
–export-dir:导出的hdfs目录
–table:导入的表名
–columns:指定导入的列
注意:MySQL中表不存在会自动创建
Hive To RDBMS(Export)
1 2 3 4 5 6 7 sqoop import \ --connect jdbc:mysql://bigdata01:3306/sqoop \ --password ruozedata --username root \ --table emp \ --num-mappers 1 \ --export -dir /user/hive/warehouse/staff \ --input-fields-terminated-by "\t"
参数:
–export-dir:指定被导出的目录
–input-fields-terminated-by:导入的分隔符格式,和导入的fields-terminated-by有区别
Sqoop 导入导出一体化流程
Hive中创建表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 CREATE TABLE emp_etl(empno int , ename string , job string , mgr int , hiredate string , sal double , comm double , deptno int ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' ;CREATE TABLE dept_etl(deptno int , dname string , loc string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' ;
使用Sqoop将MySQL中的数据导入到Hive中
1 2 3 4 5 6 7 8 9 10 11 sqoop import \ --connect jdbc:mysql://bigdata01:3306/sqoop \ --password ruozedata \ --username root \ --table dept \ --hive-overwrite \ --delete-target-dir \ --hive-import --hive-database ruozedata_hive \ --hive-table dept_etl \ --fields-terminated-by '\t' \ -m 1
Hive中创建结果表
1 2 3 4 5 6 7 CREATE TABLE result_etl( empno int, ename string, deptno int, dname string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' ;
模拟分析过程
1 2 insert overwrite table result_etl select e.empno, e.ename, e.deptno, d.dname from emp_etl e join dept_etl d on e.deptno=d.deptno;
MySQL中创建结果表 etl_result
1 2 3 4 5 6 create table etl_result(empno int , ename varchar (10 ), deptno int , dname varchar (20 ) );
将结果表导出到MySQL
1 2 3 4 5 6 7 8 sqoop export \ -m 1
Shell 中操作数据库
1 2 3 4 mysql -uroot -pruozedata <<EOF use sqoop; truncate etl_result; EOF
部分问题总结
报错信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 19/12/26 11:29:41 ERROR tool.ImportTool: Import failed: java.io.IOException: java.lang.ClassNotFoundException: org.apache.hadoop.hive.conf.HiveConf at org.apache.sqoop.hive.HiveConfig.getHiveConf(HiveConfig.java:50) at org.apache.sqoop.hive.HiveImport.getHiveArgs(HiveImport.java:392) at org.apache.sqoop.hive.HiveImport.executeExternalHiveScript(HiveImport.java:379) at org.apache.sqoop.hive.HiveImport.executeScript(HiveImport.java:337) at org.apache.sqoop.hive.HiveImport.importTable(HiveImport.java:241) at org.apache.sqoop.tool.ImportTool.importTable(ImportTool.java:530) at org.apache.sqoop.tool.ImportTool.run(ImportTool.java:621) at org.apache.sqoop.Sqoop.run(Sqoop.java:147) at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70) at org.apache.sqoop.Sqoop.runSqoop(Sqoop.java:183) at org.apache.sqoop.Sqoop.runTool(Sqoop.java:234) at org.apache.sqoop.Sqoop.runTool(Sqoop.java:243) at org.apache.sqoop.Sqoop.main(Sqoop.java:252) Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.hive.conf.HiveConf
解决:将Hive中lib下面的hive* 的jar包拷贝到Sqoop的lib目录即可