Sqoop介绍
Sqoop是一个用来将Hadoop和关系型数据库中的数据相互转移的工具,可以使用Sqoop将数据从MySQL或Oracle等关系数据库管理系统(RDBMS)导入Hadoop分布式文件系统(HDFS),在Hadoop MapReduce中转换数据,然后将数据导出回RDBMS,在不使用ETL工具情况下使用sqoop是迁移数据的一个方案。
官方文档:http://sqoop.apache.org/docs/1.4.5/SqoopUserGuide.html
sqoop的数据导入
语法:sqoop import (generic-args) (import-args)
常用参数
-connect jdbc 连接地址
--connection-manager 连接管理者
--driver 驱动类
--hadoop-mapred-home $HADOOP_MAPRED_HOME
--help help 信息
-P 从命令行输入密码
-m 指定maptask的个数,指定maptask的并行度
--target-dir 指定导出数据在hdfs上的存储目录
--fields-terminated-by 指定每条记录中字段之间的分隔符
--where 指定查询sql的where条件
--query 指定sql查询
--columns 指定查询的列 (不指定默认导出所有的列)
--password 密码
MySQL ---> HDFS
- 不指定分隔符和路径
sqoop import \
--connect jdbc:mysql://hadoop01:3306/test \ #指定连接
--username hadoop \ #指定MySQL的用户名
-password root \ #指定MySQL的密码
--table book \ #指定导出的MySQL的表
-m 1 #启动一个maptask
###如果没有指定文件的存储目录,那么默认的会保存在hdfs上的/user/用户/book 目录中,默认的字段分隔符是逗号。
- 指定导入路径和分割符
sqoop import \
--connect jdbc:mysql://hadoop01:3306/test \
--username hadoop \
--password root \
--table book \
--target-dir /user/hadoop/book \ #指定导出的HDFS目录
--fields-terminated-by '\t' \ #指定分隔符
-m 1
- 导入where的结果
sqoop import \
--connect jdbc:mysql://hadoop01:3306/test \
--username hadoop \
--password root \
--where "bid>2" \ #where筛选条件
--table book \
--target-dir /user/hadoop/book1 \
-m 1
###ps:where后的条件,用双引号,如果条件的字段为string则里面使用单引号
- 导入query结果数据
sqoop import \
--connect jdbc:mysql://hadoop01:3306/test \
--username hadoop \
--password root \
--target-dir /user/hadoop/book3 \
--query 'select * from book where 1=1 and $CONDITIONS' \
--split-by bid \ #指定maptask切分的列,列的值.hashcode/maptask的个数
--fields-terminated-by '\t' \
-m 1
ps:
1.query外层使用单引号,SQL 语句当中的条件使用双引号,否则会报错;
2.在使用query时,必须有where子句,并且必须加入 and $CONDITIONS ,否则会报错
3.--query不能和--where、--columns一起使用的
4.--query sql语句使用双引号,则SQL中$CONDITIONS需要加转义,例如--query 'select * from book where 1=1 and \$CONDITIONS'
MySQL ---> hive
Sqoop导入关系型数据到hive,的过程是先导入hdfs中,然后在load到hive。
- 普通导入
sqoop import \
--connect jdbc:mysql://hadoop01:3306/test \
--username hadoop \
--password root \
--table book \
--hive-import \
-m 1
ps:导入数据到hive表中时,默认在default库下,表名和MySQL导入的表名一样。,默认采用'\u0001'分隔。
- 指定hive库
sqoop import \
--connect jdbc:mysql://hadoop01:3306/test \
--username hadoop \
--password root \
--table book \
--fields-terminated-by '\t' \ #列分割符
--lines-terminated-by '\n' \ #行分隔符 ,默认也是\n
--hive-import \
--hive-overwrite \ #覆盖导入
--create-hive-table \ #创建表,如果表已存在则任务失败
--hive-table test.book \ #导入hive数据的表名
--delete-target-dir #删除中间存放的临时目录
ps:表会自动创建,但是库不会,所以在执行语句前,一定要保证hive的数据库存在,否则会把报错。
MySQL ---> hbase
sqoop import \
--connect jdbc:mysql://hadoop02:3306/mysql \
--username root \
--password root \
--table help_keyword \
--hbase-create-table \
--hbase-table new_help_keyword \
--column-family person \
--hbase-row-key help_keyword_id
#字段解释
--table help_keyword 表示导出 mysql 数据库的 help_keyword 表。
--hbase-create-table 表示在 HBase 中建立表。
--hbase-table new_help_keyword 表示在 HBase 中建立表 new_help_keyword。
--hbase-row-key help_keyword_id 表示hbase表的rowkey是mysql表的help_keyword_id字段。
--column-family person 表示在表 new_help_keyword 中建立列族 person。
可创建选项文件调用
当sqoop命令较长或者需要多次重复调用时,可以创建一个包含sqoop 命令的文件,使用--options-file参数将其传递到命令行。
例如:sqoop import --connect jdbc:mysql:// localhost / db --username foo --table TEST
编辑/users/homer/work/import.txt文件内容为:
Import
#连接参数和值,此行为注释
--connect
jdbc:mysql://localhost/db
--username
foo
那么sqoop --options-file /users/homer/work/import.txt --table TEST等同于上述命令。
Sqoop的数据导出
Sqoop将一个传输作业生成一个mapreduce job,一个job有多个并行执行传输作业的mapreduce task在和外部数据库做数据传输,如果由于数据库连接丢失、违反数据库约束、硬件问题等原因导致个别task失败,进而会导致整个传输job失败。会产生脏数据问题,在某些情况下,这可能导致后续作业因插入冲突而失败。
Sqoop Export任务则提供了一个“中间表”的解决办法,先将数据写入到中间表,写入中间表成功,再将中间表数据写入目标表。
例如:
sqoop export --connect jdbc:mysql://127.0.0.1/test --table employee --staging-table employee_tmp --clear-staging-table -username root -password 123456 --export-dir hdfs://localhost:9000/user/hive/warehouse/employee
注意:创建的临时表结构上和目标表需要一致。
在与ORACLE连接时,用户名和表名需要大写,因为它们是默认大写形式存在数据库中的。
参考文章:
https://blog.51cto.com/14048416/2343853?source=dra