一、sqoop介绍
Sqoop是一个用于在Hadoop和关系数据库之间传输数据的工具
- 将数据从RDBMS导入到HDFS
- HDFS、Hive、HBase
- 从HDFS导出数据到RDBMS
- 使用MapReduce导入和导出数据,提供并行操作和容错
二、数据迁移介绍
使用帮助文档
sqoop import --help
可以查到所有的迁移语句
图为部分:
案例演示
数据准备
下载数据准备
链接:数据
提取码:jmg7
在mysql中创建数据库并导入准备的数据
mysql> create database retail_db;
mysql> use retail_db;
mysql> source /root/data/sqoop/retail_db.sql
mysql> show tables;
效果如下:
将数据从MySQL中导入到HDFS上
sqoop import \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--table customers \
--username root \
--password root \
--target-dir /datas/retail_db/customers \
--m 3
注释:
- 每一行的最后是换行符 \,可以写成一行就不需要了。
- 第1行是固定写法,必须要且不能改。
- 第2~3行是连接数据库
- 第4行是指定需要倒数数据库中的哪一张表
- 第5~6行是mysql的用户名和密码
- 第7行是指定传入到hdfs中的指定目录
- 第8行 表示启动多少个map。
报错及解决:
# 报错
Exception in thread "main" java.lang.NoClassDefFoundError: org/json/JSONObject
at org.apache.sqoop.util.SqoopJsonUtil.getJsonStringforMap(SqoopJsonUtil.java:43)
at org.apache.sqoop.SqoopOptions.writeProperties(SqoopOptions.java:784)
at org.apache.sqoop.mapreduce.JobBase.putSqoopOptionsToConfiguration(JobBase.java:392)
at org.apache.sqoop.mapreduce.JobBase.createJob(JobBase.java:378)
at org.apache.sqoop.mapreduce.ImportJobBase.runImport(ImportJobBase.java:256)
at org.apache.sqoop.manager.SqlManager.importTable(SqlManager.java:692)
at org.apache.sqoop.tool.ImportTool.importTable(ImportTool.java:513)
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.json.JSONObject
解决:
拷贝jar包
cp /opt/software/java-json.jar /opt/soft/sqoop-1.4.6-cdh5.14.2/lib/
这步也可以在安装sqoop的时候就做好。
通过Where语句过滤导入表
sqoop import \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--table orders \
--where "order_date > '2015-10-10'" \
--username root \
--password root \
--delete-target-dir \
--target-dir /datas/retail_db/orders \
--m 3
注释:
- 第5行是where语句的过滤,只迁移符合条件的数据
- 第8行是如果hdfs上存在目标目录,会选择删除,然后再去创建空目录,迁移数据。
通过COLUMNS过滤导入表
sqoop import \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--table customers \
--columns "customer_id,customer_fname,customer_lname" \
--username root \
--password root \
--delete-target-dir \
--target-dir /data/retail_db/customers \
--m 3
注释:
- 第5行指定传输第四行指定表中的相应的列。
使用查询语句进行过滤
sqoop import \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--query "select * from orders where order_id < 30 and \$CONDITIONS" \
--username root \
--password ok \
--split-by order_id \
--delete-target-dir \
--target-dir /datas/orders \
--m 3
注释:
- 第4行使用sql语句查询需要的数据,进行导入
- 第7行用于分割出sql语句查询的结果数据
使用Sqoop增量导入数据
- Incremental指定增量导入的模式
- append:追加数据记录
- lastmodified:可追加更新的数据
sqoop import \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--table orders \
--username root \
--password ok \
--incremental append \
--check-column order_date \
--last-value '2015-10-10' \
--target-dir /dataes/orders \
--m 3
创建job
sqoop job --create mysql2hdfs \
-- import \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--table orders \
--username root \
--password ok \
--incremental append \
--check-column order_date \
--last-value '0' \
--target-dir /data/retail_db/orders \
--m 3
查看job
sqoop job --list
执行job
sqoop job --exec mysql2hdfs
删除job
sqoop job --delete mysql2hdfs
显示job详细信息
sqoop job --show mysql2hdfs
可以设置每天定时执行job
crontab -e
* 2 */1 * * sqoop job --exec mysql2hdfs
导入数据到Hive中
先在Hive中创建数据库
hive -e "create database if not exists retail_db;"
这是在hive外部创表,也可以进入hive创建数据库
将mysql数据导入hive
sqoop import \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--table orders \
--username root \
--password root \
--hive-import \
--create-hive-table \
--hive-database retail_db \
--hive-table orders \
--m 3
注释:
- 第7行是要导入hive所要写的语句
- 第8行是在hive中创建表,如果表已存在则会报错
- 第9行是指向hive中相应的数据库
- 第10行是指向对应的表
如果报错为
20/07/15 22:26:56 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-common-1.1.0-cdh5.14.2.jar,所以从Hive的lib中进行拷贝
cp /opt/soft/hive110/lib/hive-common-1.1.0-cdh5.14.2.jar /opt/soft/sqoop-1.4.6-cdh5.14.2/lib/
缺少jar包,需要从Hive中进行拷贝
cp /opt/soft/hive110/lib/hive-shims* /opt/soft/sqoop-1.4.6-cdh5.14.2/lib/
导入数据到Hive分区中
删除Hive表
drop table if exists orders;
向hive中导入数据
sqoop import \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--query "select order_id,order_status from orders where order_date>='2013-11-03' and order_date <'2013-11-04' and \$CONDITIONS" \
--username root \
--password root \
--delete-target-dir \
--target-dir /data/retail_db/orders \
--split-by order_id \
--hive-import \
--hive-database retail_db \
--hive-table orders \
--hive-partition-key "order_date" \
--hive-partition-value "2013-11-03" \
--m 3
注意:分区字段不能当成普通字段导入表中
导入数据到HBase中
1.在HBase中建表
create 'products','data','category'
2.sqoop导入
sqoop import \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--username root \
--password root \
--table products \
--hbase-table products \
--column-family data \
--m 3
HDFS 向MySQL中导出数据
1.MySQL中建表
create table customers_demo as select * from customers where 1=2;
2.上传数据
hdfs dfs -mkdir /customerinput
hdfs dfs -put customers.csv /customerinput
3.导出数据
sqoop export \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--username root \
--password root \
--table customers_demo \
--export-dir /customerinput \
--m 1
sqoop 脚本
1.编写脚本 job_RDBMS2HDFS.opt
import
--connect
jdbc:mysql://localhost:3306/retail_db
--driver
com.mysql.jdbc.Driver
--table
customers
--username
root
--password
root
--target-dir
/data/retail_db/customers
--delete-target-dir
--m
3
注释:脚本中没写一个是需要回撤的,并且不需要加回车符
2.执行脚本
sqoop --options-file job_RDBMS2HDFS.opt