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

来源:互联网 发布:下载微博软件 编辑:程序博客网 时间:2024/06/05 23:48

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

Sqoop import

Sqoop import命令详解

  1. 如何查看帮助

    • 帮助文档
      http://archive.cloudera.com/cdh5/cdh/5/sqoop-1.4.6-cdh5.7.0/SqoopUserGuide.html
      建议:sqoop的使用不看官方文档,太乱
    • 直接使用 –help 命令进行查看
  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.optimport--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创建成功,可以执行:

这里写图片描述

原创粉丝点击