辅助框架之Sqoop数据迁移工具

1. Sqoop是什么?

Sqoop是apache旗下的一款 ”Hadoop和关系数据库之间传输数据”的工具。

(1)导入数据:将MySQL,Oracle导入数据到Hadoop的HDFS、HIVE、HBASE等数据存储系统;

(2)导出数据:从Hadoop的文件系统中导出数据到关系数据库。

辅助框架之Sqoop数据迁移工具

辅助框架之Sqoop数据迁移工具

2. Sqoop的工作机制

将导入和导出的命令翻译成mapreduce程序实现;在翻译出的mapreduce中主要是对inputformat和outputformat进行定制。

3. Sqoop基本架构

辅助框架之Sqoop数据迁移工具

4. Sqooq数据的导入

注意:需要先开启zookeeper集群、Hadoop集群、再开启hbase,然后再执行sqoop导入

4.1列举出所有的数据库

(1)命令行查看帮助文档

sqoop list-databases --help

(2)列出node03上mysql数据库中所有的数据库名称

sqoop list-databases --connect jdbc:mysql://node03:3306/ --username root --password 123456

(3)查看某一个数据库下面的所有数据表

sqoop list-tables --connect jdbc:mysql://node03:3306/hive --username root --password 123456

4.2导入数据库表数据到HDFS

(1)在MySQL数据库服务器中创建一个数据库userdb, 然后在创建一张表 emp,添加点测试数据到表中;

  • 建库:

CREATE DATABASE IF NOT EXISTS userdb DEFAULT CHARACTER SET utf8 ;

USE userdb;

  • 建表:

CREATE TABLE `emp`  (

  `id` INT(11) NOT NULL,

  `name` VARCHAR(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,

  `deg` VARCHAR(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,

  `salary` DOUBLE(255, 2) NULL DEFAULT NULL,

  `dept` VARCHAR(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,

  PRIMARY KEY (`id`) USING BTREE) ENGINE = INNODB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = DYNAMIC;

  • 插入数据:

INSERT INTO `emp` VALUES (1201, 'gopal', 'manager', 50000.00, 'TP');

INSERT INTO `emp` VALUES (1202, 'manisha', 'Proof reader', 50000.00, 'TP');

INSERT INTO `emp` VALUES (1203, 'khalil', 'php dev', 30000.00, 'AC');

INSERT INTO `emp` VALUES (1204, 'prasanth', 'php dev', 20000.00, 'AC');

INSERT INTO `emp` VALUES (1205, 'kranthi', 'admin', 10000.00, 'TP');

INSERT INTO `emp` VALUES (1206, 'tom', 'admin', 50000.00, 'TP');

(2)从MySQL数据库服务器中的userdb数据库下的emp表导入HDFS上:

sqoop import \
--connect jdbc:mysql://node03:3306/userdb \
--username root   \
--password 123456 \
--table emp \
--m 1

#参数解释
--connect   指定mysql链接地址
--username  连接mysql的用户名
--password  连接mysql的密码
--table     指定要导入的mysql表名称
--m:        表示这个MR程序需要多少个MapTask去运行,默认为4

提交之后,会运行一个MR程序,最后查看HDFS上的目录看是否有数据生成:

辅助框架之Sqoop数据迁移工具

辅助框架之Sqoop数据迁移工具

辅助框架之Sqoop数据迁移工具

4.3导入数据库表数据到HDFS指定目录

使用参数 --target-dir来指定导出目的地;

使用参数--delete-target-dir来判断导出目录是否存在,如果存在就删掉。

sqoop import  
--connect jdbc:mysql://node03:3306/userdb 
--username root 
--password 123456  
--table emp  
--target-dir /sqoop/emp  
--delete-target-dir 
--m 1

查看hdfs上的数据:

辅助框架之Sqoop数据迁移工具

4.4 导入数据库表数据到HDFS指定目录并且指定数据字段的分隔符

使用参数:--fields-terminated-by 分隔符

sqoop import  \
--connect jdbc:mysql://node03:3306/userdb \
--username root \
--password 123456 \
--delete-target-dir \
--table emp  \
--target-dir /sqoop/emp1 \
--fields-terminated-by '#' \
--m 1

查看hdfs数据:

辅助框架之Sqoop数据迁移工具

4.5导入关系表到Hive中

(1)需要将hive的hive-exec-1.1.0-cdh5.14.2.jar包拷贝到sqoop的lib目录下。

cp /install/hive-1.1.0-cdh5.14.2/lib/hive-exec-1.1.0-cdh5.14.2.jar /install/sqoop-1.4.6-cdh5.14.2/lib/

(2)在hive中创建一个数据库和表:

 database sqooptohive;

辅助框架之Sqoop数据迁移工具

create external table sqooptohive.emp_hive(id int,name string,deg string,salary double ,dept string) row format delimited fields terminated by '\001';

辅助框架之Sqoop数据迁移工具

(3)把mysql表数据导入到hive表中

sqoop import \
--connect jdbc:mysql://node03:3306/userdb \
--username root \
--password 123456 \
--table emp \
--fields-terminated-by '\001' \
--hive-import \
--hive-table sqooptohive.emp_hive \
--hive-overwrite \

--delete-target-dir \
--m 1

##参数解释
--hive-table      指定要导入到hive表名
--hive-import     导入数据到hive表中
--hive-overwrite  覆盖hive表中已存有的数据

(4)执行完成了查看hive中表的数据:select * from sqooptohive.emp_hive;

辅助框架之Sqoop数据迁移工具

4.6 导入数据库表数据到hive中(并自动创建hive表)

sqoop import \
--connect jdbc:mysql://node03:3306/userdb \
--username root \
--password 123456 \
--table emp \             
--hive-database sqooptohive \ 
--hive-table emp1 \    
--hive-import \
--m 1

#将mysql中的emp表插入到hive的sqooptohive数据库中的emp1表中

4.7 导入表数据子集

通过where参数来导入子集。

sqoop import \
--connect jdbc:mysql://node03:3306/userdb \
--username root \
--password 123456 \
--table emp \
--target-dir /sqoop/emp_where \
--delete-target-dir \
--where "dept = 'TP'" \
--m 1

4.8 sql语句查找导入hdfs

通过 query参数来指定我们的sql语句,通过sql语句来过滤我们的数据进行导入。

sqoop import \
--connect jdbc:mysql://node03:3306/userdb \
--username root \
--password 123456 \
--target-dir /sqoop/emp_sql \
--delete-target-dir \
--query 'select * from emp where salary >30000 and $CONDITIONS' \
--m 1

辅助框架之Sqoop数据迁移工具

$CONTITONS是linux系统的变量,如果你想通过并行的方式导入结果,每个map task需要执行sql查询后脚语句的副本,结果会根据sqoop推测的边界条件分区query必须包含$CONDITIONS。这样每个sqoop程序都会被替换为一个独立的条件。同时你必须指定 --split-by '字段',后期是按照字段进行数据划分,最后可以达到多个MapTask并行运行。

如:

sqoop import \
--connect jdbc:mysql://node03:3306/userdb \
--username root \
--password 123456 \
--target-dir /sqoop/emp_sql_2 \
--delete-target-dir \
--query 'select * from emp where salary >30000 and $CONDITIONS' \
--split-by 'id' \
--m 2

 

--split-by '字段': 后期按照字段进行数据划分实现并行运行多个MapTask。

辅助框架之Sqoop数据迁移工具

4.9 增量导入

增量导入是仅导入新添加的表中的行的技术。

需要添加 ‘incremental’, ‘check-column’, 和 ‘last-value’选项来执行增量导入。

  • --incremental <mode>
  • --check-column <column name>
  • --last value <last check column value>

(1)第一种增量导入实现

基于递增列的增量数据导入(Append方式);(不能加上 --delete-target-dir 参数)

sqoop import \
--connect jdbc:mysql://node03:3306/userdb \
--username root \
--password 123456 \
--table emp \
--incremental append \
--check-column id \
--last-value 1202  \                #导入emp表当中id大于1202的数据

--target-dir /sqoop/increment \
--m 1

##参数解释
--incremental   这里使用基于递增列的增量数据导入
--check-column  递增列字段
--last-value    指定上一次导入中检查列指定字段最大值
--target-dir    数据导入的目录

辅助框架之Sqoop数据迁移工具

(2)第二种增量导入实现

基于时间列的增量数据导入(LastModified方式):要求原有表中有time字段,它能指定一个时间戳。

sqoop import \
--connect jdbc:mysql://node03:3306/userdb \
--username root \
--password 123456  \
--table user \
--incremental lastmodified  \
--check-column createTime  \
--last-value '2019-10-01 10:30:00'  \
--target-dir /sqoop/increment2 \
--m 1

##参数解释
--incremental   这里使用基于时间列的增量导入
--check-column  时间字段
--last-value    指定上一次导入中检查列指定字段最大值
--target-dir    数据导入的目录;如果该目录存在(可能已经有数据),再使用的时候需要添加 --merge-key or --append
           --merge-key 指定合并key(对于有修改的)
           --append    直接追加修改的数据

辅助框架之Sqoop数据迁移工具

4.10 mysql表的数据导入到hbase中

需求:实现把一张mysql表数据导入到hbase中。

注意:sqoop导入hbase表时需指定表名、列族、rowkey等,即如下红色字体:

sqoop import \
--connect jdbc:mysql://node03:3306/userdb \
--username root \
--password 123456  \
--table user \
--hbase-table  mysqluser \
--column-family  f1 \
--hbase-create-table \
--hbase-row-key id  \
--m 1

#参数说明
--hbase-table   指定hbase表名
--column-family 指定表的列族
--hbase-create-table 表不存在就创建
--hbase-row-key 指定hbase表的id
--m   指定使用的MapTask个数

辅助框架之Sqoop数据迁移工具

5. Sqoop数据的导出

将数据从HDFS把文件导出到RDBMS数据库。

  • 导出前,目标表必须存在于目标数据库中。
    • 默认操作是从将文件中的数据使用INSERT语句插入到表中
    • 更新模式下,是生成UPDATE语句更新表数据

5.1hdfs文件导出到mysql表中

(1)创建一张mysql表(一定要先创建!此时只是空表)

CREATE TABLE  userdb.fromhdfs (
   id INT DEFAULT NULL,
   name VARCHAR(100) DEFAULT NULL,
   age int DEFAULT NULL,
   address VARCHAR(100) DEFAULT NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8;

(2)执行导出命令

sqoop export \
--connect jdbc:mysql://node03:3306/userdb \
--username root \
--password 123456 \
--table fromhdfs \
--export-dir /user/hive/warehouse/hive_source.txt \         #数据存在此文件中
--input-fields-terminated-by " "

##参数解释
--table   指定导出的mysql表名
--export-dir   指定hdfs数据文件目录
--input-fields-terminated-by  指定文件数据字段的分隔符

命令执行后:

辅助框架之Sqoop数据迁移工具