基于传统关系型数据库的稳定性,还是有很多企业将数据存储在关系型数据库中;早期由于工具的缺乏,Hadoop与传统数据库之间的数据传输非常困难。基于前两个方面的考虑,需要一个在传统关系型数据库和Hadoop之间进行数据传输的项目,Sqoop应运而生。
Sqoop是一个用于Hadoop和结构化数据存储(如关系型数据库)之间进行高效传输大批量数据的工具。它包括以下两个方面:
Sqoop的核心设计思想是利用MapReduce加快数据传输速度。也就是说Sqoop的导入和导出功能是通过基于Map Task(只有map)的MapReduce作业实现的。所以它是一种批处理方式进行数据传输,难以实现实时的数据进行导入和导出。
参数 | 描述 |
---|---|
--connect <jdbc-uri> | 指定JDBC连接字符串 |
--username | 指定连接mysql用户名 |
--password | 指定连接mysql密码 |
参数 | 描述 |
---|---|
table <table name> | 抽取mysql数据库中的表 |
--target-dir <path> | 指定导入hdfs的具体位置。默认生成在为/user/<user>//目录下 |
-m <数值> | 执行map任务的个数,默认是4个 |
--direct | 可快速转换数据 |
将mysql数据库中的hive数据库中的roles表数据导入到HDFS中的/user/lyz/111目录下。执行代码如下:
sqoop import \
--connect jdbc:mysql://10.6.6.71:3309/hive \
--username root \
--password root123 \
--table roles \
--target-dir /user/lyz/111 \
--fields-terminated-by ',' \
-m 1 \
--direct
备注:-m参数可以指定map任务的个数,默认是4个。如果指定为1个map任务的话,最终生成的part-m-xxxxx文件个数就为1。在数据充足的情况下,生成的文件个数与指定map任务的个数是等值的。
参数 | 描述 |
---|---|
--hive-import | 将表导入Hive中 |
--hive-table <table name> | 指定导入Hive的表名 |
--fields-terminated-by <char> | 指定导入到hive中的文件数据格式 |
-m <数值> | 执行map任务的个数,默认是4个 |
--direct | 可快速转换数据 |
将mysql数据库中的hive数据库中的roles表数据导入到Hive数据库中,并生成roles_test表。执行代码如下:
sqoop import \
--connect jdbc:mysql://10.6.6.71:3309/hive \
--username root \
--password root123 \
--hive-import \
--table roles \
--hive-database default \
--hive-table roles_test \
--fields-terminated-by ',' \
-m 1 \
--direct
备注:-m参数可以指定map任务的个数,默认是4个。如果指定为1个map任务的话,最终生成在/apps/hive/warehouse/ roles_test目录下的part-m-xxxxx文件个数就为1。在数据充足的情况下,生成的文件个数与指定map任务的个数是等值的。
执行数据导入过程中,会触发MapReduce任务。任务执行成功以后,我们访问Hive验证一下数据是否导入成功。
hive> show tables;
OK
roles_test
hive> select * from roles_test;
OK
1 1545355484 admin admin
2 1545355484 public public
Time taken: 0.536 seconds, Fetched: 2 row(s)
数据导入成功。
参数 | 描述 |
---|---|
--column-family <family> | 设置导入的目标列族 |
--hbase-row-key <col> | 指定要用作行键的输入列;如果没有该参数,默认为mysql表的主键 |
--hbase-create-table | 如果执行,则创建缺少的HBase表 |
--hbase-bulkload | 启用批量加载 |
将mysql数据库中的hive数据库中的roles表数据导入到HBase中,并生成roles_test表。执行代码如下:
sqoop import \
--connect jdbc:mysql://10.6.6.71:3309/hive \
--username root \
--password root123 \
--table roles \
--hbase-table roles_test \
--column-family info \
--hbase-row-key ROLE_ID \
--hbase-create-table \
--hbase-bulkload
关于参数--hbase-bulkload的解释:
实现将数据批量的导入Hbase数据库中,BulkLoad特性能够利用MR计算框架将源数据直接生成内部的HFile格式,直接将数据快速的load到HBase中。
细心的你可能会发现,使用--hbase-bulkload参数会触发MapReduce的reduce任务。
执行数据导入过程中,会触发MapReduce任务。任务执行成功以后,我们访问HBase验证一下数据是否导入成功。
hbase(main):002:0> list
TABLE
roles_test
1 row(s) in 0.1030 seconds
=> ["roles_test"]
hbase(main):003:0> scan "roles_test"
ROW COLUMN+CELL
1 column=info:CREATE_TIME, timestamp=1548319280991, value=1545355484
1 column=info:OWNER_NAME, timestamp=1548319280991, value=admin
1 column=info:ROLE_NAME, timestamp=1548319280991, value=admin
2 column=info:CREATE_TIME, timestamp=1548319282888, value=1545355484
2 column=info:OWNER_NAME, timestamp=1548319282888, value=public
2 column=info:ROLE_NAME, timestamp=1548319282888, value=public
2 row(s) in 0.0670 seconds
总结:roles_test表的row_key是源表的主键ROLE_ID值,其余列均放入了info这个列族中。
Sqoop export工具将一组文件从HDFS导出回Mysql。目标表必须已存在于数据库中。根据用户指定的分隔符读取输入文件并将其解析为一组记录。
默认操作是将这些转换为一组INSERT将记录注入数据库的语句。在“更新模式”中,Sqoop将生成UPDATE替换数据库中现有记录的语句,并且在“调用模式”下,Sqoop将为每条记录进行存储过程调用。
将HDFS、Hive、HBase的数据导出到Mysql表中,都会用到下表的参数:
参数 | 描述 |
---|---|
--table <table name> | 指定要导出的mysql目标表 |
--export-dir <path> | 指定要导出的hdfs路径 |
--input-fields-terminated-by <char> | 指定输入字段分隔符 |
-m <数值> | 执行map任务的个数,默认是4个 |
首先在test数据库中创建roles_hdfs数据表:
USE test;
CREATE TABLE `roles_hdfs` (
`ROLE_ID` bigint(20) NOT NULL ,
`CREATE_TIME` int(11) NOT NULL ,
`OWNER_NAME` varchar(128) DEFAULT NULL ,
`ROLE_NAME` varchar(128) DEFAULT NULL ,
PRIMARY KEY (`ROLE_ID`)
)
将HDFS上的数据导出到mysql的test数据库的roles_hdfs表中,执行代码如下:
sqoop export \
--connect jdbc:mysql://10.6.6.71:3309/test \
--username root \
--password root123 \
--table roles_hdfs \
--export-dir /user/lyz/111 \
--input-fields-terminated-by ',' \
-m 1
执行数据导入过程中,会触发MapReduce任务。任务成功之后,前往mysql数据库查看是否导入成功。
首先在test数据库中创建roles_hive数据表:
CREATE TABLE `roles_hive` (
`ROLE_ID` bigint(20) NOT NULL ,
`CREATE_TIME` int(11) NOT NULL ,
`OWNER_NAME` varchar(128) DEFAULT NULL ,
`ROLE_NAME` varchar(128) DEFAULT NULL ,
PRIMARY KEY (`ROLE_ID`)
)
由于Hive数据存储在HDFS上,所以从根本上还是将hdfs上的文件导出到mysql的test数据库的roles_hive表中,执行代码如下:
sqoop export \
--connect jdbc:mysql://10.6.6.71:3309/test \
--username root \
--password root123 \
--table roles_hive \
--export-dir /apps/hive/warehouse/roles_test \
--input-fields-terminated-by ',' \
-m 1
目前Sqoop不支持从HBase直接导出到关系型数据库。可以使用Hive周转一下。
create external table hive_hbase(id int,CREATE_TIME string,OWNER_NAME string,ROLE_NAME string)
stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
with serdeproperties ("hbase.columns.mapping" = ":key,info:CREATE_TIME,info:OWNER_NAME,info:ROLE_NAME")
tblproperties("hbase.table.name" = "roles_test");
创建适配于Hive外部表的内部表:
create table if not exists hive_export(id int, CREATE_TIME string, OWNER_NAME string, ROLE_NAME string)
row format delimited fields terminated by ',' stored as textfile;
hive_hbase外部表的源是HBase表数据,当创建适配于hive_hbase外部表的Hive内部表时,指定行的格式为’,’
insert overwrite table hive_export
select * from hive_hbase;
CREATE TABLE `roles_hbase` (
`id` bigint(20) NOT NULL,
` create_time` varchar(128) NOT NULL ,
` owner_name` varchar(128) DEFAULT NULL ,
` role_name` varchar(128) DEFAULT NULL ,
PRIMARY KEY (`id`)
)
sqoop export \
--connect jdbc:mysql://10.6.6.71:3309/test \
--username root \
--password root123 \
--table roles_hbase \
--export-dir /apps/hive/warehouse/hive_export/ \
--input-fields-terminated-by ',' \
-m 1
查看mysql中的roles_hbase表,数据成功被导入。
备注:在创建表的时候,一定要注意表字段的类型,如果指定表类型不一致,有可能会报错。
使用sqoop import/export命令,可以实现将关系型数据库中的数据与Hadoop中的数据进行相互转化,其中一些转化的细节,可以指定参数实现。在执行过程中,sqoop shell操作,会转化为MapReduce任务来实现数据的抽取。
更多的sqoop操作,详情请参见:http://sqoop.apache.org/docs/1.4.6/SqoopUserGuide.html
长按下方二维码,关注更多精彩内容
码字不易,如果感觉本文对您有帮助,请点赞或订阅专栏支持一下,您的支持是我坚持写作最大的动力,谢谢!
如果您有疑问或想法,可进行评论,作者会第一时间回复。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。