Sqoop

  Sqoop这个工具是做数据迁移用的,是关系型数据库和Hive/Hadoop的数据迁移,方便大量数据的导入导出工作。Sqoop底层是通过MapReduce去实现的,但只有Map没有Reduce。Sqoop版本分成1/2,Sqoop1版本从1.4.1版本开始,Sqoop1版本从1.99.1版本开始。使用Sqoop1,版本:sqoop-1.4.6-cdh5.7.0

一、解压和环境变量设置

  和之前的大数据工具一样,解压,配置环境

1、解压
tar -zxvf sqoop-1.4.6-cdh5.7.0.tar.gz -C ../app/
2、解压的文件所属者更改
chown -R hadoop:hadoop sqoop-1.4.6-cdh5.7.0
3、设置环境变量
vim ~/.bash_profile
4、添加
#Sqoop
export SQOOP_HOME=/home/hadoop/app/sqoop-1.4.6-cdh5.7.0
export PATH=$SQOOP_HOME/bin:$PATH
5、生效
source ~/.bash_profile
6、检测
$SQOOP_HOME

二、配置

  和其他的大数据工具一样,sqoop的配置也是在$SQOOP_HOME/conf/中。

2.1 环境文件的配置

  编辑sqoop-env.sh,配置hadoop、hive环境。

1、拷贝一个sqoop-env.sh文件
cp sqoop-env-template.sh sqoop-env.sh
2、配置Hadoop的环境
export HADOOP_COMMON_HOME=/home/hadoop/app/hadoop-2.6.0-cdh5.7.0
3、配置MapReduce的环境
export HADOOP_MAPRED_HOME=/home/hadoop/app/hadoop-2.6.0-cdh5.7.0
4、配置Hive的环境
export HIVE_HOME=/home/hadoop/app/hive-1.1.0-cdh5.7.0
2.2 MySQL环境驱动配置

  拷贝MySQL的驱动到$SQOOP_HOME/lib下。还要导入java解析json包到lib中

cp mysql-connector-java-5.1.46-bin.jar $SQOOP_HOME/lib/
cp java-json.jar $SQOOP_HOME/lib/

三、测试一下

  这样Sqoop大致就装好了,测下能否运行。

1、查看sqoop有哪些命令
sqoop help 
2、查看版本
sqoop version
3、查看不懂的命令
sqoop help xxx

四、连接MySQL数据库

  通过sqoop help知道,有一个命令叫做list-databases,这个命令是列出所有可用的数据库。怎么用?使用sqoop help list-databases,可以知道有一些常用的参数需要设置。

sqoop list-databases \
--connect jdbc:mysql://hadoop001:3306 \
--username root \
--password root

五、导入数据

  导入数据,是把表从关系型数据库到Hadoop中。这个命令就是sqoop import。如果对于命令不懂可以使用sqoop help import

5.1 先创造一点数据

  现在有一个任务将MySQL中的数据导入到Hive中。从MySQL中的mysqoopdata中的emp表导到HDFS中。

在mysql的命令行中,输入
source /tmp/emp.sql
这样就导入了emp表和dept表
5.2 导入语句
sqoop import \
--connect jdbc:mysql://hadoop001:3306/mysqoopdata \
--username root --password root \
--table emp -m 2 \
--mapreduce-job-name FromMySQLToHDFS \
--delete-target-dir \
--columns "EMPNO,ENAME,JOB,SAL,COMM" \
--target-dir EMP_COLUMN_WHERE \
--fields-terminated-by '\t' \
--null-string '' --null-non-string '0' \
--where 'SAL>2000'
5.3 流程

  测试的时候会发现,如果你不加MapReduce job(mapreduce-job-name)名称,默认是要导入的表的名称加上.job,就是“emp.job”,运行的时候默认采用4个MapTask做运算(指定需要使用 -m),并且获取emp表的主建最大值和最小值,均等划分主键在MapTask任务上,最终产生4个文件。默认输出的路劲就是HDFS:/user/${user}/emp 下。
  上诉输出在HDFS:/user/hadoop/EMP_COLUMN_WHERE/ 下,生成2个文件。只导入EMPNO,ENAME,JOB,SAL,COMM 字段,数据字段用’\t’分隔,导入条件SAL>2000。 如果字段是String类型的Null,替换成‘’,如果是非String的空,替换成‘0’。

5.4 指定使用查询

  上诉的例子,使用的–table和–columns来指定需要导入那张表和表中哪些字段,有一个问题,要是我要导入的是一个查询的结果,怎么办。

--query "SELECT * FROM emp WHERE EMPNO>=7566 AND  \$CONDITIONS" \
--split-by 'EMPNO' 

  使用–query做查询,–query和–table不能同时使用。–split-by 是用来做MapTask切分,在原先–table中,可以获取到主键,现在只能指定切分字段。“AND $CONDITIONS”这个语句,如果用双引号,$是要转义,单引号$不需要转义。CONDITIONS这个和并行化计算有关,记住一定要带上就行了。

5.4 脚本执行

  使用一堆的参数在shell中书写十分不方便。sqoop可以运行脚本吗,可以。

将运行参数写到一个脚本文件中,如 emp.opt
vim emp.opt
将参数写入到这个文件,如
import
--connect
jdbc:mysql://hadoop001:3306/mysqoopdata
--username
root
--password
root
--table
emp
注意,一个命令一行,前后不能有空格。
按照如下方式执行就可以了,和原来的一样。
sqoop --options-file emp.opt

六、导出数据

  导入是指Hadoop上的数据导出到MySQL上,导出的时候要注意,MySQL中表如果不存在则不会成功,所以先要创建好表然后再导出。

sqoop export \
--connect jdbc:mysql://hadoop001:3306/mysqoopdata \
--username root --password root \
-m 2 \
--mapreduce-job-name FromHDFSToMySQL \
--table emp_demo \
--export-dir /user/hadoop/emp \
--input-fields-terminated-by '\t' \
--input-null-string '' \
--input-null-non-string '0'

七、导入Hive中

  导入Hive也是与之前一样,使用的是sqoop import,只需要增加Hive的参数。

sqoop import \
--connect jdbc:mysql://hadoop001:3306/mysqoopdata \
--username root --password 123456 \
--table emp -m 2 \
--mapreduce-job-name FromMySQLToHive \
--delete-target-dir \
--hive-database database_test \
--hive-table emp \
--hive-import \
--fields-terminated-by '\t' \
--hive-overwrite \
--create-hive-table

  这个时候运行会有一个问题,报错:Could not load org.apache.hadoop.hive.conf.HiveConf,这个因为运行的时候需要用到Hive的一些jar包,所以两种解决方式,一个是将${HIVE_HOME}/lib/*.jar复制到当前${SQOOP_HOME}\lib下,第二种,使用全局变量,让Sqoop知道jar包在哪:

vi ~/.bash_profile
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HIVE_HOME/lib/*
source ~/.bash_profile

  报错:[Error 10072]: Database does not exist,将${HIVE_HOME}/conf/hive-site.xml到${SQOOP_HOME}\conf下。
  虽然有–create-hive-table参数,在没有创建Hive表的情况下可以创建,但还是建议不要使用,为什么,因为sqoop在创建表的时候,可能会把类型弄错,如下的SAL薪水,明显不能用整数型。

empno                   int                                         
ename                   string                                      
job                     string                                      
mgr                     int                                         
hiredate                string                                      
sal                     int                                         
comm                    int                                         
deptno                  int     

  为什么导入到Hive中的时候要指定这个参数–delete-target-dir ,因为数据会先加载到HDFS上然后在导入到Hive中。
  MySQL导入hive分区表中,也是建议先创建Hive中的。

create table emp_partition 
(empno int, ename string, job string, mgr int, hiredate string, sal double, comm double, deptno int)
partitioned by (pt string)
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY '\t'

  sqoop导入语句。

sqoop import \
--connect jdbc:mysql://hadoop001:3306/mysqoopdata \
--username root --password root \
--table emp -m 2 \
--mapreduce-job-name FromMySQLToHive \
--delete-target-dir \
--hive-database database_test \
--hive-table emp_partition \
--hive-import \
--hive-partition-key 'pt' \
--hive-partition-value '2018-08-08' \
--fields-terminated-by '\t' --hive-overwrite 

  sqoop导入有一个问题啊,不能自动分区,必须指明分区值….

八、Hive导出到MySQL

  Hive导出到MySQL。其实就是HDFS到mysql

sqoop export \
--connect jdbc:mysql://hadoop001:3306/mysqoopdata \
--username root --password root \
-m 2 \
--mapreduce-job-name FromHDFSToMySQL \
--table emp_demo \
--export-dir /user/hive/warehouse/database_test.db/emp_partition/pt=2018-08-08 \
--input-fields-terminated-by '\t' \
--input-null-string '\\N' 

九、sqoop job

  每次执行一堆参数真的会比较麻烦,可以使用shell脚本,可以使用job来简化。sqoop help job查看使用方法。

1、创建一个job,该job作用是将Mysql数据导入到HDFS
sqoop job --create myjob -- \
import \
--connect jdbc:mysql://hadoop001:3306/mysqoopdata \
--username root --password root \
--table emp -m 2 \
--mapreduce-job-name FromMySQLToHDFS \
--delete-target-dir \
--target-dir EMP_COLUMN_WHERE \
--fields-terminated-by '\t' \
--null-string '' --null-non-string '0' \

  这样的job就存储在sqoop中,可以使用定时运行脚本工具 crontab ,运行脚本内容sqoop job – exec myjob,这样可以定时运行任务。
  有一点需要注意下,运行Job的时候是需要手工输入密码,对于–password root这个参数好像没什么用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值