【Hadoop离线基础总结】Sqoop数据迁移

时间:2023-03-09 17:21:32
【Hadoop离线基础总结】Sqoop数据迁移


Sqoop介绍

  • 概述

    Sqoop是Apache开源提供过的一款Hadoop和关系数据库服务器之间传送数据的工具。从关系数据库到Hadoop的数据库存储系统(HDFS,HIVE,HBASE等)称为导入,从Hadoop的数据库存储系统到关系数据库称为导出

    Sqoop主要是通过MapReduce的InputFormatOutputFormat来实现数据的输入和输出,底层执行的MapReduce任务只有Map阶段,没有Reduce阶段,也就是说只是单纯地将数据从一个地方抽取到另一个地方。

  • 版本

    Sqoop有两个大版本:

    Sqoop 1.x 不用安装,解压就能用

    【Hadoop离线基础总结】Sqoop数据迁移

    Sqoop 2.x 架构发生了变化,引入了一个服务端,可以通过代码提交sqoop的任务

    【Hadoop离线基础总结】Sqoop数据迁移

    一般情况下用Sqoop 1.x更多一些,只需要将命令写到脚本中,执行脚本即可


Sqoop安装及使用

  • Sqoop安装

    1.下载并解压

    下载地址:http://archive.cloudera.com/cdh5/cdh/5/

    这里使用的是sqoop1的版本,并且要和hadoop版本相对应,都是5.14.0

    将安装包上传到/export/softwares目录中

    tar -zxvf sqoop-1.4.6-cdh5.14.0.tar.gz -C ../servers/ 解压



    2.修改配置文件

    cd /export/servers/sqoop-1.4.6-cdh5.14.0/conf/

    cp sqoop-env-template.sh sqoop-env.sh sqoop-env-template.sh是sqoop给的配置模板,所以最好复制一份出来

    vim sqoop-env.sh

    因为这里只用到Hadoop和Hive,所以只需要配置这两个的路径即可

    【Hadoop离线基础总结】Sqoop数据迁移

    3.加入额外的依赖包

    需要在Sqoop的lib目录下加入一个mysql的依赖包,一个java-json的依赖包,否则就会报错

    【Hadoop离线基础总结】Sqoop数据迁移

    4.验证启动

    cd /export/servers/sqoop-1.4.6-cdh5.14.0

    bin/sqoop-version

    【Hadoop离线基础总结】Sqoop数据迁移

  • Sqoop数据导入

    首先可以用命令行查看帮助bin/sqoop help

    Available commands:
    可用命令: codegen Generate code to interact with database records
    生成与数据库记录交互的代码 create-hive-table Import a table definition into Hive
    将表定义导入到Hive中 eval Evaluate a SQL statement and display the results
    计算一个SQL语句并显示结果 export Export an HDFS directory to a database table
    将HDFS目录导出到数据库表 help List available commands
    罗列出可用的命令 import Import a table from a database to HDFS
    将一个表从数据库导入到HDFS import-all-tables Import tables from a database to HDFS
    将一些表从数据库导入到HDFS import-mainframe Import datasets from a mainframe server to HDFS
    从大型机服务器导入数据集到HDFS job Work with saved jobs
    用保存的jobs继续工作 list-databases List available databases on a server
    列出服务器上可用的数据库 list-tables List available tables in a database
    列出数据库中可用的表 merge Merge results of incremental imports
    增量导入的合并结果 metastore Run a standalone Sqoop metastore
    运行一个独立的Sqoop metastore version Display version information
    显示版本信息

    1.列出本地主机所有的数据库,可以用bin/sqoop listdabases --help查看帮助

    2.bin/sqoop list-databases --connect jdbc:mysql://192.168.0.106:3306/ --username root --password 自己数据库的密码 显示数据库

    java.sql.SQLException: null, message from server: "Host ‘192.168.0.30’ is not allowed to connect to this MySQL server"

    注意:如果出现这种异常,需要给自己连接的mysql授予远程连接权限

    3.bin/sqoop list-tables --connect jdbc:mysql://192.168.0.106:3306/userdb --username root --password 123456 显示数据库中的表



    4.bin/sqoop import --connect jdbc:mysql://192.168.0.106:3306/userdb --username root --password 123456 --table emp --m 1 将mysql数据库userdb中的emp表导入到hdfs中--table指要选择哪个表,--m指MapTask的个数)

    【Hadoop离线基础总结】Sqoop数据迁移

    5.bin/sqoop import --connect jdbc:mysql://192.168.0.106:3306/userdb --username root --password 123456 --table emp --delete-target-dir --target-dir /sqoop/emp --m 1 将emp表导入到hdfs指定文件夹--delete-target-dir判断导出目录是否存在,如果存在就删除 --target-dir指定导出目录)

    【Hadoop离线基础总结】Sqoop数据迁移

    6.bin/sqoop import --connect jdbc:mysql://192.168.0.106:3306/userdb --table emp --delete-target-dir --target-dir /sqoop/emp2 --username root --password 123456 --fields-terminated-by '\t' --m 1 指定分隔符

    【Hadoop离线基础总结】Sqoop数据迁移

  • 导入关系表到Hive已有表中

    1.想要将mysql中的表数据直接导入到Hive,必须先将Hive下lib目录中的一个jar包hive-exec-1.1.0-cdh5.14.0.jar复制到sqoop的lib目录下 cp /export/servers/hive-1.1.0-cdh5.14.0/lib/hive-exec-1.1.0-cdh5.14.0.jar /export/servers/sqoop-1.4.6-cdh5.14.0/lib/

    2.然后现在hive中创建一个sqooptohive的数据库,并在其中创建一个用来存放数据的表

    CREATE DATABASE sqooptohive;

    USE sqooptohive;

    CREATE EXTERNAL TABLE emp_hive(
    id INT,
    name STRING,
    deg STRING,
    salary INT,
    dept STRING)
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\001';

    3.bin/sqoop import --connect jdbc:mysql://192.168.0.106:3306/userdb --table emp --delete-target-dir --target-dir /sqoop/emp2 --fields-terminated-by '\001' --username root --password 123456 --hive-import --hive-table sqooptohive.emp_hive --hive-overwrite --m 1 从mysql向hive导入表数据--hive-overwrite 表示如果有重名的表,则覆盖掉)

    【Hadoop离线基础总结】Sqoop数据迁移

    遇到一个报错

    【Hadoop离线基础总结】Sqoop数据迁移

    原因是因为在/etc/profile中没有配置hive的环境变量,到/etc/profile/下添加两行

    【Hadoop离线基础总结】Sqoop数据迁移

    配置完成后一定记得source /etc/profile生效

  • 导入关系表到Hive(自动创建Hive表)

    bin/sqoop import --connect jdbc:mysql://192.168.0.106:3306/userdb --table emp-conn --username root -password 123456 --hive-import --hive-database sqooptohive --m 1

    【Hadoop离线基础总结】Sqoop数据迁移

  • 将关系表子集导入到HDFS中

    bin/sqoop import --connect jdbc:mysql://192.168.0.106:3306/userdb --table emp_add --delete-target-dir --target-dir /sqoop/emp_add --username root --password 123456 --where "city='sec-bad'" --m 1

    【Hadoop离线基础总结】Sqoop数据迁移

  • sql语句查找导入到HDFS

    bin/sqoop import --connect jdbc:mysql://192.168.0.106:3306/userdb --delect-target-dir --target-dir /sqoop/emp_conn --username root --password 123456 --query 'select phon from emp_conn where 1=1 and $CONDITIONS' --m 1 使用sql语句查询首先不能有--table,其次--query后面跟着的sql语句必须用单引号,必须要有where条件,没有筛选条件就用WHERE 1=1,后面必须跟一个$CONDITIONS字符串

    【Hadoop离线基础总结】Sqoop数据迁移

  • 两种增量导入方式

    实际工作中,很少有需要将整张表的数据导入到Hive或者HDFS,一般只需要导入增量数据。增量导入仅导入新添加的表中的行的技术。一般情况下,每个数据表都会有三个固定字段:create_time,update_time,is_delete。可以根据创建时间和更新时间来解决增量导入数据的需求

    Sqoop也考虑到了这种情况,提供了三个参数来帮助实现增量导入:

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

    1.第一种增量方式

    需求:导入emp表当中id大于1202的所有数据

    bin/sqoop import --connect jdbc:mysql://192.168.0.106:3306/userdb --table emp --target-dir /sqoop/increment --incremental append --check-column id --last-value 1202 --username root --password 123456 --m 1

    增量导入的时候,一定不能加参数–delete-target-dir,否则会报错。--incremental有两种mode:append \ lastmodified--check-column需要的值是用来做增量导入判断的列名(字段名)。--last-value是指定某一个值,用于标记增量导入的位置。

    【Hadoop离线基础总结】Sqoop数据迁移

    2.第二种增量方式

    需求:导入emp表中创建时间在2020.3.7且is_delete=1的数据

    bin/sqoop import --connect jdbc:mysql://192.168.0.106/userdb --table emp --target-dir /sqoop/increment2 --incremental append --where "create_time > '2020-3-7 00:00:00' and create_time < '2020-3-7 23:59:59' and is_delete = '1'" --check-column id --username root --password 123456 --m 1

    本来想的有了where来查询就可以不用--check-column参数,没想到只要是增量导入就必须要有这个参数

    【Hadoop离线基础总结】Sqoop数据迁移

    【Hadoop离线基础总结】Sqoop数据迁移

    3.思考一下如何解决减量数据的需求?

    减量数据的删除是假删除,不是真删除,其实就是改变了数据的状态,数据的更新时间也会同步改变。所以解决减量数据实际上就涉及到了数据的变更问题,只要变更数据,update_time也会发生改变

    更新数据的时候,就是要根据create_time和update_time一起来判断,只要符合其中任意一项就将数据导入到Hive或者HDFS上,那么就有可能出现两条id相同,create_time相同的数据,比如

    id		create_time			update_time
    1 2020-1-3 12:12:12 2020-1-3 12:12:12
    1 2020-1-3 12:12:12 2020-1-13 12:12:12

    可以用group by id进行分组,将id相同的分到一组,取update_time最新的数据

  • Sqoop的数据导出

    bin/sqoop export --connect jdbc:mysql://192.168.0.106:3306/userdb --table emp_out --export-dir /sqoop/emp --input-fields-terminated-by ',' --username root --password 123456

    【Hadoop离线基础总结】Sqoop数据迁移