|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
 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号