• 大数据之sqoop


    一、安装:


    1 解压然后把mysql的驱动放在$SQOOP_HOME/lib 目录中
    2. conf/sqoop-en.sh

    export HADOOP_COMMON_HOME=/home/hadoop/hadoop/hadoop-2.3.0
    export HADOOP_MAPRED_HOME=/home/hadoop/hadoop/hadoop-2.3.0

    注意事项
       1.数据库驱动:在执行sqoop命令的client的sqoop lib目录下面放入驱动jar包即可(CDH默认在/opt/cloudera/parcels/CDH/lib/sqoop/lib/目录),驱动版本使用mysql-connector-java-5.1.32-bin.jar以上。

       2.client端JDK版本1.6~1.7,并且配置环境变量


    命令

    二、sqoop工具import

    sqoop工具汇总

    选项

    含义说明

    --connect <jdbc-uri>

    指定JDBC连接字符串

    --connection-manager <class-name>

    指定要使用的连接管理器类

    --driver <class-name>

    指定要使用的JDBC驱动类

    --hadoop-mapred-home <dir>

    指定$HADOOP_MAPRED_HOME路径

    --help

    万能帮助

    --password-file

    设置用于存放认证的密码信息文件的路径

    -P

    从控制台读取输入的密码

    --password <password>

    设置认证密码

    --username <username>

    设置认证用户名

    --verbose

    打印详细的运行信息

    --connection-param-file <filename>

    可选,指定存储数据库连接参数的属性文件

    选项

    含义说明

    --append

    将数据追加到HDFS上一个已存在的数据集上

    --as-avrodatafile

    将数据导入到Avro数据文件

    --as-sequencefile

    将数据导入到SequenceFile

    --as-textfile

    将数据导入到普通文本文件(默认)

    --boundary-query <statement>

    边界查询,用于创建分片(InputSplit)

    --columns <col,col,col…>

    从表中导出指定的一组列的数据

    --delete-target-dir

    如果指定目录存在,则先删除掉

    --direct

    使用直接导入模式(优化导入速度)

    --direct-split-size <n>

    分割输入stream的字节大小(在直接导入模式下)

    --fetch-size <n>

    从数据库中批量读取记录数

    --inline-lob-limit <n>

    设置内联的LOB对象的大小

    -m,--num-mappers <n>

    使用n个map任务并行导入数据

    -e,--query <statement>

    导入的查询语句

    --split-by <column-name>

    指定按照哪个列去分割数据

    --table <table-name>

    导入的源表表名

    --target-dir <dir>

    导入HDFS的目标路径

    --warehouse-dir <dir>

    HDFS存放表的根路径

    --where <where clause>

    指定导出时所使用的查询条件

    -z,--compress

    启用压缩

    --compression-codec <c>

    指定Hadoop的codec方式(默认gzip)

    --null-string <null-string>

    果指定列为字符串类型,使用指定字符串替换值为null的该类列的值

    --null-non-string <null-string>

    如果指定列为非字符串类型,使用指定字符串替换值为null的该类列的值

    2.把mysql中的表复制到hdfs中

    默认情况下,使用导入语句,直接导入到HDFS当前用户的目录下面,生成相应的表明,文件夹名称默认为表名。

    默认(在行命令的机器上添加驱动):

    sqoop import --connect jdbc:mysql://crxy172:3306/testsqoop --username 'root' --password '123456' --table info

    指定到入目录:

    sqoop import --connect jdbc:mysql://crxy172:3306/testsqoop --username 'root' --password '123456' --table info –target-dir info_dir

    如果目录以及存在,使用--delete-target-dir:

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --delete-target-dir

    指定map个数

    默认启动4个进程导入(map数量),可以设置 1表示不并行

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1

    同一个目录进行数据追加

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1 --append

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1 --append --check-column 'id' --incremental append --last-value 23

    指定条件

    注意两点:

    第一、不能含中文;第二、"job='CTO'"

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1 --append --where "job='CTO'" (可以使用模糊批量匹配)

    启用压缩

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1 --append --where "job like 'CTO'" -z (默认Gzip压缩)

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root -password 123456 --table info -m 1 --append --where "job like 'CTO'" -z --compression-codec org.apache.hadoop.io.compress.SnappyCodec (直接指定压缩编码)

    导入空值处理

    字符串类型:

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1 --append --null-string "--" (不可以,不能是关键字符)

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1 --append --null-string "*"

    非字符串类型:

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info -m 1 --append --null-string "*" --null-non-string "="

     

    3.把mysql中的表复制到hive中

    Sql导入

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username 'root' --password '123456' --query "select name,job from info where $CONDITIONS" -m 1 --target-dir queryinfo --fields-terminated-by "," --split-by "id" (必须指定-m 、--fields-terminated-by 、--split-by)

    追加数据

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --hive-import -m 1

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --hive-import -m 1 --fields-terminated-by "|" (如果数据表已经存在,并且字段不一样,指定分隔符时会把加到第一列中,不指定时取mysql第一列id值加到hive中)

    覆盖数据

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --hive-import -m 1 --fields-terminated-by "|" --hive-overwrite (只覆盖数据,不覆盖表结构)

    创建hive表(自定义表名)

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --hive-import -m 1 --fields-terminated-by "|" --hive-table "info_t" --hive-overwrite (如果表已经存在,不会删除,只能重新定义表名)

    注意:如果导出过程失败,需要到HDFS目录当前用户目录下将临时目录删除,hdfs当前用户目录下不能存在表目录,可以另外指定--target-dir --delete-target-dir

     

    复制mysql的表结构到Hive

    sqoop create-hive-table --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --hive-table users --fields-terminated-by "001" --lines-terminated-by " " (不复制数据)

    导出所有的表到hive

    sqoop import-all-tables --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --hive-import --fields-terminated-by "u0001" --lines-terminated-by " "

    4.把mysql中的表复制到HBase

     

    选项                            说明

    --hbase-table 指定导入到hbase中的表

    --column-family 创建列族

    --hbase-row-key <id> 以id字段作为key

    --hbase-create-table 创建hbase表

    导入hive时,默认以主键作为key,没有主键使用--split-by ,暂时处理不了联合主键情况。

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --hbase-create-table --hbase-row-key id --hbase-table info --column-family xxx

    三、sqoop工具export

    选项

    含义说明

    --validate <class-name>

    启用数据副本验证功能,仅支持单表拷贝,可以指定验证使用的实现类

    --validation-threshold <class-name>

    指定验证门限所使用的类

    --direct

    使用直接导出模式(优化速度)

    --export-dir <dir>

    导出过程中HDFS源路径

    --m,--num-mappers <n>

    使用n个map任务并行导出

    --table <table-name>

    导出的目的表名称

    --call <stored-proc-name>

    导出数据调用的指定存储过程名

    --update-key <col-name>

    更新参考的列名称,多个列名使用逗号分隔

    --update-mode <mode>

    指定更新策略,包括:updateonly(默认)、allowinsert

    --input-null-string <null-string>

    使用指定字符串,替换字符串类型值为null的列

    --input-null-non-string <null-string>

    使用指定字符串,替换非字符串类型值为null的列

    --staging-table <staging-table-name>

    在数据导出到数据库之前,数据临时存放的表名称

    --clear-staging-table

    清除工作区中临时存放的数据

    --batch

    使用批量模式导出

    1.把HDFS中的表数据复制到mysql中

    导出到mysql(默认使用逗号作为分隔)

    直接导出,导出时字段需要一一对应

    sqoop export --connect jdbc:mysql://crxy172:3306/test --username root --password 123456 --table info --export-dir export

    乱码问题

    sqoop export --connect "jdbc:mysql://crxy172:3306/test?useUnicode=true&characterEncoding=utf-8" --username root --password 123456 --table info --export-dir export

    指定map数

    sqoop export --connect "jdbc:mysql://crxy172:3306/test?useUnicode=true&characterEncoding=utf-8" --username root --password 123456 --table info --export-dir export -m 1

    插入和更新

    如果存在就更新,不存在就插入

    sqoop export --connect "jdbc:mysql://crxy172:3306/test?useUnicode=true&characterEncoding=utf-8" --username root --password 123456 --table info --export-dir export -m 1 --update-key id --update-mode allowinsert

    指定分隔符(和导入区别开来)

    导入导出的事务是以Mapper任务为单位。

    注意:1--fields-terminated-by导入数据时(import)字段分割、行分割

    2 --input-fields-terminated-by解析HDFS上面的数据到数据库时使用参数

     

    2.从HBase到mysql

    没有直接导出方案。只能使用以下步骤,先通过mapreduce写入到HDFS在通过export工具导入到mysql。

    导出空值处理

    --input-null-string string类型使用参数

    --input-null-non-string <null-string> 非string类型使用参数

    四、其他工具使用

     

    1.

    Codegen

    编译jar包和record类

    sqoop codegen --connect jdbc:mysql://crxy172:3306/test --username 'root' --password '123456' --table info --bindir sqoopjar

    直接使用已经编译好的类

    sqoop import --connect jdbc:mysql://crxy172:3306/test --username 'root' --password '123456' --table info --class-name info --jar-file info.jar

    导出过程生成的和Codegen生成代码区别:

    a.导出过程生成代码纯属于副产品,无法控制,默认和表名一样

    b.Codegen可以指定生成代码的参数,可以用来重新生成导入过程的源代码

    主要作用:a) 可以将需要导入的数据事先序列化到HDFS中

    b) 检查数据表,采用最合适的数据类型

    c) 如果事先已经将数据序列化到了HDFS,可以采用该方式读取出来

    2.

    Eval

    直接使用sql查询mysql

    sqoop eval --connect jdbc:mysql://crxy172:3306/test --username 'root' --password '123456' --query "select * from info"

    插入操作:

    sqoop eval --connect "jdbc:mysql://crxy172:3306/test?useUnicode=true&characterEncoding=utf-8" --username 'root' --password '123456' --query "insert into info values (24,'超人','飞人',1)"

    3.

    job生成
    ?创建job:--create
    ?删除job:--delete
    ?执行job:--exec
    ?显示job:--show
    ?列出job:--list

        sqoop job --create myjob -- import --connect jdbc:mysql://crxy172:3306/test --username 'root' --password '123456' --table info

      sqoop job --list
      sqoop job --exec myjob

    五、常见问题

    事务处理

    由于线程的并发性,一个导入操作可能并不是原子性的。会一次statement插入100条数据,然后每100个statement提交一次,所以一次就会提交10000条数据。如果tasks失败了(由于网络问题或者其它的问题),这些tasks会尝试从它们开始导入数据的地方重新开始,会插入重复的记录。这次写数据的时候,Sqoop不提防这种潜在的问题。Sqoop提供的一个解决办法就是使用中间表,参数为:

    --staging-table <staging-table-name>

    --clear-staging-table

     

    字段名称问题

    sqoop 从mysql导入hive的字段名称问题

    hive中有些关键字限制,因此有些字段名称在mysql中可用,但是到了hive就不行。部分不能在hive中使用的字段名称

    order;sort;reduce;cast;directory

    参数处理

    部分字段含有特殊字符时需要添加双引号,单双引号都有时,一般采用双引号套单引号。

  • 相关阅读:
    List注意点【修改】
    最近遇到的笔试面试题(3)
    关于阅读
    各种语言
    最近遇到的笔试面试题(2)
    最近遇到的笔试面试题(1)
    5自由落体运动
    4 1000以内完数
    3水仙花数
    判断101-200之间的素数
  • 原文地址:https://www.cnblogs.com/chaoren399/p/4782783.html
Copyright © 2020-2023  润新知