1. Sqoop 概述
Sqoop是Hadoop和关系数据库服务器之间传送数据的一种工具。它是用来从关系数据库如:MySQL,Oracle到Hadoop的HDFS,并从Hadoop的文件系统导出数据到关系数据库。传统的应用管理系统,也就是与关系型数据库的使用RDBMS应用程序的交互,是产生大数据的来源之一。
当大数据存储器和分析器,如MapReduce, Hive, HBase, Cassandra, Pig等,Hadoop的生态系统等应运而生图片,它们需要一个工具来用的导入和导出的大数据驻留在其中的关系型数据库服务器进行交互。在这里,Sqoop占据着Hadoop生态系统提供关系数据库服务器和Hadoop HDFS之间的可行的互动。
Sqoop:“SQL 到 Hadoop 和 Hadoop 到SQL”,Sqoop是Hadoop和关系数据库服务器之间传送数据的一种工具。它是用来从关系数据库如MySQL,Oracle到Hadoop的HDFS从Hadoop文件系统导出数据到关系数据库。它是由Apache软件基金会提供。
2. Sqoop安装与部署
1)、下载tar包:Sqoop下载,上传至服务器并解压;
2)、配置Sqoop环境变量:
vim ~/.bash_profile
添加:
export SQOOP_HOME=/usr/sqoop-1.4.6.bin
PATH=$PATH:$SQOOP_HOME/bin
重新加载配置文件:
source ~/.bash_profile
3)、添加数据库连接驱动包:
cp mysql-connector-java-5.1.10.jar $SQOOP_HOME/lib
4)、$SQOOP_HOME/conf/目录下重命名文件:
mv sqoop-env-template.sh sqoop-env.sh
5)、修改$SQOOP_HOME/bin/configure-sqoop:
注释掉HCatalog,Accumulo检查(除非你准备使用HCatalog,Accumulo等HADOOP上的组件)
## Moved to be a runtime check in sqoop.
#if [ ! -d "${HCAT_HOME}" ]; then
# echo "Warning: $HCAT_HOME does not exist! HCatalog jobs willfail."
# echo 'Please set $HCAT_HOME to the root of your HCatalog installation.'
#fi
#if [ ! -d "${ACCUMULO_HOME}" ];then
# echo "Warning: $ACCUMULO_HOME does not exist! Accumulo imports willfail.“
# echo 'Please set $ACCUMULO_HOME to the root of your Accumuloinstallation.'
#fi
6)、测试
sqoop version
:
[[email protected] ~]# sqoop version
19/01/15 22:10:08 INFO sqoop.Sqoop: Running Sqoop version: 1.4.6
Sqoop 1.4.6
git commit id c0c5a81723759fa575844a0a1eae8f510fa32c25
Compiled by root on Mon Apr 27 14:38:36 CST 2015
3. Sqoop 导入与导出
请提前开启Zookeeper集群、Hadoop集群、Yarn集群、HBase集群、mysql服务。
3.1 导入(import)参数
--append 将数据追加到HDFS上一个已存在的数据集上
--as-avrodatafile 将数据导入到Avro数据文件
--as-sequencefile 将数据导入到SequenceFile
--as-textfile 将数据导入到普通文本文件(默认)
--boundary-query <statement> 边界查询,用于创建分片(InputSplit)
--columns <col,col,col…> 从表中导出指定的一组列的数据
--delete-target-dir 如果指定目录存在,则先删除掉
--direct 使用直接导入模式(优化导入速度)
--direct-split-size <n> 分割输入stream的字节大小(在直接导入模式下)
--fetch-size <n> 从数据库中批量读取记录数
--inline-lob-limit <n> 设置内联的LOB对象的大小
-m,--num-mappers <n> 使用n个map任务并行导入数据
-e,--query <statement> 导入的查询语句
--split-by <column-name> 指定按照哪个列去分割数据
--table <table-name> 导入的源表表名
--target-dir <dir> 导入HDFS的目标路径
--warehouse-dir <dir> HDFS存放表的根路径
--where <where clause> 指定导出时所使用的查询条件
-z,--compress 启用压缩
--compression-codec <c> 指定Hadoop的codec方式(默认gzip)
--null-string <null-string> 如果指定列为字符串类型,使用指定字符串替换值为null的该类列的值
--null-non-string <null-string>如果指定列为非字符串类型,使用指定字符串替换值为null的该类列的值
--validate <class-name> 启用数据副本验证功能,仅支持单表拷贝,可以指定验证使用的实现类
--validation-threshold <class-name> 指定验证门限所使用的类
--direct 使用直接导出模式(优化速度)
3.2 导出(export)参数
--export-dir <dir> 导出过程中HDFS源路径
--m,--num-mappers <n> 使用n个map任务并行导出
--table <table-name> 导出的目的表名称
--call <stored-proc-name> 导出数据调用的指定存储过程名
--update-key <col-name> 更新参考的列名称,多个列名使用逗号分隔
--update-mode <mode> 指定更新策略,包括:updateonly(默认)、allowinsert
--input-null-string <null-string> 使用指定字符串,替换字符串类型值为null的列
--input-null-non-string <null-string> 使用指定字符串,替换非字符串类型值为null的列
--staging-table <staging-table-name> 在数据导出到数据库之前,数据临时存放的表名称
--clear-staging-table 清除工作区中临时存放的数据
--batch 使用批量模式导出
3.3 将MySQL中的数据导入到HDFS/Hive/Hbase
3.3.1 MySQL 到 HDFS
sqoop import --connect jdbc:mysql://node01:3306/test --username root --password 123456 --table tb_user -m1 -target-dir hdfs://fzp/sqoop/myuser
查看数据:
[[email protected] ~]# hdfs dfs -get /sqoop/myuser /
get: `/myuser/_SUCCESS': File exists
get: `/myuser/part-m-00000': File exists
[[email protected] ~]# cat /myuser/part-m-00000
1,zhangsan,19,男
2,李四,22,女
3,wangwu,33,男
3.3.1 MySQL 到 Hive
sqoop import --connect jdbc:mysql://node01:3306/test --username root --password 123456 --table tb_user --hive-import --hive-database mydb --hive-table myuser01 --create-hive-table --fields-terminated-by "," -m 1
注:由于使用Sqoop从MySQL导入数据到Hive需要指定target-dir,因此导入的是普通表而不能为外部表。
Hive参数:
--hive-import #必须参数,指定导入hive
--hive-database default #hive库名
--hive-table people #hive表名
--fields-terminated-by #hive的分隔符
--hive-overwrite #重写重复字段
--create-hive-table # ,但是表存在会出错。不建议使用这个参数,因为到导入的时候,会与我们的字段类型有出入。
--hive-partition-key “dt” #指定分区表的字段
--hive-partition-value “2018-08-08” #指定分区表的值
-m 1 : #设置只使用一个map进行数据迁移
查看数据:
hive> select * from myuser01;
OK
1 zhangsan 19 男
2 李四 22 女
3 wangwu 33 男
Time taken: 22.925 seconds, Fetched: 3 row(s)
3.3.1 MySQL 到 HBase
sqoop import --connect jdbc:mysql://node01:3306/test --username root --password 123456 --table tb_user --hbase-table myuser --column-family cf1 --hbase-row-key name --hbase-create-table -m 1
HBase参数:
--hbase-table #HBase表名
--hbase-create-table #帮创建好 HBase 表
--column-family cf1 #指定列族名
--hbase-row-key #指定rowkey对应mysql的键
查看数据:
hbase(main):008:0> scan 'myuser'
ROW COLUMN+CELL
wangwu column=cf1:age, timestamp=1547625803703, value=33
wangwu column=cf1:id, timestamp=1547625803703, value=3
wangwu column=cf1:sex, timestamp=1547625803703, value=\xE7\x94\xB7
zhangsan column=cf1:age, timestamp=1547625803703, value=19
zhangsan column=cf1:id, timestamp=1547625803703, value=1
zhangsan column=cf1:sex, timestamp=1547625803703, value=\xE7\x94\xB7
\xE6\x9D\x8E\xE5\x9B\x9B column=cf1:age, timestamp=1547625803703, value=22
\xE6\x9D\x8E\xE5\x9B\x9B column=cf1:id, timestamp=1547625803703, value=2
\xE6\x9D\x8E\xE5\x9B\x9B column=cf1:sex, timestamp=1547625803703, value=\xE5\xA5\xB3
3 row(s) in 0.1780 seconds
3.4 使用 Sqoop 将 HDFS/Hive/HBase 中的数据导出到MySQL
3.4.1 HDFS 到 MySQL
sqoop export --connect jdbc:mysql://node01:3306/test --username root --password 123456 --table tb_user --export-dir /sqoop/myuser
3.4.2 Hive 到 MySQL
sqoop export --connect jdbc:mysql://node01:3306/test --username root --password 123456 --table tb_user --export-dir /user/hive_1/warehouse/mydb.db/myuser01 --input-fields-terminated-by ',’
3.4.3 HBase 到 MySQL
目前sqoop没有办法把数据直接从Hbase导出到mysql。也可以通过Hive建立2个表,一个外部表是基于这个Hbase表的,另一个是单纯的基于hdfs的hive原生表,然后把外部表的数据导入到原生表(临时),然后通过hive将临时表里面的数据导出到mysql。