第一章 Sqoop简介以及使用

1.1 产生背景

基于传统关系型数据库的稳定性,还是有很多企业将数据存储在关系型数据库中;早期由于工具的缺乏,Hadoop与传统数据库之间的数据传输非常困难。基于前两个方面的考虑,需要一个在传统关系型数据库和Hadoop之间进行数据传输的项目,Sqoop应运而生。

1.2 Sqoop是什么

​ Sqoop是一个用于Hadoop结构化数据存储(如关系型数据库)之间进行高效传输大批量数据的工具。它包括以下两个方面:
​ 可以使用Sqoop将数据从关系型数据库管理系统(如MySQL)导入到Hadoop系统(如HDFS、Hive、HBase)中
​ 将数据从Hadoop系统中抽取并导出到关系型数据库(如MySQL)

常见数据库开源工具:

  1. sqoop
  2. datax
  3. kettle
  4. cannal

1.3 底层实现原理

​ Sqoop的核心设计思想是利用MapReduce加快数据传输速度。也就是说Sqoop的导入和导出功能是通过基于Map Task(只有map)的MapReduce作业实现的。所以它是一种批处理方式进行数据传输,难以实现实时的数据进行导入和导出。


官网介绍:
Apache Sqoop™ is a tool designed for efficiently transferring bulk
data between Apache Hadoop and structured datastores such as relational databases.

Sqoop结构图:

1.4 特点

  • 优点:它可以将跨平台的数据进行整合。
  • 缺点:它不是很灵活。

主要执行操作

#mermaid-svg-4biMgUnEHVuyguZg {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-4biMgUnEHVuyguZg .error-icon{fill:#552222;}#mermaid-svg-4biMgUnEHVuyguZg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4biMgUnEHVuyguZg .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-4biMgUnEHVuyguZg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4biMgUnEHVuyguZg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4biMgUnEHVuyguZg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4biMgUnEHVuyguZg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4biMgUnEHVuyguZg .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4biMgUnEHVuyguZg .marker.cross{stroke:#333333;}#mermaid-svg-4biMgUnEHVuyguZg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4biMgUnEHVuyguZg .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-4biMgUnEHVuyguZg text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-4biMgUnEHVuyguZg .actor-line{stroke:grey;}#mermaid-svg-4biMgUnEHVuyguZg .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-4biMgUnEHVuyguZg .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-4biMgUnEHVuyguZg #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-4biMgUnEHVuyguZg .sequenceNumber{fill:white;}#mermaid-svg-4biMgUnEHVuyguZg #sequencenumber{fill:#333;}#mermaid-svg-4biMgUnEHVuyguZg #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-4biMgUnEHVuyguZg .messageText{fill:#333;stroke:#333;}#mermaid-svg-4biMgUnEHVuyguZg .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-4biMgUnEHVuyguZg .labelText,#mermaid-svg-4biMgUnEHVuyguZg .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-4biMgUnEHVuyguZg .loopText,#mermaid-svg-4biMgUnEHVuyguZg .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-4biMgUnEHVuyguZg .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-4biMgUnEHVuyguZg .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-4biMgUnEHVuyguZg .noteText,#mermaid-svg-4biMgUnEHVuyguZg .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-4biMgUnEHVuyguZg .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-4biMgUnEHVuyguZg .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-4biMgUnEHVuyguZg .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-4biMgUnEHVuyguZg .actorPopupMenu{position:absolute;}#mermaid-svg-4biMgUnEHVuyguZg .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-4biMgUnEHVuyguZg .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-4biMgUnEHVuyguZg .actor-man circle,#mermaid-svg-4biMgUnEHVuyguZg line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-4biMgUnEHVuyguZg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Mysql HDFS Hive HBase import import import export export Mysql HDFS Hive HBase

sqoop的重要的几个关键词

  • import : 从关系型数据库到hadoop
  • export : 从hadoop到关系型数据库。

第二章 Sqoop的安装

注意:在安装sqoop之前要配置好本机的Java环境和Hadoop环境

先把spoop的安装包sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz拷贝在系统目录下的 /root/soft下面

2.1、解压配置环境变量

# 解压tar.gz包
[root@qianfeng01 local] tar -zxvf /root/sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz -C /usr/local/#把sqoop的安装路径修改为sqoop,方便以后配置和调用
[root@qianfeng01 local]# mv  sqoop-1.4.7.bin__hadoop-2.6.0 sqoop1.4.7
[root@qianfeng01 sqoop1.4.7]# vi /etc/profile
# 追加内容如下:export SQOOP_HOME=/usr/local/sqoop1.4.7
export PATH=$PATH:$SQOOP_HOME/bin

2.2、新建配置文件

[root@qianfeng01 sqoop1.4.7] mv ./conf/sqoop-env-template.sh ./conf/sqoop-env.sh

2.3、修改配置文件

配置文件:

[root@qianfeng01 sqoop1.4.7]  vi ./conf/sqoop-env.sh

按照本系统实际安装的Hadoop系列目录配置好下面的路径:

export HADOOP_COMMON_HOME=/usr/local/hadoop-2.7.6/
export HADOOP_MAPRED_HOME=/usr/local/hadoop-2.7.6/
export HIVE_HOME=/usr/local/hive-2.1.1/
export ZOOCFGDIR=/usr/local/zookeeper-3.4.10/

2.4、拷贝mysql驱动

因为我们现在通过JDBC让Mysql和HDFS等进行数据的导入导出,所以我们先必须把JDBC的驱动包拷贝到sqoop/lib路径下,如下

[root@qianfeng01 sqoop1.4.7] cp /root/mysql-connector-java-5.1.18.jar ./lib/

2.5、验证安装:

#查看sqoop的版本
[root@qianfeng01 sqoop1.4.7] sqoop version

第三章 Sqoop命令执行

3.1 常见命令执行参数

通过sqoop加不同参数可以执行导入导出,通过sqoop help 可以查看常见的命令行

#常见sqoop参数
[root@qianfeng01 sqoop1.4.7] sqoop helpcodegen            Generate code to interact with database recordscreate-hive-table  Import a table definition into Hiveeval               Evaluate a SQL statement and display the resultsexport             Export an HDFS directory to a database table #导出help               List available commandsimport             Import a table from a database to HDFS  #导入import-all-tables  Import tables from a database to HDFSimport-mainframe   Import mainframe datasets to HDFSlist-databases     List available databases on a serverlist-tables        List available tables in a databaseversion            Display version information

3.2 直接执行命令

Sqoop运行的时候不需要启动后台进程,直接执行sqoop命令加参数即可.简单举例如下:

# #通过参数用下面查看数据库
[root@qianfeng01 sqoop1.4.7] sqoop list-databases --connect jdbc:mysql://localhost:3306 --username root --password 123123;

3.3 通过文件传递参数(脚本)

在执行sqoop命令时,如果每次执行的命令都相似,那么把相同的参数可以抽取出来,放在一个文本文件中,把执行时的参数加入到这个文本文件为参数即可. 这个文本文件可以用--options-file来指定,平时可以用定时任务来执行这个脚本,避免每次手工操作.

3.2章节中命令中的jdbc连接的参数一般是不变的,可以把它抽取出来放在一个文件中/.../sqoop1.4.7/config.conf,如下:

list-databases
--connect
jdbc:mysql://localhost:3306
--username
root
--password
123123

那么上面的执行的命令就可以变为:

[root@qianfeng01 sqoop1.4.7] bin/sqoop --options-file config.conf

为了让配置文件config.txt的可读性更强,可以加入空行和注释,不会影响文件内容的读取,如下:

# 指令: 列出mysql中的所有数据库
list-databases# 指定连接字符串
--connect
jdbc:mysql://localhost:3306--username
root--password
123123

3.4 Import 详解

import是从关系数据库导入到Hadoop,下面是一些通用参数介绍:

3.4.1通用参数

如下:

Argument Description
–connect 指定JDBC连接字符串
--connection-manager 指定连接管理类
--driver 指定连接的驱动程序
-P 从控制台读入密码(可以防止密码显示中控制台)
–password 指定访问数据库的密码
–username 指定访问数据库的用户名

3.4.1.1 连接数据库

sqoop的设计就是把数据库数据导入HDFS,所以必须指定连接字符串才能访问数据库,这个连接字符串类似于URL,这个连接字符串通过--connect参数指定,它描述了连接的数据库地址和具体的连接数据库,譬如:

[root@qianfeng01 sqoop1.4.7] sqoop import --connect jdbc:mysql://database.example.com/employees
#指定连接的服务器地址是database.example.com ,要连接的数据库是employees

上面连接命令只是指定数据库,默认情况下数据库都是需要用户名和参数的,在这里可以用--username--password来指定,譬如:

#指定用户名和密码来连接数据库
[root@qianfeng01 sqoop1.4.7] sqoop import --connect jdbc:mysql://localhost:3306/mysql --username root --password 123123;

3.4.1.2 查看数据库

在Sqoop中,可以通过list-databases参数来查看mysql的数据库,这样在导入之前可以得到所有的数据库的名字,具体案例如下:

# 列出所有数据库
[root@qianfeng01 sqoop1.4.7] bin/sqoop list-databases --connect jdbc:mysql://localhost:3306 --username root --password 123123;

3.4.1.3 查看所有表

在得到所有数据库的名字后,也可以查看当前数据库中的所有表,可以使用 list-tables参数来进行查看,查看的时候在url连接中一定要指定数据库的名字.

# 列出数据库中所有表
[root@qianfeng01 sqoop1.4.7] bin/sqoop list-tables --connect jdbc:mysql://localhost:3306/qfdb --username root --password 123123;

3.4.2 Import的控制参数

常见Import的控制参数有如下几个:

Argument Description
--append 通过追加的方式导入到HDFS
--as-avrodatafile 导入为 Avro Data 文件格式
--as-sequencefile 导入为 SequenceFiles文件格式
--as-textfile 导入为文本格式 (默认值)
--as-parquetfile 导入为 Parquet 文件格式
--columns 指定要导入的列
--delete-target-dir 如果目标文件夹存在,则删除
--fetch-size 一次从数据库读取的数量大小
-m,--num-mappers n 用来指定map tasks的数量,用来做并行导入
-e,--query 指定要查询的SQL语句
--split-by 用来指定分片的列
--table 需要导入的表名
--target-dir HDFS 的目标文件夹
--where 用来指定导入数据的where条件
-z,--compress 是否要压缩
--compression-codec 使用Hadoop压缩 (默认是 gzip)

3.4.2.1 指定表导入

数据准备

:在本地mysql数据库中新建一个qfdb数据库,sql代码在data/qfdb.sql中,如下:

CREATE TABLE emp(empno        INT primary key,ename        VARCHAR(50),job        VARCHAR(50),mgr        INT,hiredate    DATE,sal        DECIMAL(7,2),comm        decimal(7,2),deptno        INT
) ;
INSERT INTO emp values(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);
INSERT INTO emp values(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30);
INSERT INTO emp values(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30);
INSERT INTO emp values(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20);
INSERT INTO emp values(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30);
INSERT INTO emp values(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30);
INSERT INTO emp values(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10);
INSERT INTO emp values(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,NULL,20);
INSERT INTO emp values(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10);
INSERT INTO emp values(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30);
INSERT INTO emp values(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,NULL,20);
INSERT INTO emp values(7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30);
INSERT INTO emp values(7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20);
INSERT INTO emp values(7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10);

sqoop的典型导入都是把关系数据库中的表导入到HDFS中,使用--table参数可以指定具体的表导入到hdfs,譬如用 --table emp,默认情况下是全部字段导入.如下:

[root@qianfeng01 sqoop1.4.7]# bin/sqoop import --connect jdbc:mysql://localhost:3306/qfdb \
--username root --password 123123 \
--table emp \
--target-dir hdfs://qianfeng01:9000/sqoopdata/emp
--delete-target-dir

可以快速使用hdfs的命令查询结果

[root@qianfeng01 sqoop1.4.7]# hdfs dfs -cat /sqoopdata/emp/par*

3.4.2.2 指定列导入

如果想导入某几列,可以使用 --columns,如下:

[root@qianfeng01 sqoop1.4.7]# bin/sqoop import --connect jdbc:mysql://localhost:3306/qfdb \
--username root --password 123123 \
--table emp \
--columns 'empno,mgr' \
--target-dir hdfs://qianfeng01:9000/sqoopdata/emp \
--delete-target-dir

可以使用下面hdfs命令快速查看结果

[root@qianfeng01 sqoop1.4.7]# hdfs dfs -cat /sqoopdata/emp/par*
3.4.2.3 指定条件导入

在导入表的时候,也可以通过指定where条件来导入,具体参数使用 --where,譬如要导入员工号大于7800的记录,可以用下面参数:

[root@qianfeng01 sqoop1.4.7]# bin/sqoop import --connect jdbc:mysql://localhost:3306/qfdb \
--username root --password 123123 \
--table emp \
--columns 'empno,mgr' \
--where 'empno>7800' \
--target-dir hdfs://qianfeng01:9000/sqoopdata/5 \
--delete-target-dir

用命令查询结果:

[root@qianfeng01 sqoop1.4.7]# hdfs dfs -cat /sqoopdata/emp/par*

结果如下:

7839,null
7844,7698
7876,7788
7900,7698
7902,7566
7934,7782
3.4.2.4 指定Sql导入

上面的可以通过表,字段,条件进行导入,但是还不够灵活,其实sqoop还可以通过自定义的sql来进行导入,可以通过--query 参数来进行导入,这样就最大化的用到了Sql的灵活性.如下:

[root@qianfeng01 sqoop1.4.7]# bin/sqoop import --connect jdbc:mysql://localhost:3306/qfdb \
--username root --password 123123 \
--query 'select empno,mgr,job from emp WHERE empno>7800 and $CONDITIONS' \
--target-dir hdfs://qianfeng01:9000/sqoopdata/emp \
--delete-target-dir \
--split-by empno \
-m 1

注意:在通过--query来导入数据时,必须要指定--target-dir

如果你想通过并行的方式导入结果,每个map task需要执行sql查询语句的副本,结果会根据sqoop推测的边界条件分区。query必须包含$CONDITIONS。这样每个scoop程序都会被替换为一个独立的条件。同时你必须指定--split-by.分区

-m 1 是指定通过一个Mapper来执行流程

查询执行结果

[root@qianfeng01 sqoop1.4.7]# hdfs dfs -cat /sqoopdata/emp/par*

结果如下:

7839,null,PRESIDENT
7844,7698,SALESMAN
7876,7788,CLERK
7900,7698,CLERK
7902,7566,ANALYST
7934,7782,CLERK

3.4.2.5 单双引号区别

在导入数据时,默认的字符引号是单引号,这样sqoop在解析的时候就安装字面量来解析,不会做转移:例如:

--query 'select empno,mgr,job from emp WHERE empno>7800 and $CONDITIONS'  \

如果使用了双引号,那么Sqoop在解析的时候会做转义的解析,这时候就必须要加转义字符: 如下:

--query "select empno,mgr,job from emp WHERE empno>7800 and \$CONDITIONS" \

3.4.2.6 MySql缺主键问题

1、如果mysql的表没有主键,将会报错:

19/12/02 10:39:50 ERROR tool.ImportTool: Import
failed: No primary key could be found for table u1. Please specify one with
-- split-  by or perform a sequential import with '-m 1

解决方案:

通过 --split-by 来指定要分片的列

代码如下:

[root@qianfeng01 sqoop1.4.7]# bin/sqoop import --connect jdbc:mysql://localhost:3306/qfdb \
--username root --password 123123 \
--query 'select empno,mgr,job from emp WHERE empno>7800 and $CONDITIONS' \
--target-dir hdfs://qianfeng01:9000/sqoopdata/emp \
--delete-target-dir \
--split-by empno \
-m 1

3.4.3 导入到Hive中

3.4.3.1 说明

​ Sqoop的导入工具的主要功能是将数据上传到HDFS中的文件中。如果您有一个与HDFS集群相关联的Hive,Sqoop还可以通过生成和执行CREATETABLE语句来定义Hive中的数据,从而将数据导入到Hive中。将数据导入到Hive中就像在Sqoop命令行中添加–hive-import选项。

​ 如果Hive表已经存在,则可以指定--hive-overwrite选项,以指示必须替换单元中的现有表。在将数据导入HDFS或省略此步骤之后,Sqoop将生成一个Hive脚本,其中包含使用Hive的类型定义列的CREATE表操作,并生成LOAD Data INPATH语句将数据文件移动到Hive的仓库目录中。

在导入Hive之前先要配置Hadoop的Classpath才可以,否则会报类找不到错误,在/etc/profile末尾添加如下配置:

export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HIVE_HOME/lib/*#刷新配置
source /etc/profile

3.4.3.2 参数说明

具体的参数如下:

Argument Description
--hive-home 覆盖环境配置中的$HIVE_HOME,默认可以不配置
–hive-import 指定导入数据到Hive中
--hive-overwrite 覆盖当前已有的数据
--create-hive-table 是否创建hive表,如果已经存在,则会失败
--hive-table 设置要导入的Hive中的表名

3.4.3.3 实际导入案例

具体导入演示代码如下:

提示: 为了看到演示效果,可以先在Hive删除emp表

[root@qianfeng01 sqoop1.4.7] bin/sqoop import --connect jdbc:mysql://localhost:3306/qfdb \
--username root \
--password 123123 \
--table emp \
--hive-import \
--hive-overwrite \
-m 1

在Hive中查看表:

hive> show tables;
#结果如下:
OK
emp

可以在Hive中查看数据是否导入:

select * from emp;
#结果如下:
7369    SMITH   CLERK   7902    1980-12-17      800.0   NULL    20
7499    ALLEN   SALESMAN        7698    1981-02-20      1600.0  300.0   30
7521    WARD    SALESMAN        7698    1981-02-22      1250.0  500.0   30
7566    JONES   MANAGER 7839    1981-04-02      2975.0  NULL    20
7654    MARTIN  SALESMAN        7698    1981-09-28      1250.0  1400.0  30
7698    BLAKE   MANAGER 7839    1981-05-01      2850.0  NULL    30
7782    CLARK   MANAGER 7839    1981-06-09      2450.0  NULL    10
7788    SCOTT   ANALYST 7566    1987-04-19      3000.0  NULL    20
7839    KING    PRESIDENT       NULL    1981-11-17      5000.0  NULL    10
7844    TURNER  SALESMAN        7698    1981-09-08      1500.0  0.0     30
7876    ADAMS   CLERK   7788    1987-05-23      1100.0  NULL    20
7900    JAMES   CLERK   7698    1981-12-03      950.0   NULL    30
7902    FORD    ANALYST 7566    1981-12-03      3000.0  NULL    20
7934    MILLER  CLERK   7782    1982-01-23      1300.0  NULL    10

第四章 Sqoop导入实战

4.1 Sqoop-import

案例1

表没有主键,需要指定map task的个数为1个才能执行

Sqoop导入原理:

​ Sqoop默认是并行的从数据库源导入数据。您可以使用-m或–num-mappers参数指定用于执行导入的map任务(并行进程)的数量。每个参数都取一个整数值,该整数值对应于要使用的并行度。默认情况下,使用四个任务。一些数据库可以通过将这个值增加到8或16来改善性能。

​ 默认情况下,Sqoop将标识表中的主键id列用作拆分列。从数据库中检索分割列的高值和低值,map任务操作整个范围的大小均匀的组件。譬如ID的范围是0-800,那么Sqoop默认运行4个进程,通过执行 SELECT MIN(id), MAX(id) FROM emp找出id的范围,然后把4个任务的id设置范围是(0-200),(200-400),(400-600),(600-800)

但是当一个表没有主键时,上面的切分就无法进行,sqoop导入时就会出错,这时候可以通过-m把mapper的数量设为1,只有也Mapper在运行,这时候就不需要切分,也可以避免主键不存在时候报错的问题.

#错误信息
ERROR tool.ImportTool: Import failed: No primary key could be found for table emp. Please specify one with --split-by or perform a sequential import with '-m 1'.

导入代码:

[root@qianfeng01 sqoop1.4.7]# bin/sqoop import --connect jdbc:mysql://localhost:3306/qfdb \
--username root --password 123123 \
--table emp -m 1

4.2 DBMS-HDFS

案例2

表没有主键,使用–split-by指定执行split的字段

问题同上,如果表没有主键,那么还有个办法就是手工指定要拆分的列,通过--split-by来指定

[root@qianfeng01 sqoop1.4.7]# bin/sqoop import --connect jdbc:mysql://localhost:3306/qfdb \
--username root --password 123123 \
--table emp \
--split-by empno \
--delete-target-dir \
--target-dir hdfs://qianfeng01:9000/sqoopdata/emp
-- 出错
Caused by: java.sql.SQLException: null,  message from server: "Host 'qianfeng01' is not allowed to connect to this MySQL server"

解决方案:

先连接mysql:

[root@qianfeng01 sqoop1.4.7]# mysql -uroot -p

(执行下面的语句 .:所有库下的所有表 %:任何IP地址或主机都可以连接)

mysql> GRANT ALL PRIVILEGES ON . TO 'root'@'%' IDENTIFIED BY 'mysql' WITH GRANT OPTION;FLUSH PRIVILEGES;grant all privileges on . to root@"localhost" identified by "mysql" with grant option;FLUSH PRIVILEGES;

案例3:条件导入

需要导入的数据不是全部的,而是带条件导入

[root@qianfeng01 sqoop1.4.7]# bin/sqoop import --connect jdbc:mysql://localhost:3306/qfdb \
--username root --password 123123 \
--table emp \
--split-by empno \
--where 'empno > 7777' \
--target-dir hdfs://qianfeng01:9000/sqoopdata/emp

案例4:部分字段导入

:要导入的数据,不想包含全部字段,只需要部分字段

[root@qianfeng01 sqoop1.4.7] bin/sqoop import --connect jdbc:mysql://localhost:3306/qfdb \
--username root --password 123123 \
--split-by empno \
--query 'select empno,ename,job from emp where empno > 7777 and $CONDITIONS' \
--target-dir hdfs://qianfeng01:9000/sqoopdata/7

4.3 DBMS-Hive

案例5:将数据导入到hive中

[root@qianfeng01 sqoop1.4.7]# bin/sqoop import --connect jdbc:mysql://localhost:3306/qfdb --username root --password 123123 --table emp --hive-import -m 1

第五章 Sqoop导出

在Sqoop中,使用export进行导出,指的是从HDFS中导出数据到Mysql中:

1、构建mysql的表:

CREATE TABLE `u2` (`id` int(11) DEFAULT NULL,`age` int(11) DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE TABLE `u3` (`id` int(11) DEFAULT NULL,`name` varchar(20) default NULL,`age` int(11) DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2、HDFS导出到mysql

[root@qianfeng01 sqoop1.4.7]# sqoop export --connect jdbc:mysql://qianfeng01:3306/qfdb \
--username root \
--password root \
--table u2 \
--driver com.mysql.jdbc.Driver \
--export-dir '/1906sqoop/u2/*' \
-m 1# 方法二:
先从新导入数据:
[root@qianfeng01 sqoop1.4.7]# sqoop import --connect jdbc:mysql://qianfeng01:3306/qfdb \
--username root \
--password root \
--query 'select id,name,age from stu where id > 6 and $CONDITIONS' \
--driver com.mysql.jdbc.Driver \
--delete-target-dir \
--target-dir '/1906sqoop/u7' \
--split-by id \
-m 1 \
--fields-terminated-by '\t' \
--null-string '\\N' \
--null-non-string '0'导出语句:
[root@qianfeng01 sqoop1.4.7]# sqoop export --connect jdbc:mysql://hadoop01:3306/qfdb \
--username root \
--password root \
--table u3 \
--driver com.mysql.jdbc.Driver \
--export-dir '/1906sqoop/u7/*' \
--input-fields-terminated-by '\t' \
--input-null-string '\\N' \
--input-null-non-string '\\N' \
-m 1

要注意以下问题

  • mysql表的编码格式做为utf8,hdfs文件中的列数类型和mysql表中的字段数一样
  • 导出暂不能由hbase表导出mysql关系型数据库中
  • --export-dir是一个hdfs中的目录,它不识别_SUCCESS文件
  • –query导入的时候注意设置问题。
  • 导出数据中有些列值有"null",会报没法解析
  • 导出数据的类型需要和mysql中的一致(能自动转没有问题)

第六章 Sqoop的Job

6.1 增量导入数据

6.1.1 使用场景:

  1. 经常被操作不断产生数据的表,建议增量。
  2. 当某表基数很大,但是变化很小,也建议增量

6.1.2 使用方式

  • 1、query where : 能精确锁定数据范围
  • 2、–incremental : 增量,最后记录值来做的

6.1.2.1 query where方式:

通过查询具体日期的方式进行导入

新建一个脚本文件

[root@hadoop01 sqoop-1.4.7] vi ./import.sh

写入以下内容:

#!/bin/bash
# yesterday=`date -d "1 days ago" "+%Y-%m-%d"`
yesterday='2019-02-01'
sqoop import --connect jdbc:mysql://qianfeng01:3306/sales_source \
--username root \
--password 123123 \
--query "select * from sales_order where DATE(order_date) = '${yesterday}' and \$CONDITIONS" \
--driver com.mysql.jdbc.Driver \
--delete-target-dir \
--target-dir /user/hive/warehouse/sales_order/dt=${yesterday} \
--split-by id \
-m 1 \
--fields-terminated-by '\t' \
--null-string '\\N' \
--null-non-string '0'

通过下面hdfs可以快速查询到结果:

 [root@hadoop01 sqoop-1.4.7]# hdfs dfs -cat /user/hive/warehouse/sales_order/dt=2019-01-01/pa*

6.1.2.2 increment的append方式:

#将会手动维护last-value
[root@hadoop01 sqoop-1.4.7]# sqoop import --connect jdbc:mysql://qianfeng01:3306/sales_source \
--username root \
--password root \
--table sales_order \
--driver com.mysql.jdbc.Driver \
--target-dir /user/hive/warehouse/sales_order1/dt=2019-12-30 \
--split-by id \
-m 1 \
--check-column order_number \
--incremental append \
--last-value 80000 \
--fields-terminated-by '\t' \
--null-string '\\N' \
--null-non-string '0'

使用下面命令查看:

[root@hadoop01 sqoop-1.4.7]# hdfs dfs -cat /user/hive/warehouse/sales_order1/dt=2019-12-30/pa*

6.2 Job操作

job的好处:
1、一次创建,后面不需要创建,可重复执行job即可
2、它可以帮我们记录增量导入数据的最后记录值
3、job的元数据默认存储目录:$HOME/.sqoop/
4、job的元数据也可以存储于mysql中。

sqoop提供一系列的job语句来操作sqoop。

$ sqoop job (generic-args) (job-args) [-- [subtool-name] (subtool-args)]
$ sqoop-job (generic-args) (job-args) [-- [subtool-name] (subtool-args)]

使用方法:

usage: sqoop job [GENERIC-ARGS] [JOB-ARGS] [-- [<tool-name>] [TOOL-ARGS]]Job management arguments:--create <job-id>            Create a new saved job--delete <job-id>            Delete a saved job--exec <job-id>              Run a saved job--help                       Print usage instructions--list                       List saved jobs--meta-connect <jdbc-uri>    Specify JDBC connect string for themetastore--show <job-id>              Show the parameters for a saved job--verbose                    Print more information while working

列出sqoop的job:

[root@qianfeng01 sqoop1.4.7] sqoop job --list

创建一个sqoop的job:

[root@qianfeng01 sqoop1.4.7]# sqoop job --create sq2 -- import  --connect jdbc:mysql://qianfeng01:3306/qfdb \
--username root \
--password root \
--table u2 \
--driver com.mysql.jdbc.Driver \
--delete-target-dir \
--target-dir '/1906sqoop/u9' \
--split-by id \
-m 1

执行sqoop的job:

#如报错json包找不到,则需要手动添加
sqoop job --exec sq1执行的时候回让输入密码:
输入该节点用户的对应的密码即可
# 1、配置客户端记住密码(sqoop-site.xml)追加<property><name>sqoop.metastore.client.record.password</name><value>true</value></property># 2、将密码配置到hdfs的某个文件,我们指向该密码文件
说明:在创建Job时,使用--password-file参数,而且非--passoword。主要原因是在执行Job时使用--password参数将有警告,并且需要输入密码才能执行Job。当我们采用--password-file参数时,执行Job无需输入数据库密码。
[root@qianfeng01 sqoop1.4.7]# echo -n "root" > sqoop.pwd
[root@qianfeng01 sqoop1.4.7]# hdfs dfs -rm sqoop.pwd /input/sqoop.pwd
[root@qianfeng01 sqoop1.4.7]# hdfs dfs -put sqoop.pwd /input
[root@qianfeng01 sqoop1.4.7]# hdfs dfs -chmod 400 /input/sqoop.pwd
[root@qianfeng01 sqoop1.4.7]# hdfs dfs -ls /input
-r-------- 1 hadoop supergroup 6 2018-01-15 18:38 /input/sqoop.pwd

查看sqoop的job:

[root@qianfeng01 sqoop1.4.7] sqoop job --show sq1

删除sqoop的job:

[root@qianfeng01 sqoop1.4.7] sqoop job --delete sq1

问题:

1、创建job报错:19/12/02 23:29:17 ERROR sqoop.Sqoop: Got exception running Sqoop: java.lang.NullPointerException
java.lang.NullPointerExceptionat org.json.JSONObject.<init>(JSONObject.java:144)解决办法:
添加java-json.jar包到sqoop的lib目录中。
如果上述办法没有办法解决,请注意hcatlog的版本是否过高,过高将其hcatlog包剔除sqoop的lib目录即可。2、报错:Caused by: java.lang.ClassNotFoundException: org.json.JSONObject
解决办法:
添加java-json.jar包到sqoop的lib目录中。

6.3 metastore服务

metastore服务是元数据服务,用于存储sqoop的job相关信息,将信息保存于关系型数据库中。

优点:

1、job信息更加有保障
2、多个client之间共享job信息。

(1)在MySQL中创建Sqoop的元数据存储数据库 (如果有root可以用root)

create database sqoop;
create user 'sqoop'@'%' identified by 'sqoop';
grant all privileges on sqoop.* to 'sqoop'@'%';
flush privileges;

(2)配置Sqoop的元数据存储参数
$SQOOP_HOME/conf/sqoop-site.xml中添加以下的参数,在/code/sqoop-site.xml也可以查阅。

sqoop.metastore.server.location:指定元数据服务器位置,初始化建表时需要。
sqoop.metastore.client.autoconnect.url:客户端自动连接的数据库的URL。
sqoop.metastore.client.autoconnect.username:连接数据库的用户名。
sqoop.metastore.client.enable.autoconnect:启用客户端自动连接数据库。
sqoop.metastore.client.record.password:在数据库中保存密码,不需要密码即可执行sqoop job脚本。
sqoop.metastore.client.autoconnect.password:连接数据库的密码。<property><name>sqoop.metastore.client.enable.autoconnect</name><value>false</value><description>If true, Sqoop will connect to a local metastorefor job management when no other metastore arguments areprovided.</description></property><property><name>sqoop.metastore.client.autoconnect.url</name><value>jdbc:mysql://192.168.10.103:3306/sqoop</value></property><property><name>sqoop.metastore.client.autoconnect.username</name><value>root</value></property><property><name>sqoop.metastore.client.autoconnect.password</name><value>123456</value></property><property><name>sqoop.metastore.client.record.password</name><value>true</value></property><property><name>sqoop.metastore.server.location</name><value>/usr/local/sqoop/sqoop-metastore/shared.db</value></property><property><name>sqoop.metastore.server.port</name><value>16000</value></property>

(3)重启Sqoop服务
保存配置并重启完成后,MySQL的sqoop库中有了一个名为SQOOP_ROOT的空表。

#启动:
[root@qianfeng01 sqoop1.4.7]# sqoop metastore &#查看进程:
[root@qianfeng01 sqoop1.4.7]# jps
sqoop#关闭:
[root@qianfeng01 sqoop1.4.7]# sqoop metastore --shutdown

(4)预装载SQOOP表

insert into SQOOP_ROOT values (NULL, 'sqoop.hsqldb.job.storage.version', '0');

(5)job相关操作

[root@qianfeng01 sqoop1.4.7]# sqoop job --list  ###需要加--meta-connect创建job:
[root@qianfeng01 sqoop1.4.7]# sqoop job --create sq3 --meta-connect 'jdbc:mysql://qianfeng01:3306/sqoop?user=root&password=root' -- import  --connect jdbc:mysql://hadoop01:3306/test \
--username root \
--password root \
--table user_info \
--driver com.mysql.jdbc.Driver \
--delete-target-dir \
--target-dir '/1906sqoop/u9' \
--split-by id \
-m 1列出job:
[root@qianfeng01 sqoop1.4.7]# sqoop job --meta-connect 'jdbc:mysql://qianfeng01:3306/sqoop?user=root&password=root' --list执行job:
[root@qianfeng01 sqoop1.4.7]# sqoop job --meta-connect 'jdbc:mysql://qianfeng01:3306/sqoop?user=root&password=root' --exec sq3执行job并打印详细信息:
[root@qianfeng01 sqoop1.4.7]# sqoop job --meta-connect 'jdbc:mysql://qianfeng01:3306/sqoop?user=root&password=root' --exec sq3 -verbose

​ 此时并不会返回先前已经创建的myjob_incremental_import作业,因为此时MySQL中没有元数据信息。该命令执行完成后,MySQL的sqoop库中有了一个名为SQOOP_SESSIONS的空表,该表存储sqoop job相关信息。

(6)将表的存储引擎修改为MYISAM(如job信息存储到mysql的SQOOP_SESSIONS则不用执行如下)

alter table SQOOP_ROOT engine=myisam;
alter table SQOOP_SESSIONS engine=myisam;

因为每次执行增量抽取后都会更新last_value值,如果使用Innodb可能引起事务锁超时错误。

第七章 Sqoop优化

7.1 -m与split-by的优化

  1. 小量数据时(200M左右) :最好使用一一个map,快且减少小文件。
  2. 大量数据时:要特别考虑数据的特征,对于split- by最完美的情况是有一个:均匀分布的数字(如自增列)或时间字段,且这个字段还有索引(最好字段是int、tinyin),这样在抽取时使得并发的每个sq1处理相近的数据量,并且sqoop附加的where条件可以使用索引。
  3. split-by id,-m 2, 数据量1-100。第 一个mapper:(0,50]第二个mapper: (50, 100],对于m要综合考虑数据量、I0、源数据库的性能、集群的资源等等。一种简单的考虑是最大不超过yarn.上分配给这个用户的vcore个数,最小“数据量/m”要够一个128MB的文件。如果条件允许可以先设置一个值跑着试试,然后观察源数据库负载、集群I0以及运行时长等,再进行相应调整。

7.2 --fetch-size n

一次取mysq1中批量读取的数据条数。建议优化如下:

  1. 考虑一条数据的量。(如果2个字段和200个字段的–fetch-size不能一-样)
  2. 考虑数据库的性能
  3. 考虑网络速度
  4. 最好的状态是一 次–fetch-si ze能满足-一个mapper

Sqoop简介以及使用相关推荐

  1. 【Sqoop学习之一】Sqoop简介

    环境 sqoop-1.4.6 Sqoop:将关系数据库(oracle.mysql.postgresql等)数据与hadoop数据进行转换的工具. 两个版本:两个版本完全不兼容,sqoop1使用最多: ...

  2. sqoop简介与安装配置

    SQOOP的描述 SQOOP是用于对数据进行导入导出的. (1)把MySQL.Oracle等数据库中的数据导入到HDFS.Hive.HBase中 (2)把HDFS.Hive.HBase中的数据导出到M ...

  3. Sqoop数据迁移原理及基本框架

    目录 Sqoop简介 Sqoop架构 Sqoop导入底层工作原理 Sqoop导出底层工作原理 Sqoop简介 Sqoop旨在协助RDBMS与Hadoop之间进行高效的大数据交流.可以把关系型数据库的数 ...

  4. cdh mysql sqoop 驱动_大数据技术之Sqoop学习——原理、安装、使用案例、常用命令...

    第1章 Sqoop 简介 Sqoop 是一款开源的工具,主要用于在 Hadoop(Hive) 与传统的数据库 (mysql,postgresql,...) 间进行数据的高校传递,可以将一个关系型数据库 ...

  5. RDBMS和HDFS, HIVE, HBASE的迁移工具Sqoop

    Sqoop 简介 Apache Sqoop 项目旨在协助 RDBMS 与 Hadoop 之间进行高效的大数据交流.用户可以在 Sqoop 的帮助下,轻松地把关系型数据库的数据导入到 Hadoop 与其 ...

  6. 数据同步工具Sqoop

    大数据Hadoop之--数据同步工具Sqoop Sqoop基本原理及常用方法 1 概述 Apache Sqoop(SQL-to-Hadoop)项目旨在协助RDBMS(Relational Databa ...

  7. 大数据技术之Sqoop

    第1章 Sqoop简介 Sqoop是一款开源的工具,主要用于在Hadoop(Hive)与传统的数据库(mysql.postgresql...)间进行数据的传递,可以将一个关系型数据库(例如: MySQ ...

  8. 大数据技术之 Sqoop

    文章目录 1. Sqoop 简介 2. Sqoop 原理 3. Sqoop 安装 3.1 下载并解压 3.2 修改配置文件 3.3 拷贝JDBC驱动 3.4 验证 Sqoop 3.5 测试 Sqoop ...

  9. Hadoop和关系型数据库间的数据传输工具——Sqoop

    Hadoop和关系型数据库间的数据传输工具--Sqoop 一.Sqoop简介以及使用 1.1.产生背景 基于传统关系型数据库的稳定性,还是有很多企业将数据存储在关系型数据库中:早期由于工具的缺乏,Ha ...

最新文章

  1. hdu-3071 Gcd Lcm game---质因数分解+状态压缩+线段树
  2. SAP MM 特殊库存之T库存
  3. python django -5 进阶
  4. python redis集群_Python3 redis集群连接 (带密码验证)
  5. 【MM配置】评估和账户确定(Valuation Account Determination) - 2
  6. 6 种激活函数核心知识点,请务必掌握!
  7. 小程序上拉加载,下拉刷新
  8. ATEN—第九章OSPF多区域的配置
  9. 基于Java的TCP Socket通信详解(计算机端/Android手机端)
  10. Atcoder 077E - guruguru(线段树+dp)
  11. 线程(Thread)和异常
  12. oracle 11g安装自己理解
  13. Android的UC的flash插件下载,uc浏览器flash不支持解决方法详解
  14. 1秒钟等于多少毫秒,等于多少微秒
  15. 知到计算机绘图网课答案,计算机绘图知到网课答案
  16. 解决登录vCenter提示“当前网站安全证书不受信任“
  17. 等额本息公式推导------玩一下等比数列
  18. 微信小程序:页面路由
  19. 猎聘网的第二次面试之路
  20. EMC Unisphere客户端连接EMC

热门文章

  1. [NOIP模拟][动态规划]permut
  2. 博客园客户端UAP开发随笔 -- App UI设计的三大纪律八项注意
  3. 【c#基础-MessageBox】MessageBox的使用和消息框
  4. 卸载asterisk
  5. telnet不是内部或外部命令
  6. Android app本地图片转换成Drawable对象的方法
  7. 嵌入页面拒绝了我们的连接请求
  8. lvds单8转双8芯片_LVDS驱动芯片
  9. 北京软件项目外包流程及管理
  10. 建模助手 | 关于REVIT的小技巧,你知道多少?