sqoop 完整学习和遇到的错误

sqoop 学习与问题

配置问题:centos7 与sqoop1.4.7,使用比较好一些。centos6与sqoop1.4.6一起使用比较好一些。如果在centos6版本中使用sqoop1.4.7会需要修改很多配置。具体会在后面提到

1、sqoop原理

实现数据的导入导出

将导入或到处命令翻译成mapreduce程序来实现的

在翻译出的mapreduce中主要是对inputformat和outputformat进行定制。

2、sqoop 安装(这里不细说)

2.1、解压
2.2、重命名配置文件
mv sqoop-envtemplate.sh sqoop-env.sh
2.3、修改配置文件
sqoop-env.sh
2.4、拷贝JDB驱动到sqoop的lib目录下

注意在sqoop-env.sh中没有配置mysql,在执行命令的时候主动连接mysql

2.5、检测
列出数据库
sqoop list-databases \
--connect jdbc:mysql://hadoop01:3306 \
--username root --password 123456;

3、sqoop 的简单使用案例

3.1导入数据 import

从非大数据集群(RDBMS)向大数据集群(HDFS,HIVE,HBASE)中传输数据叫做:导入数据,

3.1.1 RDBMS到HDFS

​ 确定mysql服务开启

建立数据库

在mysql中写入数据
CREATE TABLE `stu1` (
  `id` bigint(10) NOT NULL,
  `name` varchar(10) DEFAULT NULL,
  `age` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

全部导入数据

sqoop import \
--connect jdbc:mysql://hadoop01:3306/mydb1 \
--username root \
--password 123456 \
--table stu1 \
--target-dir /user/sqoopmysql \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t"

查询导入$CONDITIONS 是用来传递参数的,保证输入输出一致

sqoop import \
--connect jdbc:mysql://hadoop01:3306/mydb1 \
--username root \
--password 123456 \
--target-dir /user/sqoopmysql \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--query 'select id,name,age from stu1 where id >1 and $CONDITIONS'
$CONDITIONS 是用来传递参数的,保证输入输出一致
如何使用双引号必须转义 \$conditions,防止shell认为是自己的变量

导入指定的列

sqoop import \
--connect jdbc:mysql://hadoop01:3306/mydb1 \
--username root \
--password 123456 \
--target-dir /user/sqoopmysql \
--table stu1 \
--columns id,name \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" 



columns 后面的参数用逗号分隔

关键字筛选

sqoop import \
--connect jdbc:mysql://hadoop01:3306/mydb1 \
--username root \
--password 123456 \
--target-dir /user/sqoopmysql/data1 \
--table stu1 \
--where "id=1" \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t"

where ++columns可以共用

sqoop import \
--connect jdbc:mysql://hadoop01:3306/mydb1 \
--username root \
--password 123456 \
--target-dir /user/sqoopmysql/data1 \
--table stu1 \
--columns id,name \
--where "id=1" \
--delete-target-dir \
--num-mappers \
--fields-terminated-by "\t"


3.3.2 RDBMS到Hive

先从mysql导入到hdfs,再从hdfs上面迁移到hive

sqoop import \
--connect jdbc:mysql://hadoop01:3306/mydb1 \
--driver com.mysql.jdbc.Driver \
--username root \
--password 123456 \
--table stu1 \
--num-mappers 1 \
--hive-import \
--fields-terminated-by "\t" \
--delete-target-dir \
--hive-overwrite \
--hive-table hh22.dstu1

hive-table stu1 自动创建

ERROR1


--Could not load org.apache.hadoop.hive.conf.HiveConf. Make sure HIVE_CONF_DIR is set correctly.
--解决
将hive 里面的lib下的hive-exec-**.jar 放到sqoop 的lib 下可以解决以下问题

3.2导出数据 export
从大数据集群(	hdfs,hive,hbase)向非大数据集群(rdbms)中传输数据,叫导出

hdfs\hive到RDBMS

sqoop export \
--connect jdbc:mysql://hadoop01:3306/mydb1 \
--driver com.mysql.jdbc.Driver \
--username root \
--password 123456 \
--table stu2 \
--num-mappers 1 \
--export-dir hdfs://hadoop01:8020/user/hive/warehouse/hh22.db/dstu1  \
--input-fields-terminated-by "\t"
不加切割符,会出现一个字符串

ERROR2

hadoop01:9000 failed on connection exception: java.net.ConnectException: Connection refused;
解决:
检查端口问题:mysql端口和hdfd上的端口好是否正确

4、脚本打包

使用opt格式的文件打包sqoop命名,然后执行

1、创建一个.opt文件

mkdir opt
touch opt/job_HDFS2RDBMS.opt

2、编写sqoop脚本

vi opt/job_HDFS2RDBMS.opt

sqoop export \
--connect jdbc:mysql://hadoop01:3306/mydb1 \
--driver com.mysql.jdbc.Driver \
--username root \
--password 123456 \
--table stu2 \
--num-mappers 1 \
--export-dir hdfs://hadoop01:8020/user/hive/warehouse/hh22.db/dstu1  \
--input-fields-terminated-by "\t"

3、执行该脚本

bin/sqoop --options-file /home/job/job_HDFS2RDBMS.opt

5、增量数据导入

增量数据导入分两种:

一、是基于递增列的增量数据导入(Append方式)。

二、是基于时间列的增量数据导入(LastModified方式)。

5.1 append方式

举个栗子,有一个订单表,里面每个订单有一个唯一标识自增列ID,在关系型数据库中以主键形式存在。之前已经将id在0~5201314之间的编号的订单导入到Hadoop中了(这里为HDFS),现在一段时间后我们需要将近期产生的新的订单数据导入Hadoop中(这里为HDFS),以供后续数仓进行分析。此时我们只需要指定–incremental 参数为append,–last-value参数为5201314即可。表示只从id大于5201314后开始导入。

mysql-hdfs

sqoop import \
--connect jdbc:mysql://hadoop01:3306/mydb1 \
--username root \
--password 123456 \
--table stu3 \
--num-mappers 2 \
--incremental append \
--check-column id \
--last-value 4 \
--fields-terminated-by "\t" \
--target-dir /user/sq_mysql/stu3/ 

mysql -hive

sqoop import \
--connect jdbc:mysql://hadoop01:3306/mydb1 \
--driver com.mysql.jdbc.Driver \
--username root \
--password 123456 \
--table stu3 \
--num-mappers 1 \
--incremental append \
--check-column id \
--last-value 0 \
--hive-import  \
--fields-terminated-by '\t' \
--hive-database hh22 \
--hive-table stu3 \
--target-dir /input/sqoop3/ 

--target-dir /input/sqoop3/ 是一个中间目录

注意:–append and --delete-target-dir can not be used together.

参数 说明
–incremental append 基于递增列的增量导入(将递增列值大于阈值的所有数据增量导入Hadoop)
–check-column 递增列(int)
–last-value 阈值(int)
5.2 lastmodify方式

此方式要求原有表中有time字段,它能指定一个时间戳,让Sqoop把该时间戳之后的数据导入至Hadoop(这里为HDFS)。因为后续订单可能状态会变化,变化后time字段时间戳也会变化,此时Sqoop依然会将相同状态更改后的订单导入HDFS,当然我们可以指定merge-key参数为orser_id,表示将后续新的记录与原有记录合并。

mysql-hdfs

sqoop import \
--connect jdbc:mysql://hadoop01:3306/mydb1 \
--username root \
--password 123456 \
--table stu4 \
--num-mappers 2 \
--split-by id \
--incremental lastmodified \
--check-column time \
--merge-key id \
--fields-terminated-by "\t" \
--target-dir /user/sq_mysql/stu6/ \
--last-value "2014-11-09 21:00:00"

mysql-hive


参数 说明
–incremental lastmodified 基于时间列的增量导入(将时间列大于等于阈值的所有数据增量导入Hadoop)
–check-column 时间列(int)
–last-value 阈值(int)
–merge-key 合并列(主键,合并键值相同的记录)

6 、create job

6.1创建任务


sqoop job --create job_16 -- import --connect jdbc:mysql://hadoop01:3306/mydb1 \
--driver com.mysql.jdbc.Driver \
--username root \
--password 123456 \
--table stu1 \
--input-null-string '' \
--input-null-non-string '' \
--target-dir /user/sqoopmysql \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t"

6.2 执行

sqoop job --exec job_16

显示job里面的内容: sqoop job --show job_16
删除Job :sqoop job --delete job_1

ERROR3

ERROR sqoop.Sqoop: Got exception running Sqoop: java.lang.NullPointerException
解决:
需要缺少java-json.jar这么一个jar包,到sqoop的lib下

7、 静态分区

sqoop import --connect jdbc:mysql://hadoop-02:3306/test \
--driver com.mysql.jdbc.Driver \
--username root --password 123456 \
--table user \
--columns user_id,user_name \
-m 1 \
--incremental append \
--check-column trade_time \
--last-value '2019-09-19 00:00:00' \
--fields-terminated-by '\t' \
--target-dir /input/sqoop3/ \
--hive-database qf_test \
--hive-table part1 \
--hive-import \
--hive-partition-key  trade_time \
--hive-partition-value 2019921

实现定时导数据


crontab -e

0 0 2 * * /hadoop/sqoop_jobs/sqoop_job_order.sh >> /data/hadoop/sqoop_job.log 2>&1

你可能感兴趣的:(大数据学习)