(超详细)数据转换工具Sqoop的实战

数据转换工具Sqoop的安装与实战操作

JunLeon——go big or go home


目录

数据转换工具Sqoop的安装与实战操作

一、Sqoop的概述

1、什么是Sqoop?

2、Sqoop的功能与特性

二、Sqoop的环境搭建

1、环境准备

2、安装配置

3、sqoop测试

扫描二维码关注公众号,回复: 15232741 查看本文章

三、Sqoop实战

1、Sqoop命令及参数

2、Sqoop数据导入

3、Sqoop数据导出

4、问题解决


 前言:

        随着Hadoop大数据平台的广泛应用,用户将数据集在Hadoop和传统数据库之间转移的需求也越来越大。传统ETL工具对于Hadoop平台的兼容性相对不高,所以Apache推出了Sqoop,它可以在Hadoop和关系型数据库之间转移数据。Sqoop项目开始于2009年,最早是作为Hadoop的第三方模块存在,后来为了让使用者能够快速部署,开发人员能够更快速地迭代开发,Sqoop独立成为一个Apache项目,并于2012年成为顶级项目。

        Sqoop用于在结构化数据存储和Hadoop大数据平台(如大型主机或关系型数据库MySQL、Oracle、Postgres等)之间高效传输批量数据。用户可以使用Sqoop将数据从外部结构化数据存储导入Hadoop平台,如Hive和HBase。同时,Sqoop也可用于从Hadoop中提取数据,并将其导出到外部结构化数据存储(如关系型数据库和企业数据仓库)

一、Sqoop的概述

1、什么是Sqoop?

        Sqoop 是 SQL to Hadoop 的缩写,是一款开源、免费的数据转换工具,主要用在 Hadoop 与传统关系数据库之间进行高效块数据的转移。可以将一个关系数据库中的数据导入到 Hadoop 的 HDFS 文件系统、 HBase 数据库、 Hive 数据仓库中,也可以将 Hadoop 的数据导入到关系数据库中。

2、Sqoop的功能与特性

(1)Sqoop的功能

        Sqoop是Hadoop中简单高效的数据传输工具。主要功能为以下两个。

import : RDBMS-->Hadoop

  • 将数据从关系型数据库或大型主机导入到Hadoop平台,导入进程中的输入内容是数据库表或主机数据集。对于数据库,Sqoop将逐行读取表格到Hadoop。对于主机数据集,Sqoop将从每个主机数据集读取记录到HDFS。导入过程的输出是一组文件,其中包含导入的表或数据集的副本。导入过程是并行执行的。因此,输出将在多个文件中产生。

    export: Hadoop -- > RDBMS

  • 将数据从Hadoop平台导出到关系数据库或大型主机,Sqoop的导出过程会并行地从HDFS读取所需数据,将它们解析为记录,如果导出到数据库,则将它们作为新行插入到目标数据库表中,如果导出到大型主机,则直接形成数据集,供外部应用程序或用户使用。

        用户使用Sqoop时,只需要通过简单的命令进行操作,Sqoop会自动化数据传输中的大部分过程。Sqoop使用MapReduce导入和导出数据,提供并行操作和容错功能。 在使用Sqoop的过程中,用户可以定制导入、导出过程的大多数方面,可以控制导入的特定行范围或列,也可以为数据的基于文件的表示以及所使用的文件格式指定特定的分隔符和转义字符。

(2)Sqoop的特性

        Sqoop专门用于Hadoop平台与外部数据源的数据交互,对Hadoop生态系统是一个有力的补充。Sqoop具有以下特性。

  • 并行处理

    Sqoop充分利用了MapReduce的并行特点,以批处理的方式加快数据的传输,同时也借助MapReduce实现了容错。

  • 适用性高

    通过JDBC接口和关系型数据库进行交互,理论上支持JDBC接口的数据库都可以使用Sqoop和Hadoop进行数据交互。

  • 使用简单

    用户通过命令行的方式对Sqoop进行操作,一共只有15条命令。其中13条命令用于数据处理,操作简单,用户可以轻松地完成Hadoop与RDBMS的数据交互。

二、Sqoop的环境搭建

1、环境准备

(1)sqoop下载

官方下载:Index of /dist/sqoop

注:Sqoop 分为 1.x 和 2.x 两个版本序列 (称为 Sqoop1 和 Sqoop2)二者完全不兼容,当前 Sqoop1 的最新稳定版本为 1.4.7,故下载 sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz 即可。

(2)上传至虚拟机Hadoop集群的主节点

使用XShell或者其他远程连接工具将下载好的sqoop压缩包上传Hadoop主节点的虚拟机的/opt目录中,方便接下来的安装。

2、安装配置

(1)解压上传的压缩包

cd /opt
# 如果压缩包不在/opt目录中,则需要使用[-C /opt]指定解压到/opt目录下
[root@BigData01 opt]# tar -zxvf sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz    # 解压压缩包
[root@BigData01 opt]# mv sqoop-1.4.7.bin__hadoop-2.6.0 sqoop-1.4.7      # 更改sqoop安装的目录名

(2)配置Sqoop

1.配置环境变量

vi /etc/profile

export SQOOP_HOME=/opt/sqoop-1.4.7
export PATH=$SQOOP_HOME/bin:$PATH

使环境变量配置生效:

source /etc/profile

2.配置sqoop-env.sh文件

复制模板文件:

[root@BigData01 conf]# cd $SQOOP_HOME/conf
[root@BigData01 conf]# cp sqoop-env-template.sh sqoop-env.sh

配置:vi sqoop-env.sh

#Set path to where bin/hadoop is available
export HADOOP_COMMON_HOME=/opt/hadoop-2.7.3
​
#Set path to where hadoop-*-core.jar is available
export HADOOP_MAPRED_HOME=/opt/hadoop-2.7.3
​
#set the path to where bin/hbase is available
export HBASE_HOME=/opt/hbase-1.4.13
​
#Set the path to where bin/hive is available
export HIVE_HOME=/opt/hive-2.3.3
​
#Set the path for where zookeper config dir is
export ZOOCFGDIR=/opt/zookeeper-3.4.12

(3)复制MySQL驱动包到$SQ OOP_HOME/lib目录下

1.上传MySQL驱动包

将MySQL驱动包 mysql-connector-java-5.1.49.jar 上传至/opt目录下

2.复制到$SQOOP_HOME/lib目录下

cd /opt
cp mysql-connector-java-5.1.49.jar $SQOOP_HOME/lib/

3、sqoop测试

(1)启动MySQL服务

systemctl start mysqld      # CentOS 7 启动MySQL服务
service mysqld start        # CentOS 6 启动MySQL服务

(2)测试--连接MySQL

[root@BigData01 ~]# sqoop list-databases --connect jdbc:mysql://localhost:3306/ --username root -P  

三、Sqoop实战

1、Sqoop命令及参数

(1)sqoop命令

序号 命令 说明
1 import ImportTool 将数据导入到集群
2 export ExportTool 将集群数据导出
3 codegen CodeGenTool 获取数据库中某张表数据生成Java并打包Jar
4 create-hive-table CreateHiveTableTool 创建Hive表
5 eval EvalSqlTool 查看SQL执行结果
6 import-all-tables ImportAllTablesTool 导入某个数据库下所有表到HDFS中
7 job JobTool 用来生成一个sqoop的任务,生成后,该任务并不执行,除非使用命令执行该任务。
8 list-databases ListDatabasesTool 列出所有数据库名
9 list-tables ListTablesTool 列出某个数据库下所有表
10 merge MergeTool 将HDFS中不同目录下面的数据合在一起,并存放在指定的目录中
11 metastore MetastoreTool 记录sqoop job的元数据信息,如果不启动metastore实例,则默认的元数据存储目录为:~/.sqoop,如果要更改存储目录,可以在配置文件sqoop-site.xml中进行更改。
12 help HelpTool 打印sqoop帮助信息
13 version VersionTool 打印sqoop版本信息

(2)公用参数:数据库连接

序号 参数 说明
1 --connect 连接关系型数据库的URL
2 --connection-manager 指定要使用的连接管理类
3 --driver Hadoop根目录
4 --help 打印帮助信息
5 --password 连接数据库的密码
6 --username 连接数据库的用户名
7 --verbose 在控制台打印出详细信息

(3)公用参数:import

序号 参数 说明
1 --enclosed-by <char> 给字段值前加上指定的字符
2 --escaped-by <char> 对字段中的双引号加转义符
3 --fields-terminated-by <char> 设定每个字段是以什么符号作为结束,默认为逗号
4 --lines-terminated-by <char> 设定每行记录之间的分隔符,默认是\n
5 --mysql-delimiters Mysql默认的分隔符设置,字段之间以逗号分隔,行之间以\n分隔,默认转义符是\,字段值以单引号包裹。
6 --optionally-enclosed-by <char> 给带有双引号或单引号的字段值前后加上指定字符。

(4)公用参数:export

序号 参数 说明
1 --input-enclosed-by <char> 对字段值前后加上指定字符
2 --input-escaped-by <char> 对含有转移符的字段做转义处理
3 --input-fields-terminated-by <char> 字段之间的分隔符
4 --input-lines-terminated-by <char> 行之间的分隔符
5 --input-optionally-enclosed-by <char> 给带有双引号或单引号的字段前后加上指定字符

(5)公用参数:hive

序号 参数 说明
1 --hive-delims-replacement <arg> 用自定义的字符串替换掉数据中的\r\n和\013 \010等字符
2 --hive-drop-import-delims 在导入数据到hive时,去掉数据中的\r\n\013\010这样的字符
3 --map-column-hive <arg> 生成hive表时,可以更改生成字段的数据类型
4 --hive-partition-key 创建分区,后面直接跟分区名,分区字段的默认类型为string
5 --hive-partition-value <v> 导入数据时,指定某个分区的值
6 --hive-home <dir> hive的安装目录,可以通过该参数覆盖之前默认配置的目录
7 --hive-import 将数据从关系数据库中导入到hive表中
8 --hive-overwrite 覆盖掉在hive表中已经存在的数据
9 --create-hive-table 默认是false,即,如果目标表已经存在了,那么创建任务失败。
10 --hive-table 后面接要创建的hive表,默认使用MySQL的表名
11 --table 指定关系数据库的表名

(6)Sqoop-Hive命令及参数

命令&参数:create-hive-table

生成与关系数据库表结构对应的hive表结构。

命令:

如:

sqoop create-hive-table --connect jdbc:mysql://localhost:3306/company \
    --username root --password 'root123456' \
    --table staff --hive-table hive_staff

参数:

序号 参数 说明
1 --hive-home <dir> Hive的安装目录,可以通过该参数覆盖掉默认的Hive目录
2 --hive-overwrite 覆盖掉在Hive表中已经存在的数据
3 --create-hive-table 默认是false,如果目标表已经存在了,那么创建任务会失败
4 --hive-table 后面接要创建的hive表
5 --table 指定关系数据库的表名

命令&参数:eval

可以快速的使用SQL语句对关系型数据库进行操作,经常用于在import数据之前,了解一下SQL语句是否正确,数据是否正常,并可以将结果显示在控制台。

命令:

如:

sqoop eval \--connect jdbc:mysql://localhost:3306/company \--username root \--password 'root123456' \--query "SELECT * FROM staff"

参数:

序号 参数 说明
1 --query或--e 后跟查询的SQL语句

命令&参数:import-all-tables

可以将RDBMS中的所有表导入到HDFS中,每一个表都对应一个HDFS目录

命令:

如:

sqoop import-all-tables --connect jdbc:mysql://hadoop102:3306/company \
    --username root --password 'root123456' \
    --warehouse-dir /all_tables 

参数:

序号 参数 说明
1 --as-avrodatafile 这些参数的含义均和import对应的含义一致
2 --as-sequencefile
3 --as-textfile
4 --direct
5 --direct-split-size <n>
6 --inline-lob-limit <n>
7 --m或—num-mappers <n>
8 --warehouse-dir <dir>
9 -z或--compress
10 --compression-codec

命令&参数:job

用来生成一个sqoop任务,生成后不会立即执行,需要手动执行。

命令:

如:

sqoop job --create myjob -- import-all-tables \ 
    --connect jdbc:mysql://localhost:3306/company \ 
    --username root --password 'root123456'
sqoop job --list
sqoop job --exec myjob

提示:注意import-all-tables和它左边的--之间有一个空格

提示:如果需要连接metastore,则--meta-connect jdbc:hsqldb:hsql://BigData01:16000/sqoop

参数:

序号 参数 说明
1 --create <job-id> 创建job参数
2 --delete <job-id> 删除一个job
3 --exec <job-id> 执行一个job
4 --help 显示job帮助
5 --list 显示job列表
6 --meta-connect <jdbc-uri> 用来连接metastore服务
7 --show <job-id> 显示一个job的信息
8 --verbose 打印命令运行时的详细信息

提示:在执行一个job时,如果需要手动输入数据库密码,可以做如下优化

<property>
    <name>sqoop.metastore.client.record.password</name>
    <value>true</value>
    <description>If true, allow saved passwords in the metastore.</description>
</property>

命令&参数:list-databases

命令:

如:

sqoop list-databases --connect jdbc:mysql://localhost:3306/ \
    --username root --password 'root123456'

参数:与公用参数一样

命令&参数:list-tables

命令:

如:

sqoop list-tables --connect jdbc:mysql://localhost:3306/company \
    --username root --password 'root123456'

参数:与公用参数一样

2、Sqoop数据导入

登录MySQL准备数据:

[root@BigData01 ~]# mysql -u root -p    # 输入密码即可
mysql> CREATE DATABASE studentdb;       # 创建数据库studentdb
mysql> USE studentdb;       # 使用该数据库
mysql> CREATE TABLE student(id INT,name VARCHAR(25) NOT NULL,age INT);      # 创建表student
mysql> INSERT INTO student(id,name,age) VALUE(1001,'zhangsan',18),(1002,'lisi',19),(1003,'wangwu',20);      # 向student表插入数据
mysql> SELECT * FROM student;       # 查看该表的数据

(1)数据从MySQL导入到HDFS中

sqoop import --connect jdbc:mysql://localhost:3306/studentdb --username root --password 'root123456' --table student -m 1

(2)查看结果

默认存储的路径在HDFS中的 user/<用户>/<表名>/ 中,比如:当前用户为root,则实际路径为:/user/root/student/,会在该路径下生成part-m-00000的文件

[root@BigData01 ~]# hadoop fs -ls -R /user/root/
drwxr-xr-x   - root supergroup       0 2021-12-10 11:05 /user/root/student
-rw-r--r--   1 root supergroup       0 2021-12-10 11:05 /user/root/student/_SUCCESS
-rw-r--r--   1 root supergroup      45 2021-12-10 11:05 /user/root/student/part-m-00000

(3)其他参数导入

注1:“-Dorg.apache.sqoop.splitter.allow_text_splitter=true”参数表示——当表的主键字段不是自增id,而是字符类型时。

sqoop import -Dorg.apache.sqoop.splitter.allow_text_splitter=true --connect \
    jdbc:mysql://localhost:3306/studentdb --username root --password 'password' \
    --table student

注2:“--num-mappers 1”或者“-m 1”,即最后汇总为一个输出文件。

sqoop import -Dorg.apache.sqoop.splitter.allow_text_splitter=true --connect \
    jdbc:mysql://localhost:3306/studentdb --username root --password 'password' \
    --table student --num-mappers 1
sqoop import --connect jdbc:mysql://localhost:3306/studentdb \
    --username root --password 'password' --table student --num-mappers 1

注3:可以指定导入到指定目录下,需要带上“ --warehouse-dir ”参数,比如:

sqoop import -Dorg.apache.sqoop.splitter.allow_text_splitter=true --connect \
    jdbc:mysql://localhost:3306/studentdb --username root --password 'password' \
    --table student --warehouse-dir /user/sqoop

注4:默认以短号分隔,可以更换为以\t分隔数据(需带上“--fields-terminated-by ”参数)

sqoop import -Dorg.apache.sqoop.splitter.allow_text_splitter=true --connect \
    jdbc:mysql://localhost:3306/studentdb --username root --password 'password' \
    --table student --warehouse-dir /user/sqoop --fields-terminated-by '\t' -m1 

3、Sqoop数据导出

在本地准备文件上传至Hadoop的HDFS中

[root@BigData01 ~]# vi sqoopdata.txt    # 输入几行数据
103  wangwu      22
102  lisi        21 
101  zhangsan    20
[root@BigData01 ~]# hadoop fs -mkdir -p /user/data
[root@BigData01 ~]# hadoop fs -put sqoopdata.txt /user/data/

在MySQL中创建好Hadoop数据导出的表:

[root@BigData01 ~]# mysql -u root -p
Enter password:
​
mysql> create database testdb;
Query OK, 1 row affected (0.00 sec)
​
mysql> use testdb;
Database changed
​
mysql> create table student(id int,name varchar(25) not null,age int);
Query OK, 0 rows affected (0.03 sec)
​
mysql> quit;
Bye

在命令行中输入命令导出数据到指定的MySQL表中存储

[root@BigData01 ~]# sqoop export --connect jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8 \
 --username root --password 'root123456' --table student \
 --export-dir '/user/data/*' --fields-terminated-by '\t'

验证MySQL的表中是否有数据:

[root@BigData01 ~]# mysql -u root -p
Enter password:
​
mysql> use testdb;
Database changed
​
mysql> SELECT * FROM student;
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|  103 | wangwu   |   22 |
|  102 | lisi     |   21 |
|  101 | zhangsan |   20 |
+------+----------+------+
3 rows in set (0.00 sec)

4、问题解决

(1)当导出时出现如下类似错误

ERROR mapreduce.ExportJobBase: Export job failed!
ERROR tool.ExportTool: Error during export:
    Export job failed!
    at org.apache.sqoop.mapreduce.ExportJobBase.runExport(ExportJobBase.java:445)
    at org.apache.sqoop.manager.SqlManager.exportTable(SqlManager.java:931)
    at org.apache.sqoop.tool.ExportTool.exportTable(ExportTool.java:80)
    at org.apache.sqoop.tool.ExportTool.run(ExportTool.java:99)
    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)

解决办法:

a. 在MySQL中授权:

对其他节点添加了远程访问,但没有对自己添加远程访问权限。

grant all privileges on *.* to 'root'@'%' identified by 'password' with grant option; 
​
flush privileges;

单独添加对 BigData01 的远程访问权限

grant all privileges on *.* to 'root'@'BigData01' identified by 'password' with grant option;   
​
flush privileges;

b. jdbc连接不要使用localhost,可使用host名称或IP地址。

c. 注意:HDFS数据文件的字段值和MySQL的字段对应,且注意字段类型和字符串长度问题。

d. 输入数据字段分隔符,输出数据字段分隔符

e. 若数据中存在中文的,则考虑连接数据库参数中加入 永久设置MySQL字符编码 -- 解决jdbc数据导入由于存在中文字符出错问题!

sqoop export --connect "jdbc:mysql://BigData01:3306/testDB?useUnicode=true&characterEncoding=utf8mb4" \
    --username root -password 'root123456' --table Users --input-fields-terminated-by "," \
    --export-dir '/user/root/Users/part-m-00000' --fields-terminated-by ','

下一篇:日志采集工具Flume的实战(超详细)

如果你喜欢、对你有帮助,点赞+收藏,跟着军哥学知识……

猜你喜欢

转载自blog.csdn.net/JunLeon/article/details/122160032