Sqoop数据迁入迁出实战

一Sqoop是什么

   Sqoop是一种用于在Hadoop和关系数据库(RDBMS,如MySQL或Oracle)之间传输数据的工具,使用Sqoop可以批量将数据从关系数据库导入到Hadoop分布式文件系统(HDFS)及其相关系统(如HBase和Hive)中,也可以把Hadoop文件系统及其相关系统中的数据导出到关系数据库中,如下图:

 

                                                  

Sqoop基本架构

Sqoop是使用Java语言编写的,Sqoop的架构非常简单,整合了HDFS,HBase和Hive。底层使用MapReduce进行数据传递,从而提供并进行操作和容错功能,如下图:

 

                                                   

Sqoop接收到客户端的请求命令后,通过命令翻译器(Task Translater)将命令转换为对应的MapReduce任务,然后通过MapReduce任务将数据在RDBMS和Hadoop系统之间进行导入与导出。

Sqoop导入操作的输入是一个RDBMS数据库表,输出是包含表数据的一系列HDFS文件。导入操作是并行的,可以同时启动多个map任务,每个map任务分别逐行读取表中的一部分数据,并且将这部分数据输出到一个HDFS文件中(即一个map任务对应一个HDFS文件)。

Sqoop导出操作是将数据从HDFS或者Hive导出到关系型数据库中。导出过程并行地读取HDFS上的文件,将每一行内容转化成一条记录添加到关系型数据库表中。除了导入和导出操作,Sqoop还可以查询数据库结构和表信息等。

 

二Sqoop开发流程

     在实际开发中,若数据存储于关系型数据库中,当数据量达到一定规模后需要对其进行分析或统计,此时关系型数据库可能称为瓶颈,这时可以将数据从关系型数据库中导入到HBase中,而后通过数据仓库Hive对HBase中的数据进行统计与分析,并将分析结果存入到Hive表中。最后通过Sqoop将分析结果导出到关系型数据库中作为业务的辅助数据或用于Web页面的展示。

     Sqoop的业务开发流程如图所示:

 

                                                    

                            使用Sqoop

要使用Sqoop,需要指定要使用的工具和控制工具的参数。

可以通过进入Sqoop安装目录运行bin/sqoop命令来运行Sqoop。

$ sqoop tool-name [tool-arguments]

Sqoop内置了很多工具,可以通过执行以下命令,显示所有可用工具的列表:

$ sqoop help

常用工具及解析如下:

codegen      生成与数据库记录交互的代码

create-hive-table  导入表的结构到Hive中

eval    执行SQL语句并返回结果

export  导出HDFS目录中的文件数据到数据库表中

help 列出所有可用的工具

import 导入数据库表数据到HDFS中

import-all-tables  导入数据库所有表数到HDFS中

list-databases  列出所有可用数据库

list-tables  列出数据库中所有可用表

version     显示版本信息

 

也可以执行sqoop help (tool-name)来显示特定工具的帮助信息,例如sqoop help import。还可以将--help参数添加到任何命令,例如sqoop import --help

Sqoop的导入和导出操作主要使用import工具和export工具。这两个工具提供了很多参数帮助我们完成数据的迁移和同步。两个工具中都包含的一些通用参数,如下表所示

 

参数

含义

--connect<jdbc-url>

指定JDBC连接字符串

--connection-manager<class-name>

指定要使用的连接管理器类

--driver<class-name>

指定要使用的JDBC驱动类

--hadoop-mapred-home<dir>

指定$HADOOP_MAPRED_HOME路径(MapReduce主目录)

--password-file

设置用于存放认证的密码信息文件的路径

-P (大写的p)

从控制台读取设置输入的密码

--password<password>

设置认证密码

--username<username>

设置认证用户名

--verbose

打印详细的运行信息

--connection-param-file<filename>

指定存储数据库连接参数的属性文件(可选)

                

案例分析一:将mysql表数据导入到HDFS中

创建数据库create databases hdfs_hive;  该数据用于实现mysql表数据导入到hdfs分布式文件系统中。

在MySQL中创建数据库hdfs_hive,并在该表中创建表user_info

SET FOREIGN_KEY_CHECKS=0;

 

-- ----------------------------

-- Table structure for user_info

-- ----------------------------

DROP TABLE IF EXISTS `user_info`;

CREATE TABLE `user_info` (

  `userId` int(20) NOT NULL AUTO_INCREMENT,

  `userName` varchar(100) DEFAULT NULL,

  `password` varchar(50) DEFAULT NULL,

  `trueName` varchar(50) DEFAULT NULL,

  `addedTime` date DEFAULT NULL,

  PRIMARY KEY (`userId`)

) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

 

-- ----------------------------

-- Records of user_info

-- ----------------------------

INSERT INTO `user_info` VALUES ('1', '杨洪', '1234565yanghong', 'yanghong', '2020-03-31');

INSERT INTO `user_info` VALUES ('2', '张三', '312321321zhangsan', 'zhangsan', '2020-03-31');

INSERT INTO `user_info` VALUES ('3', '李四', '423432lisi', 'lisi', '2020-03-10');

INSERT INTO `user_info` VALUES ('4', '王五', '234324wangwu', 'wangwu', '2020-03-06');

下面将使用sqoop将表user_info中的数据导入到hdfs中,步骤如下。

1启动Hadoop

在导入数据之前,需要先启动Hadoop集群。执行如下命令,启动Hadoop:

$ start-all.sh

2执行导入命令

执行如下命令,使用Sqoop连接mysql并将表数据到导入到HDFS中

sqoop import \

 --connect 'jdbc:mysql://ip:3306/hdfs_hive?characterEncoding=UTF-8' \

 --username root \

 --password 123456 \

 --table user_info \

 --columns userId,userName,password,trueName,addedTime \

 --target-dir /sqoop/mysql

 

需要注意的是,”\”后面紧跟回车,表示当前行下一行的续行.

上述代码中各参数含义如下:

--connect:  数据库连接URL

--username:  数据库连接用户名

--password:  数据库密码

--table:  数据库表名

--columns:  数据库列名

--target-dir:数据在HDFS中存放目录。如果HDFS中没有该目录则会自动生成.

20/03/31 21:11:29 INFO mapreduce.Job:  map 0% reduce 0%

20/03/31 21:11:38 INFO mapreduce.Job:  map 25% reduce 0%

20/03/31 21:11:39 INFO mapreduce.Job:  map 50% reduce 0%

20/03/31 21:11:50 INFO mapreduce.Job:  map 75% reduce 0%

20/03/31 21:11:53 INFO mapreduce.Job:  map 100% reduce 0%

20/03/31 21:11:53 INFO mapreduce.Job: Job job_1585649819788_0001 completed successfully

 

3查看导入结果

执行下面的命令,查看HDFS中的/sqoop/mysql目录下生成的文件:

$ hadoop fs  -ls /sqoop/mysql

 

-rw-r--r--   3 hadoop supergroup          0 2020-03-31 21:11 /sqoop/mysql/_SUCCESS

-rw-r--r--   3 hadoop supergroup         45 2020-03-31 21:11 /sqoop/mysql/part-m-00000

-rw-r--r--   3 hadoop supergroup         47 2020-03-31 21:11 /sqoop/mysql/part-m-00001

-rw-r--r--   3 hadoop supergroup         36 2020-03-31 21:11 /sqoop/mysql/part-m-00002

-rw-r--r--   3 hadoop supergroup         40 2020-03-31 21:11 /sqoop/mysql/part-m-00003

可以看出数据库中的四条数据存储为四个文件,一个文件对应一条数据

执行如下命令,查看/sqoop/mysql/目录下的所有文件的内容:

$ hadoop fs -cat /sqoop/mysql/*

1,杨洪,1234565yanghong,yanghong,2020-03-31

2,张三,312321321zhangsan,zhangsan,2020-03-31

3,李四,423432lisi,lisi,2020-03-10

4,王五,234324wangwu,wangwu,2020-03-06

案例分析二:将HDFS中的数据导出到MySQL中

1在hdfs_hive数据库中创建一个临时表user_info_tmp,字段及类型与表user_info相同,如下:

CREATE TABLE `user_info_tmp` (

  `userId` int(20) NOT NULL AUTO_INCREMENT,

  `userName` varchar(100) DEFAULT NULL,

  `password` varchar(50) DEFAULT NULL,

  `trueName` varchar(50) DEFAULT NULL,

  `addedTime` date DEFAULT NULL,

  PRIMARY KEY (`userId`)

) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

2执行导出命令

执行以下命令,将HDFS文件系统/sqoop/mysql/下的文件中的内容导出到表user_info_tmp中:

sqoop export \

 --connect 'jdbc:mysql://ip:3306/hdfs_hive?characterEncoding=UTF-8' \

 --username root \

 --password 123456 \

 --table user_info_tmp \

 --export-dir /sqoop/mysql/*

 

也可以一条一条数据导入

上述代码中各个参数的含义如下:

--table: 目标数据所在的表的名称

--export-dir:  源数据所在的位置

执行成功后输出的部分日志如下:

20/03/31 21:41:44 INFO mapreduce.Job:  map 0% reduce 0%

20/03/31 21:41:51 INFO mapreduce.Job:  map 100% reduce 0%

20/03/31 21:41:51 INFO mapreduce.Job: Job job_1585649819788_0002 completed successfully

案例分析三:将MySQL表数据导入到HBase中,步骤如下

本例使用sqoop将MySQL中的表user_info的数据导入到HBase中,操作步骤如下。

1启动HBase集群

执行以下命令,启动HBase集群:

start-hbase.sh

新建HBase表,列族为baseinfo:

create 'user_info','baseinfo' 

2修改Sqoop配置文件

修改sqoop-env.sh文件,指定HBase的安装目录:

export HBASE_HOME=/home/hadoop/hbase/hbase-1.4.11

3执行以下命令,将MySQL中的数据导入到HBase中:

 bin/sqoop import \

 --connect 'jdbc:mysql://ip:3306/hdfs_hive?characterEncoding=UTF-8' \

 --username root --password 123456 \

 --query "select * from user_info where 1=1 and \$CONDITIONS" \

 --hbase-table user_info \

 --column-family baseinfo \

 --hbase-row-key userId \

 --split-by addedTime \

 --m 2

上述代码中各项参数含义如下:

--query: 指定导入数据的查询条件.

--hbase-table: 指定要导入的HBase中的表名

--column-family: 指定导入的HBase表的列族

--hbase-row-key: 指定MYSQL中的某一列作为HBase表中的rowkey

--split-by: 指定数据库中的某一列作为分区拆分列。默认是主键列(如果存在)。如果主键的实践值不在其范围内均匀分布,那么这可能导致任务分配不平衡。此时应该显式地选择一个具有--split-by参数列

--m: 指定导入过程使用的map任务的数量(并行进程的数量)。若不指定该参数,默认使用4个map任务。一些数据库可以通过将该值增加到8或者16来提高性能,但注意不要增加超过MapReduce集群中可用的并行度。该参数与-m和--num-mappers具有同样的效果。

成功日志:

20/04/01 17:34:36 INFO mapreduce.Job:  map 0% reduce 0%

20/04/01 17:34:45 INFO mapreduce.Job:  map 50% reduce 0%

20/04/01 17:34:46 INFO mapreduce.Job:  map 100% reduce 0%

20/04/01 17:34:46 INFO mapreduce.Job: Job job_1585649819788_0012 completed successfully

查看导入的结果

进入HBase Shell,执行scan ‘user_info’命令,扫描user_info表中的数据:

hbase(main):012:0> scan 'user_info'

ROW                                                                  COLUMN+CELL                                                                                                                                                                                              

 1                                                                   column=baseinfo:addedTime, timestamp=1585733684452, value=2020-03-31                                                                                                                                     

 1                                                                   column=baseinfo:password, timestamp=1585733684452, value=1234565yanghong                                                                                                                                 

 1                                                                   column=baseinfo:trueName, timestamp=1585733684452, value=yanghong                                                                                                                                        

 1                                                                   column=baseinfo:userName, timestamp=1585733684452, value=\xE6\x9D\xA8\xE6\xB4\xAA                                                                                                                        

 2                                                                   column=baseinfo:addedTime, timestamp=1585733684452, value=2020-03-31                                                                                                                                     

 2                                                                   column=baseinfo:password, timestamp=1585733684452, value=312321321zhangsan                                                                                                                               

 2                                                                   column=baseinfo:trueName, timestamp=1585733684452, value=zhangsan                                                                                                                                        

 2                                                                   column=baseinfo:userName, timestamp=1585733684452, value=\xE5\xBC\xA0\xE4\xB8\x89                                                                                                                        

 3                                                                   column=baseinfo:addedTime, timestamp=1585733684216, value=2020-03-10                                                                                                                                     

 3                                                                   column=baseinfo:password, timestamp=1585733684216, value=423432lisi                                                                                                                                      

 3                                                                   column=baseinfo:trueName, timestamp=1585733684216, value=lisi                                                                                                                                            

 3                                                                   column=baseinfo:userName, timestamp=1585733684216, value=\xE6\x9D\x8E\xE5\x9B\x9B                                                                                                                        

 4                                                                   column=baseinfo:addedTime, timestamp=1585733684216, value=2020-03-06                                                                                                                                     

 4                                                                   column=baseinfo:password, timestamp=1585733684216, value=234324wangwu                                                                                                                                    

 4                                                                   column=baseinfo:trueName, timestamp=1585733684216, value=wangwu                                                                                                                                          

 4                                                                   column=baseinfo:userName, timestamp=1585733684216, value=\xE7\x8E\x8B\xE4\xBA\x94  

从以上的结果可以看到,四条数据已经成功导入。

如果修改user_info中的数据,重新导入,则会更新替换HBase中相同rowkey对应行的数据。

目前暂不支持将HBase中的数据导出到MySQL,但可以先将HBase中的数据导出到HDFS或者Hive中,再将数据导出到MySQL。

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值