Sqoop中import & export & job & eval与options-file

Sqoop中的import与export都是基于Hadoop而言的。在本篇文章中,将对Sqoop中的import与export进行详细介绍;同时对sqoop job的使用,eval与options-file的使用进行介绍

Sqoop import

Sqoop import命令详解

  1. 如何查看帮助

  2. 查看使用帮助

    $>sqoop import --help
  3. 将MySQL中的数据导入到HDFS

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp

    产生报错:
    这里写图片描述

    原因:少个jar包,需要将java-json.jar包拷贝到lib目录下

    $>cp java-json.jar $SQOOP_HOME/lib/
  4. 导入jar包之后,重新导入

    在运行过程中,扔到了YARN上去执行作业
    原因:Sqoop的底层是MapReduce任务的执行,因此是跑在Yarn上的

    分析打印的控制台log:

    • 打印了信息SELECT t.* FROM emp AS t LIMIT 1
      这里写图片描述
      执行这句话的目的:去查看emp这张表是否在数据库中存在
      不相信,我们可以直接在mysql中进行执行

      select * from empsb limit 1;   // 会报错,因为empsb这张表在数据库中不存在
      select * from emp limit 1;     // 没报错,因为empsb这张表在数据库中存在
    • 打印信息HADOOP_MAPRED_HOME is /opt/app/hadoop-2.6.0-cdh5.7.0
      这里写图片描述

    • 打印信息Writing jar file: /tmp/sqoop-hadoop/compile/3b2ff5cf1612195cd5cbd6b29c3e75e5/emp.jar
      这里写图片描述
      根据表的名字,生成一个相关的jar包
    • 打印信息number of splits:4
      这里写图片描述
      why? 因为默认情况下就是4个map,会生成4个文件
      我们可以通过-m参数进行指定map个数
  5. 导入成功之后,查看HDFS上的数据
    这里写图片描述

  6. 使用–delete-target-dir参数
    执行的过程中,删除已经存在的输出目录
    (因为如果输出的目录已经存在了,会报错,和执行MR的时候是一样的)

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp \
    --delete-target-dir
  7. 使用–mapreduce-job-name命令
    指定输出jar包的名字

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp \
    --delete-target-dir \
    --mapreduce-job-name emp-all

    通过Web界面可以发现不同:
    这里写图片描述

  8. 只抽取指定字段

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp \
    --delete-target-dir \
    --mapreduce-job-name emp-all \
    --columns "EMPNO,ENAME,JOB,SAL,COMM"

    这里写图片描述

  9. 指定输出到HDFS的路径

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp \
    --delete-target-dir \
    --mapreduce-job-name emp-all \
    --columns "EMPNO,ENAME,JOB,SAL,COMM" \
    --target-dir EMP_COLUMN

    这里写图片描述

  10. 使用-m参数指定map个数

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp \
    -m 1 \
    --delete-target-dir \
    --mapreduce-job-name emp-all \
    --columns "EMPNO,ENAME,JOB,SAL,COMM" \
    --target-dir EMP_COLUMN

    这里写图片描述

Sqoop import命令条件过滤详解

  1. 使用–where参数来限定工资条件(SAL > 2000)

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp \
    -m 1 \
    --delete-target-dir \
    --mapreduce-job-name emp-all \
    --columns "EMPNO,ENAME,JOB,SAL,COMM" \
    --target-dir EMP_COLUMN \
    --where "SAL>2000"

    这里写图片描述

  2. 使用–query 写sql语句 来执行

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    -m 1 \
    --delete-target-dir \
    --mapreduce-job-name emp-all \
    --target-dir EMP_COLUMN \
    --query 'select * from emp where sal>2000 and $CONDITIONS'

    这里写图片描述

    注意:

    • 使用–query写sql语句,就不需要–table 去指定表名了,也不需要–columns该参数去指定输出列了,不然会报错
    • 而且必须在sql语句的最后加 $CONDITIONS,不然会报错

导入没有主键的表数据到HDFS,并且使用多个map来运行

  1. 创建没有主键的表salgrage,并导入数据

    create table salgrade (
        grade numeric,
        losal numeric,
        hisal numeric
    );
    
    insert into salgrade values (1, 700, 1200);
    insert into salgrade values (2, 1201, 1400);
    insert into salgrade values (3, 1401, 2000);
    insert into salgrade values (4, 2001, 3000);
    insert into salgrade values (5, 3001, 9999);
  2. 导入

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table salgrade

    报错:
    这里写图片描述

    分析错误信息:对于这张表,没有主键能够被找到

    分析报错原因:

    • 因为map的默认数量为4,而salgrage里有5条数据,那么就必然涉及到数据的切分
    • 但是因为没主键,如何去切分数据呢?

    解决方案:
    - 设置map个数为1
    - 设置切分数据的字段

    设置切分的字段为GRADE 去导入:

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table salgrade \
    --split-by GRADE \
    --delete-target-dir \
    -m 2

    查看HDFS上的数据:

    $>hadoop fs -ls salgrage
    $>hadoop fs -text salgrade/*

    这里写图片描述

对分隔符及空值的处理

  1. 介绍
    这里写图片描述
    这里写图片描述

    –null-non-string ‘0’ \ 非String类型的null值用0替代
    –null-string ” \ String类型的null值用’ ‘替代

  2. 分隔符及空值处理

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp \
    -m 1 \
    --delete-target-dir \
    --mapreduce-job-name emp-all \
    --columns "EMPNO,ENAME,JOB,SAL,COMM" \
    --target-dir EMP_COLUMN_SPLIT \
    --fields-terminated-by '\t' \
    --null-non-string '0' \
    --null-string ''
  3. 查看HDFS上的数据

    $>hadoop fs -text EMP_COLUMN_SPLIT/part-m-00000

    这里写图片描述

direct模式

  1. 使用

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp \
    -m 1 \
    --delete-target-dir \
    --mapreduce-job-name emp-all \
    --columns "EMPNO,ENAME,JOB,SAL,COMM" \
    --target-dir EMP_COLUMN_SPLIT \
    --fields-terminated-by '\t' \
    --null-non-string '0' \
    --null-string '' \
    --direct    
  2. 浅析direct模式
    direct模式底层使用了工具mysqlimport
    当数据量不大,使用该模式跑起来没什么意义

    观察日志信息:
    使用的manager为DirectMySQLManager

    17/10/21 15:18:18 WARN manager.DirectMySQLManager: Direct-mode import from MySQL does not support column

    而不使用–direct模式,使用的manager则为MySQLManager

    17/10/21 15:15:15 WARN manager.MySQLManager: It looks like you are importing from mysql.
    17/10/21 15:15:15 WARN manager.MySQLManager: This transfer can be faster! Use the --direct

    同时,值得注意的信息有:direct模式支持全部列导入的模式

  3. 对各种数据库的支持
    这里写图片描述

增量导入

上面所介绍的数据导入方式都是:全量的导入方式

  1. 增量导入介绍
    这里写图片描述

  2. 增量导入的使用

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp \
    -m 1 \
    --mapreduce-job-name emp-all \
    --columns "EMPNO,ENAME,JOB,SAL,COMM" \
    --target-dir EMP_APPEND \
    --fields-terminated-by '\t' \
    --null-non-string '0' \
    --null-string '' \
    --check-column EMPNO \
    --incremental append \
    --last-value 7900

    –last-value 7900 表示只取比7900大的数据,进行导入

    注意
    –incremental append 与 –delete-target-dir之间不能共用,因为是互斥的

导入MySQL数据到Hive表

  1. 使用参数–create-hive-table导入

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp \
    -m 1 \
    --delete-target-dir \
    --hive-import \
    --create-hive-table \
    --hive-table emp_import

    报错:
    这里写图片描述
    说是找不到类,Jar包缺失

    解决办法:

    $>cp $HIVE_HOME/lib/hive-common-1.1.0-cdh5.7.0.jar $SQOOP_HOME/lib
    $>cp $HIVE_HOME/lib/hive-shims-* $SQOOP_HOME/lib

    重新导入

    查看导入到Hive表的表结构:

    hive>desc emp_import;

    会发现有些字段的类型发生了改变,从double类型变成了int类型

  2. 使用–hive-import参数导入
    删除Hive表之后,再度执行一次:

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp \
    -m 1 \
    --delete-target-dir \
    --hive-import \
    --hive-table emp_import

    补充

    • –create-hive-table 生产上不建议使用,字段类型和我们自己预想会有差别
      而且只能执行一次(再执行一次,会报表已经存在的错误)
    • –hive-import 在导入的时候,会默认去读Hive的default数据库
      –hive-table 不需要自己先去Hive中创建表,执行的时候,会自动帮我们去创建相应的表

导入分区表到Hive中

  1. 介绍
    这里写图片描述

  2. 分区表导入
    增量导入的方式(综合前面的import使用命令)

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp \
    --mapreduce-job-name emp-all \
    --fields-terminated-by '\t' \
    --null-non-string '0' \
    --null-string '' \
    --check-column EMPNO \
    --incremental append \
    --last-value 7900 \
    --hive-import \
    --hive-table emp_import \
    --hive-partition-key 'event_month' \
    --hive-partition-value '2017-10-08' 
  3. 导入成功
    这里写图片描述

Sqoop export

导出HDFS数据到MySQL

  1. 创建MySQL表
    导入数据到MySQL之前,需要现在MySQL上创建一个表
    导入一个空表,但是有表结构

    mysql>create table emp_demo as select * from emp where 1=2;
    mysql>select * from emp_demo;
  2. 导出
    导出之前,先从MySQL全量导入一张表到HDFS中,并命名为emp

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp \
    --target-dir emp \
    --fields-terminated-by '\t'

    这里写图片描述

    开始导出:

    sqoop export \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp_demo \
    --fields-terminated-by '\t' \
    --export-dir /user/hadoop/emp
  3. 成功导出到MySQL
    这里写图片描述

    注意每操作一次,数据就会直接叠加上去

导出Hive数据到MySQL

  1. 前置准备
    事先先导入数据到Hive表中,自己设置分隔符

    sqoop import \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp \
    --fields-terminated-by '\t' \
    --delete-target-dir \
    --hive-import \
    --hive-table emp_import
  2. 导出

    sqoop export \
    --connect jdbc:mysql://localhost:3306/sqoop \
    --username root \
    --password root \
    --table emp_demo \
    --export-dir /user/hive/warehouse/emp_import \
    --fields-terminated-by '\t' \
    -m 1

    这里写图片描述

    注意导出的时候,分隔符需要自己去设置,不然又要对不上,可能会报错

eval与options-file

eval的使用

执行一个SQL语句,并将结果展示出来在控制台上

```
sqoop eval \
--connect jdbc:mysql://localhost:3306/sqoop \
--username root \
--password root \
--query "select * from emp where deptno=10"
```

这里写图片描述

options-file的使用

在工作中推荐这样子使用

```
$>vi emp.opt
import
--connect 
jdbc:mysql://localhost:3306/sqoop 
--username 
root 
--password 
root 
--table 
emp 
-m 
1 
--delete-target-dir  
--target-dir 
EMP_OPTIONS_FILE 
```

执行sqoop
$>sqoop –options-file emp.opt

执行成功:
这里写图片描述

Sqoop job

sqoop job --create myjob  -- \
import --connect jdbc:mysql://localhost:3306/sqoop \
--username root \
--password root \
--delete-target-dir \
--table emp

$>sqoop job --list             列出创建的sqoopjob
$>sqoop job --show myjob
$>sqoop job --exec myjob           执行创建的job
$>hadoop fs -text emp/part*        查看HDFS上的数据

sqoop job创建成功,可以执行:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值