百度网盘:sqoop-1.4.6-cdh5.14.2.tar.gz
java-json.jar
mysql-connector-java-5.1.27-bin.jar
一、什么是Sqoop
Sqoop是一个用于在Hadoop和关系数据库之间传输数据的工具
- 将数据从RDBMS导入到Hadoop (HDFS、Hive、HBase)
- 从Hadoop导出数据到RDBMS
- 将导入或导出命令翻译成MapReduce程序来并行操作和容错
二、sqoop安装教程
2.1下载并解压
2.1.1 解压sqoop安装包
我这边放到 opt 目录下
进入opt目录 cd /opt
解压安装包:tar -zxf sqoop-1.4.6-cdh5.14.2.tar.gz
2.1.2 更改目录名【非必须】
mv sqoop-1.4.6-cdh5.14.2.tar.gz sqoop
2.2配置环境变量
2.2.1进入profile文件:vi /etc/profile
2.2.2 配置环境变量
输入i
进入编辑模式
export SQOOP_HOME=/opt/sqoop
export PATH=$SQOOP_HOME/bin:$PATH
输入esc退出编辑模式,输入:x
保存退出
2.2.3使配置文件生效:source /etc/profile
2.3 修改sqoop配置文件
2.3.1 进入sqoop 根目录下的 conf 目录
cd /opt/sqoop/conf
2.3.2 拷贝并重命名配置文件
cp sqoop-env-template.sh sqoop-env.sh
2.3.3 修改配置文件 sqoop-env.sh
进入 sqoop-env.sh vi sqoop-env.sh
放开相关注释,进行配置
export HADOOP_COMMON_HOME=/opt/hadoop
export HADOOP_MAPRED_HOME=/opt/hadoop
export HBASE_HOME=/opt/hbase
export HIVE_HOME=/opt/hive
export ZOOKEEPER_HOME=/opt/zookeeper
export ZOOCFGDIR=/opt/zookeeper
保存退出
2.4 拷贝相关jar包
2.4.1 将以下两个jar包拖动到 sqoop 的 lib 目录
mysql-connector-java-5.1.27-bin.jar
java-json.jar
2.4.2 拷贝hive的相关jar包到sqoop的lib目录
cp /opt/hive/lib/hive-common-1.1.0-cdh5.14.2.jar /opt/sqoop/lib/
cp /opt/hive/lib/hive-shims* /opt/install/sqoop/lib/
2.5 验证sqoop
输入 sqoop help
出现以下界面为配置成功
三、sqoop导入导出语法
3.1 mysql 导入到 hdfs
3.1.1 使用sqoop将customers表导入到hdfs上
//--connect 配置数据库连接为MySQL中数据库
//--driver 驱动
//--table 表名
//--username mysql用户名
//--password mysql密码
//--target-dir 导入hdfs指定目录
//--m 表示Mapper数量
sqoop import \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--table orders \
--username root \
--password root \
--target-dir /data/retail_db/orders \
--m 3
举例说明:并行计算 --m 3
表导入相当于:select * from orders ;
如果没指定分割字段,会按照主键进行分割(如果没有主键必须指定分隔字段)
假设只有90条数据,会按主键(orders_id)进行平均分割
select * from orders where order>0 and order<30
select * from orders where order>30 and order<60
select * from orders where order>60 and order<90
如果指定分割字段为日期时,会按天数进行分割
假设有3天,其中第一天10订单,第二条50订单,第三天20订单
select * from orders where order_date>=2020-7-20 and order_date<2020-7-21
select * from orders where order_date>=2020-7-21 and order_date<2020-7-22
select * from orders where order_date>=2020-7-22 and order_date<2020-7-23
hdfs出现此页面说明导入成功
3.1.2 使用where语句过滤导入表
//--where 指定where条件
//--delete-target-dir 如果目标目录存在,则删除
sqoop import \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--table orders \
--where "order_id<100" \
--username root \
--password root \
--delete-target-dir \
--target-dir /data/retail_db/orders \
--m 3
3.1.3 通过COLUMNS过滤导入表
//--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
3.1.4 使用query方式导入数据
$CONDITIONS
:使用where子句必须添加,如果query后面使用的是双引号,则$CONDITIONS
前面必须加转义符,防止Shell识别为自己的变量
split-by:用于指定分割的列
在并行导入查询结果时,必须指定split-by。否则会报错(即通过query方式并m设置大于1时必须制定split-by)
sqoop import \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--query "select * from orders where order_id>500 and \$CONDITIONS" \
--username root \
--password root \
--split-by order_id \
--delete-target-dir \
--target-dir /data/retail_db/order \
--m 3
3.1.5 使用Sqoop增量导入数据
incremental指定增量导入的模式
- append:追加数据记录
- lastmodified:可追加更新的数据
//--incremental 增量导入
//--check-column 指定递增的列
//--last-value 指定上一次导入的最大值
// --last-value '0' 每次job执行成功之后都会修改 --last-value 值 将最后一次的最大值填充进去,这里的 '0' 没有实际含义,只是为了保证第一次数据导入时值最小
sqoop import \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--table orders \
--username root \
--password root \
--incremental append \
--check-column order_date \
--last-value '2013-07-24 00:00:00' \
--target-dir /data/retail_db/orders \
--m 3
3.1.6 创建增量导入job,并定时执行
// --last-value '0' 每次job执行成功之后都会修改 --last-value 值 将最后一次的最大值填充进去,这里的 '0' 没有实际含义,只是为了保证第一次数据导入时值最小,根据check-column的字段类型进行设置,last-value 会自动更新
//创建job
sqoop job --create mysql2hdfs \
-- import \
--connect jdbc:mysql://localhost:3306/retail_db \
--driver com.mysql.jdbc.Driver \
--table orders \
--username root \
--password root \
--incremental append \
--check-column order_date \
--last-value '1970-1-1' \
--target-dir /data/retail_db/orders \
--m 3
//查看job
sqoop job --list
//执行job命令
sqoop job --exec mysql2hdfs
//每天可以定时执行(每天2点执行一次)
crontab -e
* 2 */1 * * sqoop job --exec mysql2hdfs
3.2 导入数据到Hive中
3.2.1 直接导入数据到Hive
如果没有相应的数据库则进行创建
hive -e “create database if not exists retail_db;”
//--create-hive-table 自动创建表,指定创建一个新的hive表,如果表已经存在则报错[一般不使用]
//--hive-overwrite 覆盖原有表数据
//--hive-import 通过hive-import指定导入到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
3.2.2 导入数据到Hive分区
注意:分区字段不能当成普通字段导入表(分区表)中
//--hive-partition-key 分区字段
//--hive-partition-value 分区值
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
3.3 导入数据到HBase中
hbase中需要先创建表 create ‘products’,‘data’ 【如果表存在请忽略】
如不指定hbase-row-key则RowKey默认为行号
//--table 指定导入HBase的表
//--hbase-table HBase中的表
//--column-family 列簇
//--hbase-row-key 行键
sqoop import \
--connect jdbc:mysql://hadoop102:3306/retail_db \
--username root \
--password root \
--driver com.mysql.jdbc.Driver \
--table products \
--columns "product_id, product_name, product_description, product_price, product_image" \
--hbase-table products \
--column-family data \
--hbase-row-key product_id \
--m 3
3.4HDFS向MySQL中导出数据
3.4.1 在MySQL中创建表
create table `customers_demo` (
`customer_id` int(11),
`customer_fname` varchar(45),
`customer_lname` varchar(45),
`customer_email` varchar(45),
`customer_password` varchar(45),
`customer_street` varchar(255),
`customer_city` varchar(45),
`customer_state` varchar(45),
`customer_zipcode` varchar(45)
)
3.4.2导出数据到MySQL
//--export-dir 导出文件的目录,确保路径存在
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
3.5 导入文件格式
–as-textfile 导入数据为text文件(默认)
–as-avrodatafile 导入数据为avro文件
–as-sequencefile 导入数据为sequence文件
–as-parquetfile 导入数据为parquet文件
sqoop import \
--connect jdbc:mysql://hadoop102:3306/hr \
--table orders \
--username root \
--password root \
--delete-target-dir \
--target-dir /data/orders \
--m 3 \
--as-sequencefile
3.6 编写sqoop脚本
sqoop脚本
1.编写脚本 job_RDBMS2HDFS.opt
--------------------------------------------
import
--connect
jdbc:mysql://hadoop102: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