Sqoop

1. 作用

image-20180628203438952

image-20180628203419288

Sqoop 是 Apache 旗下一款“Hadoop 和关系数据库服务器之间传送数据”的工具。

导入数据MySQL,Oracle 导入数据到 Hadoop 的 HDFS、HIVE、HBASE 等数据存储系统

导出数据:从 Hadoop 的文件系统中导出数据到关系数据库 MySQL 等

Sqoop 的本质还是一个命令行工具,和 HDFS,Hive 相比,并没有什么高深的理论。

2.工作机制

将导入导出命令翻译成 MapReduce 程序来实现

在翻译出的 MapReduce 中主要是对 InputFormat 和 OutputFormat 进行定制

3.安装

注意: 目录下要有hive, 因为要拿到 hive 的 home, 执行 hive 操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
1、 准备安装包 sqoop-1.4.6.bin_hadoop-2.0.4-alpha.tar.gz

2、 解压安装包到安装目录
tar -zxvf sqoop-1.4.6.bin_hadoop-2.0.4-alpha.tar.gz -C apps/ cd apps
mv sqoop-1.4.6.bin_hadoop-2.0.4-alpha/ sqoop-1.4.6

3、 进入到 conf 文件夹,找到 sqoop-env-template.sh,修改其名称为 sqoop-env.sh cd conf
mv sqoop-env-template.sh sqoop-env.sh

4、 修改 sqoop-env.sh
-----
export HADOOP_COMMON_HOME=/home/ap/apps/hadoop export HADOOP_MAPRED_HOME=/home/ap/apps/hadoop export HBASE_HOME=/home/ap/apps/hbase
export HIVE_HOME=/home/ap/apps/hive
export ZOOCFGDIR=/home/ap/apps/zookeeper/conf
-----

5、 加入 mysql 驱动包到 sqoop-1.4.6/lib 目录下
cp mysql-connector-java-5.1.40-bin.jar ~/apps/sqoop-1.4.6/lib/

6、 配置系统环境变量 vi ~/.bashrc
然后输入:
export SQOOP_HOME=/home/hadoop/apps/sqoop-1.4.6 export PATH=$PATH:$SQOOP_HOME/bin
然后保存退出
source ~/.bashrc

7、 验证安装是否成功
sqoop-version 或者 sqoopversion

ps : 吹出现警告, 不用管
---
[ap@cs2]~% sqoop version
Warning: /home/ap/apps/sqoop/../hcatalog does not exist! HCatalog jobs will fail.
Please set $HCAT_HOME to the root of your HCatalog installation.
Warning: /home/ap/apps/sqoop/../accumulo does not exist! Accumulo imports will fail.
Please set $ACCUMULO_HOME to the root of your Accumulo installation.
Warning: /home/ap/apps/sqoop/../zookeeper does not exist! Accumulo imports will fail.
Please set $ZOOKEEPER_HOME to the root of your Zookeeper installation.
18/06/28 20:43:52 INFO sqoop.Sqoop: Running Sqoop version: 1.4.6
Sqoop 1.4.6
git commit id c0c5a81723759fa575844a0a1eae8f510fa32c25
Compiled by root on Mon Apr 27 14:38:36 CST 2015


8\  可以配置记住密码 
但是好像不起作用???

查看任务详细或者执行任务的时候不输入密码 免密
[sqoop-site.xml]
添加:
<property>
<name>sqoop.metastore.client.record.password</name>
<value>true</value>
<description>If true, allow saved passwords in the metastore.</description>
</property>

4. 基本使用

1
2
1) sqoop help : 查看帮助
2) sqoop help import : 进一步层级查看

5. Sqoop 数据导入

常用指令
1
2
3
4
5
6
7
8
9
10
--connect			指定数据库链接url
--username 指定数据库的用户名
--password 指定数据库的密码
--table 指定要导出数据的mysql数据库表
-m 指定MapTask的个数
--target-dir 指定导出数据在HDFS上的存储目录
--fields-terminated-by 指定每条记录中字段之间的分隔符
--where 指定查询SQL的where条件
--query 指定查询SQL
--columns 指定查询列

5.1 list mysql 的数据库 & 表, 复制mysql 中表结构相同表 –> hive

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
列出MySQL数据有哪些数据库:

sqoop list-databases \
--connect jdbc:mysql://cs2:3306/ \
--username root \
--password 123

列出MySQL中的某个数据库有哪些数据表:

sqoop list-tables \
--connect jdbc:mysql://cs2:3306/mysql \
--username root \
--password 123

创建一张跟mysql中的help_keyword表一样的hive表hk:(没有数据貌似)

sqoop create-hive-table \
--connect jdbc:mysql://cs2:3306/mysql \
--username root \
--password 123 \
--table help_keyword \
--hive-table hk

5.2 导入 mysql中表 到 HDFS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

导入MySQL表中数据到HDFS中:

// 普通导入:导入mysql库中的help_keyword的数据到HDFS上的默认路径:/user/ap/help_keyword
sqoop import \
--connect jdbc:mysql://cs2:3306/mysql \
--username root \
--password 123 \
--table help_keyword \
-m 1

最后的1,是指使用1个 mapTask
导入到hdfs后, 可以使用 hdfs dfs -text /.... 查看数据
----


// 导入: 指定分隔符 & 导入路径 & mapTask 个数

sqoop import \
--connect jdbc:mysql://cs2:3306/mysql \
--username root \
--password 123 \
--table help_keyword \
--target-dir /user/ap/my_help_keyword1 \
--fields-terminated-by '\t' \
-m 3


// 导入数据:带where条件

sqoop import \
--connect jdbc:mysql://cs2:3306/mysql \
--username root \
--password 123 \
--where "name='STRING' " \
--table help_keyword \
--target-dir /user/ap/my_help_keyword2 \
-m 1


// 查询指定列
-------------发现一个结论, 如果启动3个 mapper, 但是最后只有一个结论, 只会生成一个结果文件

sqoop import \
--connect jdbc:mysql://cs2:3306/mysql \
--username root \
--password 123 \
--columns "name" \
--where "name='STRING' " \
--table help_keyword \
--target-dir /user/ap/my_help_keyword3 \
-m 3


// 导入:指定自定义查询SQL
--------------疑点: split-by 的作用, 和 -m 数量的关系

sqoop import \
--connect jdbc:mysql://cs2:3306/mysql \
--username root \
--password 123 \
--target-dir /user/ap/my_help_keyword4 \
--query 'select help_keyword_id,name from help_keyword WHERE $CONDITIONS and name = "STRING"' \
--split-by help_keyword_id \
--fields-terminated-by '\t' \
-m 1

----------------------------
sqoop import \
--connect jdbc:mysql://cs2:3306/mysql \
--username root \
--password 123 \
--target-dir /user/hadoop/my_help_keyword5 \
--query "select help_keyword_id,name from help_keyword WHERE \$CONDITIONS" \
--split-by help_keyword_id \
--fields-terminated-by '\t' \
-m 1

# 在以上需要按照自定义SQL语句导出数据到HDFS的情况下:
1、引号问题,要么外层使用单引号,内层使用双引号,$CONDITIONS的$符号不用转义, 要么外层使用双引号,那么内层使用单引号,然后$CONDITIONS的$符号需要转义
2、自定义的SQL语句中必须带有WHERE \$CONDITIONS

5.3 导入MySQL数据库中的表数据到Hive中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

导入MySQL数据库中的表数据到Hive中:

// 普通导入:数据存储在默认的default hive库中,表名就是对应的mysql的表名:
// 通过对比发现, sqoop 是默认导入到 hdfs 的, 导入到hdfs时, 不用加额外的参数

sqoop import \
--connect jdbc:mysql://cs2:3306/mysql \
--username root \
--password 123 \
--table help_keyword \
--hive-import \
-m 1

hadoop fs -cat /user/myhive/warehouse/help_keyword/part-m-00000 // 查看数据
当然也可以在 hive 中查看数据

// 指定行分隔符和列分隔符,指定hive-import,指定覆盖导入,指定自动创建hive表,指定表名,指定删除中间结果数据目录

Database does not exist: mydb_test ???
注意: 要先创建 database mydb_test
问题: 为什么导出后, 变成了4个块


sqoop import \
--connect jdbc:mysql://cs2:3306/mysql \
--username root \
--password 123 \
--table help_keyword \
--fields-terminated-by "\t" \
--lines-terminated-by "\n" \
--hive-import \
--hive-overwrite \
--create-hive-table \
--delete-target-dir \
--hive-database mydb_test \
--hive-table new_help_keyword

另外一种写法:
sqoop import \
--connect jdbc:mysql://cs2:3306/mysql \
--username root \
--password 123 \
--table help_keyword \
--fields-terminated-by "\t" \
--lines-terminated-by "\n" \
--hive-import \
--hive-overwrite \
--create-hive-table \
--hive-table mydb_test.new_help_keyword1 \
--delete-target-dir

5.4 增量导入到 HDFS

—-应该也是可以导入到 Hive

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

第三部分:增量导入

Incremental import arguments:
--check-column <column> Source column to check for incremental
change 原始的列作为增长改变的
--incremental <import-type> Define an incremental import of type
'append' or 'lastmodified'
--last-value <value> Last imported value in the incremental
check column

比较使用于自增长主键!!



// 增量导入


sqoop import \
--connect jdbc:mysql://cs2:3306/mysql \
--username root \
--password 123 \
--table help_keyword \
--target-dir /user/ap/my_help_keyword_import1 \
--incremental append \
--check-column help_keyword_id \
--last-value 500 \
-m 3

5.5 第四部分: 导入数据到HBase

1
2
3
4
5
6
7
8
9
10
11
12
13
14

第四部分: 导入数据到HBase


导入MySQL数据库中的表数据到HBase中:

sqoop import \
--connect jdbc:mysql://cs2:3306/mysql \
--username root \
--password 123 \
--table help_keyword \
--hbase-table new_help_keyword \
--column-family person \
--hbase-row-key help_keyword_id

5.6 导出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

第五部分:导出:


注意:导出的RDBMS的表必须自己预先创建,不会自动创建
------mysql-----先在 mysql 中创建库
create database sqoopdb default character set utf8 COLLATE utf8_general_ci;
use sqoopdb;
CREATE TABLE sqoopstudent (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(20),
sex VARCHAR(20),
age INT,
department VARCHAR(20)
);


// 导出HDFS数据到MySQL:


sqoop export \
--connect jdbc:mysql://cs2:3306/sqoopdb \
--username root \
--password 123 \
--table sqoopstudent \
--export-dir /sqoopdata \
--fields-terminated-by ','


// 导出hive数据到MySQL:
sqoop export \
--connect jdbc:mysql://cs2:3306/sqoopdb \
--username root \
--password 123 \
--table uv_info \
--export-dir /user/hive/warehouse/uv/dt=2011-08-03 \
--input-fields-terminated-by '\t'

5.6 导出HBase数据到MySQL

很遗憾,现在还没有直接的命令将 HBase 的数据导出到 MySQL

一般采用如下 3 种方法:

1、将 HBase 数据,扁平化成 HDFS 文件,然后再由 sqoop 导入

2、将 HBase 数据导入 Hive 表中,然后再导入 MySQL

3、直接使用 HBase 的 Java API 读取表数据,直接向 MySQL 导入,不需要使用 sqoop

5.7 sqoop 支持 & 不支持

hdfs to mysql 可以直接使用。!!
hive to mysql 就是hdfs to mysql
hbase to mysql 很不幸,不支持。!

怎么实现?

1、扁平化到HDFS
2、hbase和hive做整合
3、自己编写程序去实现从HBASE当中读取数据,然后写入到mYsql

6.Sqoop Job 作业

查看帮助:

sqoop help job

6.0 mysql 创建数据库 spider 和 表 lagou

1
2
# 这样可以直接导入 sql 数据
source /home/ap/temp/lagou.sql

6.1 创建作业 Job (–create)

1
2
3
4
5
6
7
8
9
# 注意: mysql 中此时已经存在 spider 库, 库中有 lagou 表
# ps: 导入表

sqoop job --create my_sqoop_job \
-- import \
--connect jdbc:mysql://cs2:3306/spider \
--username root \
--password 123 \
--table lagou

6.2 查看作业 Job (–list)

1
2
3
4
sqoop job --list
----------------------
Available jobs:
my_sqoop_job

6.3 查看作业详细信息 (–show)

1
sqoop job --show my_sqoop_job

6.4 执行作业

1
sqoop job --exec my_sqoop_job

6.5 删除作业

1
sqoop job --delete my_sqoop_job

7.Sqoop 导入导出原理

7.1 导入原理

image-20180629172721667

1、第一步,Sqoop 会通过 JDBC 来获取所需要的数据库元数据,例如,导入表的列名,数据 类型等。

2、第二步,这些数据库的数据类型(varchar, number 等)会被映射成 Java 的数据类型(String, int 等),根据这些信息,Sqoop 会生成一个与表名同名的类用来完成序列化工作,保存表中的 每一行记录。

3、第三步,Sqoop 启动 MapReducer 作业

4、第四步,启动的作业在 input 的过程中,会通过 JDBC 读取数据表中的内容,这时,会使 用 Sqoop 生成的类进行反序列化操作

5、第五步,最后将这些记录写到 HDFS 中,在写入到 HDFS 的过程中,同样会使用 Sqoop 生 成的类进行反序列化

7.2 导出原理

image-20180629172706382

1、 第一步,sqoop 依然会通过 JDBC 访问关系型数据库,得到需要导出数据的元数据信息

2、 第二步,根据获取到的元数据的信息,sqoop 生成一个 Java 类,用来进行数据的传输载

体。该类必须实现序列化和反序列化

3、 第三步,启动 mapreduce 作业

4、 第四步,sqoop 利用生成的这个 java 类,并行的从 hdfs 中读取数据

5、 第五步,每个 map 作业都会根据读取到的导出表的元数据信息和读取到的数据,生成一 批 insert 语句,然后多个 map 作业会并行的向数据库 mysql 中插入数据

所以,数据是从 hdfs 中并行的进行读取,也是并行的进入写入,那并行的读取是依赖 hdfs 的性能,而并行的写入到 mysql 中,那就要依赖于 mysql 的写入性能嘞。

官网:

参考PDF:

如果帮到你, 可以给我赞助杯咖啡☕️
0%