|NO.Z.00054|——————————|BigDataEnd|——|Hadoop&Sqoop.V02|——|Sqoop.v02|MySQL导入到HDFS|
一、应用案例
### --- 在Sqoop中
~~~ # 导入是指:
~~~ 从关系型数据库向大数据集群(HDFS、HIVE、HBASE)传输数据;使用import关键字;
~~~ # 导出是指:
~~~ 从 大数据集群 向 关系型数据库 传输数据;使用export关键字;
### --- 测试数据脚本
~~~ 以下案例需要启动:HDFS、YARN、MySQL 对应的服务;
~~~ 用于在 Mysql 中生成测试数据
CREATE DATABASE sqoop;
USE sqoop;
CREATE TABLE sqoop.goodtbl(
gname VARCHAR(50),
serialNumber INT,
price INT,
stock_number INT,
create_time DATE);
DROP FUNCTION IF EXISTS `rand_string`;
DROP PROCEDURE IF EXISTS `batchInsertTestData`;
~~~ # 替换语句默认的执行符号,将;替换成 //
DELIMITER //
CREATE FUNCTION `rand_string` (n INT) RETURNS VARCHAR(255) CHARSET 'utf8'
BEGIN
DECLARE char_str VARCHAR(200) DEFAULT '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
DECLARE return_str VARCHAR(255) DEFAULT '';
DECLARE i INT DEFAULT 0;
WHILE i < n DO
SET return_str = CONCAT(return_str, SUBSTRING(char_str, FLOOR(1 + RAND()*36), 1));
SET i = i+1;
END WHILE;
RETURN return_str;
END
//
~~~ # 第一个参数表示:序号从几开始;第二个参数表示:插入多少条记录
CREATE PROCEDURE `batchInsertTestData` (m INT, n INT)
BEGIN
DECLARE i INT DEFAULT 0;
WHILE i < n DO
INSERT INTO goodtbl (gname, serialNumber, price, stock_number, create_time)
VALUES (rand_string(6), i+m, ROUND(RAND()*100), FLOOR(RAND()*100), NOW());
SET i = i+1;
END WHILE;
END
//
DELIMITER ;
CALL batchInsertTestData(10, 200);
二、导入数据:MySQL 到 HDFS
### --- 导入全部数据
~~~ # 导入是指:
~~~ 从关系型数据库向大数据集群(HDFS、Hive、HBase)传输数据,使用import关键字
~~~ # 导出是指:
~~~ 从大数据集群向关系型数据库传输数据,使用export关键字
[root@linux123 ~]# sqoop import \
--connect jdbc:mysql://linux123:3306/sqoop \
--username hive \
--password 12345678 \
--table goodtbl \
--target-dir /user/root/sqoop \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t"
[root@linux123 ~]# hdfs dfs -ls sqoop
-rw-r--r-- 3 root supergroup 0 2021-08-28 20:14 sqoop/_SUCCESS
-rw-r--r-- 3 root supergroup 5474 2021-08-28 20:14 sqoop/part-m-00000
[root@linux123 ~]# hdfs dfs -cat sqoop/part-m-00000
### --- 备注:
~~~ target-dir:将数据导入 HDFS 的路径;
~~~ delete-target-dir:如果目标文件夹在 HDFS 上已经存在,那么再次运行就会报错。
~~~ 可以使用--delete-target-dir来先删除目录。也可以使用 append 参数,表示追加数据;
~~~ num-mappers:启动多少个Map Task;默认启动4个Map Task;也可以写成 -m 1
~~~ fields-terminated-by:HDFS文件中数据的分隔符;
### --- 导入查询数据
[root@linux123 ~]# sqoop import \
--connect jdbc:mysql://linux123:3306/sqoop \
--username hive \
--password 12345678 \
--target-dir /user/root/query \
--append -m 1 \
--fields-terminated-by "\t" \
--query 'select gname, serialNumber, price, stock_number,
create_time from goodtbl where price>88 and $CONDITIONS;'
### --- 备注:
~~~ 查询语句的where子句中必须包含 '$CONDITIONS'
~~~ 如果query后使用的是双引号,则$CONDITIONS前必须加转移符,防止shell识别为自己的变量
### --- 导入指定的列
~~~ 备注:columns中如果涉及到多列,用逗号分隔,不能添加空格
[root@linux123 ~]# sqoop import \
--connect jdbc:mysql://linux123:3306/sqoop \
--username hive \
--password 12345678 \
--target-dir /user/root/column \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--columns gname,serialNumber,price \
--table goodtbl
### --- 导入查询数据(使用关键字)
[root@linux123 ~]# sqoop import \
--connect jdbc:mysql://linux123:3306/sqoop \
--username hive \
--password 12345678 \
--target-dir /user/root/keyword \
--delete-target-dir \
-m 1 \
--fields-terminated-by "\t" \
--table goodtbl \
--where "price>=68"
### --- 启动多个Map Task导入数据在 goodtbl 中增加数据:call batchInsertTestData(1000000);
[root@linux123 ~]# sqoop import \
--connect jdbc:mysql://linux123:3306/sqoop \
--username hive \
--password 12345678 \
--table goodtbl \
--target-dir /user/root/maptask \
--append \
--fields-terminated-by "," \
--split-by serialNumber
~~~ # 分区字段是字符类型
[root@linux123 ~]# sqoop import -Dorg.apache.sqoop.splitter.allow_text_splitter=true \
--connect jdbc:mysql://linux123:3306/sqoop \
--username hive \
--password 12345678 \
--table goodtbl \
--target-dir /user/root/maptask \
--append \
--fields-terminated-by "," \
--split-by gname
~~~ # 给 goodtbl 表增加主键
[root@linux123 ~]# mysql -uroot -p12345678
mysql> use sqoop;
mysql> alter table goodtbl add primary key(serialNumber);
### --- 备注:
~~~ 使用多个 Map Task 进行数据导入时,sqoop 要对每个Task的数据进行分区
~~~ 如果 MySQL 中的表有主键,指定 Map Task 的个数就行
~~~ 如果 MySQL 中的表有主键,要使用 split-by 指定分区字段
~~~ 如果分区字段是字符类型,
~~~ 使用 sqoop 命令的时候要添加:-Dorg.apache.sqoop.splitter.allow_text_splitter=true。即
### --- 查询语句的where子句中的 '$CONDITIONS' ,也是为了做数据分区使用的,即使只有1个Map Task
sqoop import -Dorg.apache.sqoop.splitter.allow_text_splitter=true \
--connect jdbc:mysql://linux123:3306/sqoop \
... ...
Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
——W.S.Landor
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」