目录
- Sqoop介绍
- sqoop数据传输
- 一、RDBMS —> HDFS
- a.增量导入-incremental append
- b.增量导入-incremental lastmodified
- 二、RDBMS —> HBASE
- 单列族传输
- 多列族传输
- 三、RDBMS —> HIVE
- 四、Hive/Hdfs—> RDBMS
- 五、Hbase数据映射Hive
Sqoop介绍
- Sqoop是一个用来将关系型数据库和Hadoop中的数据进行相互转移的工具,可以将一个关系型数据库(例如Mysql、Oracle)中的数据导入到Hadoop(例如HDFS、Hive、Hbase)中,也可以将Hadoop(例如HDFS、Hive、Hbase)中的数据导入到关系型数据库(例如Mysql、Oracle)中。
- Sqoop工具接收到客户端的shell命令或者Java api命令后,通过Sqoop中的任务翻译器(Task Translator)将命令转换为对应的MapReduce任务,而后将关系型数据库和Hadoop中的数据进行相互转移,进而完成数据的拷贝。
sqoop数据传输
一、RDBMS —> HDFS
a.增量导入-incremental append
incremental append -->只支持新增不支持更新;
先将服务启动好之后进行如下操作,这里演示从关系型数据库传输数据至HDFS:
- 实例演示
sqoop import \
--connect jdbc:mysql://single:3306/mysqltest \
--username root \
--password root \
--query "select sid,student_id,course_id,score from score where \$CONDITIONS" \
--target-dir /kb10/mysqlscore1119 \
--split-by sid \
-m 2 \
--check-column sid \
--incremental append \
--last-value 0
- 代码翻译:
* 表示从系型数据库传输数据至HDFS( import);
* 表示连接到mysql的mysqtest数据库(图中的single为服务器的hostname,也可写为ip地址,使用hostname的前提是地址与
hostname做过关联配置);
* 表示连接数据库的用户名;
* 表示连接数据库的密码;
* query为请求的查询语句,后面的$CONDITIONS表示引用查询到的输出结果;
* 表示数据导出的目标路径;
* 这里的split-by与下一行相配合,图上为sid为分割,不同的sid将进行Hash操作之后取余mapreduce的数量,最后的结果决定了
进入哪一个mapreduce内(也可以写成--num-mappers 2 \);
* 表示启动mapredce的数量;
* 从这一行到最后一行配合使用,可以实现增量插入数据,相当于where sid >0;
* 表示使用incremental append增量导入操作;
* 表示增量导入的开始行,这里是第一次导入所以也是全量导入;
- 实例结果展示
运行时代码截图展示,可以见到上下边界值的大小,下边界作为下一次增量导入的上边值;
20/11/19 18:39:23 INFO tool.ImportTool: Incremental import based on column `sid`
20/11/19 18:39:23 INFO tool.ImportTool: Lower bound value: 0
20/11/19 18:39:23 INFO tool.ImportTool: Upper bound value: 60
20/11/19 18:39:23 INFO mapreduce.ImportJobBase: Beginning query import.
- 结果展示
落盘文件数量为2,对应的启动的mapreduce数量,数据查询到第60行结束;
1,1,1,60
2,1,2,59
3,1,3,58
4,1,4,22
5,1,5,59
...
...
58,11,7,99
59,12,3,100
60,12,8,60
下一次再次进行增量导入时,将之前的到的下边界值作为条件写入语句中;
- 实例演示
sqoop import \
--connect jdbc:mysql://single:3306/mysqltest \
--username root \
--password root \
--query "select sid,student_id,course_id,score from score where \$CONDITIONS" \
--target-dir /kb10/mysqlscore1119 \
--split-by sid \
-m 1 \
--check-column sid \
--incremental append \
--last-value 60
- 代码翻译:
* 注意最后的last-value,此时的value值是上一次全量导入后返回的下边界值;最后三行相当于where sid >60
- 实例结果展示
运行时代码截图展示,可以见到上下边界值是60和68;
20/11/19 18:59:13 INFO tool.ImportTool: Incremental import based on column `sid`
20/11/19 18:59:13 INFO tool.ImportTool: Lower bound value: 60
20/11/19 18:59:13 INFO tool.ImportTool: Upper bound value: 68
20/11/19 18:59:13 INFO mapreduce.ImportJobBase: Beginning query import.
- 实例结果展示
因为这一次我设置的mapreduce数量为1,所以最后落盘也只增加了一个文件,最后查看数据只到第68行数据;
1,1,1,60
2,1,2,59
3,1,3,58
4,1,4,22
5,1,5,59
...
...
66,12,5,49
67,12,6,82
68,12,7,77
b.增量导入-incremental lastmodified
incremental lastmodified -->修改和增加
check-column 必须为timestamp类型,如果导入的表数据中没有date(time)类型的,那么这种方式将无法使用;
- 实例演示
sqoop import \
--connect jdbc:mysql://single:3306/mysqltest \
--username root \
--password root \
--query "select id,name,time from lmtest where \$CONDITIONS" \
--target-dir /kb10/lm1118 \
--split-by id \
-m 1 \
--check-column time \
--incremental lastmodified \
--merge-key id \
--last-value '2020-11-19 12:24:12'
- 代码解释:
* 与上面的append增量导入有所区别在于,check-column必须为date(time)类型。此时更新的数据是根据时间字段更新数据。
* 更新的是incremental.last.value中的值所表示的时间到当前系统时间的时间段的数据。
- 实例结果展示
运行时代码截图展示,可以见到上下边界时间;
20/11/19 17:36:27 INFO tool.ImportTool: Incremental import based on column `time`
20/11/19 17:36:27 INFO tool.ImportTool: Lower bound value: '2020-11-19 12:24:12'
20/11/19 17:36:27 INFO tool.ImportTool: Upper bound value: '2020-11-19 17:36:27.0'
20/11/19 17:36:27 INFO mapreduce.ImportJobBase: Beginning query import.
1,henry,2020-11-19 17:24:12.0
2,curry,2020-11-19 17:24:12.0
3,paul,2020-11-19 17:24:12.0
4,alex,2020-11-19 17:24:12.0
二、RDBMS —> HBASE
利用hbase作为hive的数据源,因为hbase延时低,数据吞吐量大,所以从MySQL传输至Hbase需要重点掌握!
单列族传输
先在Hbase内建表;
hbase(main):004:0> create 'stu:mysql_stu2','info','score'
0 row(s) in 2.3930 seconds
=> Hbase::Table - stu:mysql_stu2
- 实例演示
sqoop import \
--connect jdbc:mysql://single:3306/mysqltest \
--username root \
--password root \
--table score \
--hbase-table stu:mysql_stu2 \
--column-family score \
--hbase-create-table \
--hbase-row-key sid \
--hbase-bulkloa
- 代码解释:
* 表示从关系型数据库传输数据至hbase(import);
* 表示连接到mysql的mysqtest数据库;
* 表示连接数据库的用户名;
* 表示连接数据库的密码;
* 表示连接mysqltest数据库的表score;
* 数据传输至hbase的表;
* column-family指定列族;
* 表示如果表不存在会自动创建表;
* 指定hbase表的row-key;
* hbase-bulkloa:不用指定输出的路径,自动数据转移;
- 实例结果展示
hbase(main):001:0> scan 'stu:mysql_stu2'
ROW COLUMN+CELL
1 column=score:course_id, timestamp=1605785555916, value=1
1 column=score:score, timestamp=1605785555916, value=60
1 column=score:student_id, timestamp=1605785555916, value=1
10 column=score:course_id, timestamp=1605785555916, value=1
10 column=score:score, timestamp=1605785555916, value=99
...
...
8 column=score:student_id, timestamp=1605785555916, value=1
9 column=score:course_id, timestamp=1605785555916, value=9
9 column=score:score, timestamp=1605785555916, value=88
9 column=score:student_id, timestamp=1605785555916, value=1
64 row(s) in 0.3630 seconds
多列族传输
以下均是从同一MySQL的表中传输至hbase上同一表中的不同列族中的操作;
如果数据不在同一张表中,可以考虑做成视图统一从视图提取数据,这样可以保证数据的一致性,不然可能导致数据错乱的问题;
先在Hbase中建表;
hbase(main):001:0>create 'kb10:mysql_school','basicinfo','classinfo','scoreinfo'
0 row(s) in 2.3930 seconds
=> Hbase::Table - kb10:mysql_school
- 实例演示
这里也可以使用query进行传输,但是使用query需要将–hbase-bulkload删除,否则会出错!
sqoop import \
--connect jdbc:mysql://single:3306/school \
--username root \
--password root \
--table stuscore_info \
--columns id,stuname,stugender,province,city,district \
--hbase-table kb10:mysql_school \
--column-family basicinfo \
--hbase-row-key id \
--split-by id \
--num-mappers 1 \
--hbase-bulkload
sqoop import \
--connect jdbc:mysql://single:3306/school \
--username root \
--password root \
--table stuscore_info \
--columns id,proname,classname,opendate \
--hbase-table kb10:mysql_school \
--column-family classinfo \
--hbase-row-key id \
--split-by id \
--num-mappers 1 \
--hbase-bulkload
sqoop import \
--connect jdbc:mysql://single:3306/school \
--username root \
--password root \
--table stuscore_info \
--columns id,subname,score \
--hbase-table kb10:mysql_school \
--column-family scoreinfo \
--hbase-row-key id \
--split-by id \
--num-mappers 1 \
--hbase-bulkload
- 代码解释:
* 与上面的单列族导入类似,三次导入不同的是MySQL表的字段名,还有对应hbase的列族名;值得一提的是,三次导入时的rowkey必须一致,保证了数据的准确;
因为hbase中文显示乱码问题,这里就不放实例结果了,可以将数据映射Hive,Hive查询并操作数据。(见第四项的映射操作)
三、RDBMS —> HIVE
先在hive中建表,建表时设置的字段分割要和sqoop导入时设置的字段分割一致,不然即使显示导入成功,但是查询数据字段数据都为null。
create table student(
sid int,
sname string,
gender string,
class_id int)
row format delimited
fields terminated by '\t'
stored as textfile
- 实例演示
sqoop import \
--connect jdbc:mysql://192.168.182.130:3306/mysqltest \
--username root \
--password root \
-m 1 \
--table student \
--hive-database 'myhive' \
--hive-import \
--hive-overwrite \
--direct \
--hive-table 'student' \
--null-string '\\ N' \
--null-non-string '\\ N' \
--fields-terminated-by '\t'
- 实例结果展示(图片来自zeppelin截图)
四、Hive/Hdfs—> RDBMS
先在MySql内建表;
create table hive_shop(
id int,
name varchar(50),
mobile varchar(20),
address varchar(100),
vol2020 int
);
- 实例演示
sqoop export \
--connect jdbc:mysql://single:3306/mysqtest\
--username root \
--password root \
--table hive_shop \
--columns id,name,mobile,address,vol2020 \
--fields-terminated-by ',' \
--export-dir '/kb10/shop1118/000000_0'
- 代码解释:
* 表示从HIVE/HDFS传输数据至关系型数据库;(import)
* 表示连接到mysql的mysqtest数据库;
* 表示连接数据库的用户名;
* 表示连接数据库的密码;
* 表示导入至数据库的表名;
* 表示数据库表中相应的字段;
* 字段间隔以“,”隔开;
* 表示数据导入所在的目录;
- 实例结果展示
+----+--------------+-------------+-------------------------+---------+
| id | name | mobile | address | vol2020 |
+----+--------------+-------------+-------------------------+---------+
| 1 | 紫燕百味鸡 | 18014499655 | 江苏南京雨花小行路288号 | 1000000 |
| 2 | 如家快捷酒店 | 13987499234 | 江苏南京雨花小行路28号 | 1259800 |
| 3 | 苏果超市 | 13814987651 | 江苏南京雨花小行路06号 | 1123000 |
| 4 | 罗森 | 14766848644 | 江苏南京雨花小行路08号 | 1000000 |
+----+--------------+-------------+-------------------------+---------+
五、Hbase数据映射Hive
- 建立映射对应关系
- 实例演示(对应第二点的MySQL传输至Hbase多列族)
CREATE EXTERNAL TABLE mysql_school(id string,stuname string,stugender string,province string,city string,district string,classname string,proname string,opendate string,subname string,score int)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,basicinfo:stuname,basicinfo:stugender,basicinfo:province,basicinfo:city,basicinfo:district,classinfo:classname,classinfo:proname,classinfo:opendate,scoreinfo:subname,scoreinfo:score")
TBLPROPERTIES ("hbase.table.name" = "test:mysql_school")
- 实例结果展示(进入Hive查询数据)
PS:如果有写错或者写的不好的地方,欢迎各位大佬在评论区留下宝贵的意见或者建议,敬上!如果这篇博客对您有帮助,希望您可以顺手帮我点个赞!不胜感谢!
原创作者:wsjslient |