• 大数据之sqoopCDH 备份


    Sqoop课程笔记

    一、概述

    1、什么是sqoop?

    Hadoop的优势在于对数据的存储和处理,相比以前传统的数据库,在处理较较多的数据时,传统数据行业通过提升单机性能以提高处理性能,而且性价比随着性能提高越来越低,在场景下派生出的大数据行业。

    同样的数据处理,hadoop无论是处理的性能和成本都远低于传统通过单机处理,但是从传统的数据处理切换到新生的hadoop平台,避免不了有数据迁移的过程,需要将传统数据按照hadoop的规则进行转换,中间需要一个转换的工具,由此派生出sqoop这样一个优秀的工具,不仅可以将关系数据库(oracle、mysql、postgresql等)数据转换到hadoop中进行处理,同样可以将hadoop数据处理的结果导入到关系数据库中。

    2、sqoop的应用场景

    不用说,既然是一个转换工具,在关系数据库和hadoop之间数据的相互转换就少不了。但是不是所有的数据都适合于hadoop处理,比如安全性高的银行业以及结构化很强的数据就不是很适合使用hadoop进行处理、存储。

    3、sqoop的版本问题

    sqoop有两个版本,完全不兼容,可以从版本号进行区分,1.4.x为sqoop1,1.99.x为sqoop2。

    4、sqoop的地位

    唯我独尊!

    二、架构

    1、sqoop整体架构

    clip_image002

    sqoop架构非常简单,是hadoop生态系统的架构最简单的框架,sqoop1由client端直接接入hadoop,任务通过解析生成对应的maprecue执行。

    2、导入

    clip_image004

    3、导出

    clip_image006

    3、执行流程

    1)读取要导入数据的表结构,生成运行类,默认是QueryResult,打成jar包,然后提交给Hadoop

    2)设置好job,主要也就是设置好的各个参数

    3)这里就由Hadoop来执行MapReduce来执行Import命令了,

          a.首先要对数据进行切分,也就是DataSplit

              DataDrivenDBInputFormat.getSplits(JobContext job)

          b.切分好范围后,写入范围,以便读取

    DataDrivenDBInputFormat.write(DataOutput output) 这里是lowerBoundQuery and  upperBoundQuery

          c.读取以上2)写入的范围

              DataDrivenDBInputFormat.readFields(DataInput input)

    d.然后创建RecordReader从数据库中读取数据

    DataDrivenDBInputFormat.createRecordReader(InputSplit split,TaskAttemptContext context)

    e.创建Map

    TextImportMapper.setup(Context context)

    f.RecordReader一行一行从关系型数据库中读取数据,设置好Map的Key和Value,交给Map

    DBRecordReader.nextKeyValue()

    g.运行map

    TextImportMapper.map(LongWritable key, SqoopRecord val, Context context)

    最后生成的Key是行数据,由QueryResult生成,Value是NullWritable.get()

    三、安装

    1、下载地址

    sqoop1:

    http://archive.cloudera.com/cdh5/cdh/5/sqoop-1.4.5-cdh5.4.4.tar.gz

    sqoop2:

    http://archive.cloudera.com/cdh5/cdh/5/sqoop2-1.99.5-cdh5.4.4.tar.gz

    2、基于CDH的安装

    too simple!

    CDH在安装了sqoop2之后就1和2 都有了。

    3、原生安装

    a.解压对应压缩包

    b.重命名sqoop-1.4.5-cdh5.4.4/sqoop-env-template.sh 为sqoop-env.sh

    配置以下参数即可:

    clip_image008

    c.配置环境变量
    vi /etc/profile

    export PATH=$PATH: /opt/sqoop-1.4.5-cdh5.4.4/bin

    source /etc/profile

    4、注意事项

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

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

    四、使用

    1、工具选项

    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>

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

    2、数据导入工具import

    所谓import工具,是将关系数据库数据导入到Hadoop平台,基本命令选项如下:

    选项

    义说

    --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的该类列的值

    --import-all-tables

    导入所有表

    应用场景

    a. 导入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

    b. 指定map个数

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

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

    c. 增量导入

    参数

    说明

    –check-column (col)

    用来作为判断的列名,如id

    –incremental (mode)

    append:追加,比如对大于last-value指定的值之后的记录进行追加导入。lastmodified:最后的修改时间,追加last-value指定的日期之后的记录

    –last-value (value)

    指定自从上次导入后列的最大值(大于该指定的值),也可以自己设定某一值

    同一个目录进行数据追加

    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

    d. 指定条件

    指定条件时需要注意两点:第一、不能含中文 ;第二、"job='CTO'"

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

    e. 启用压缩

    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 (直接指定压缩编码)

    f. 导入空值处理

    字符串类型:

    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 "="

    g. 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 ","

    h. 导入hive

    参数

    说明

    --hive-home <dir>

    直接指定hive安装目录

    --hive-import

    使用默认分隔符导入hive

    --hive-overwrite

    覆盖掉在hive表中已经存在的数据

    --create-hive-table

    生成与关系数据库表的表结构对应的HIVE表。如果表不存在,则创建,如果存在,报错。

    --hive-table <table-name>

    导入到hive指定的表,可以创建新表

    --hive-drop-import-delims

    导入数据到hive时,删除字符串字段中的 , , and 1 

    --hive-delims-replacement

    用自定义的字符串替换掉数据中的 , , and 1等字符

    --hive-partition-key

    创建分区,后面直接跟分区名即可,创建完毕后,通过describe 表名可以看到分区名,默认为string型

    --hive-partition-value <v>

    该值是在导入数据到hive中时,与–hive-partition-key设定的key对应的value值。

    --map-column-hive <map>

    生成hive表时,可以更改生成字段的数据类型,格式如:–map-column-hive LAST_ACCESS_TIME=string

    --fields-terminated-by

    指定分隔符(hive默认的分隔符是/u0001)

    追加数据

    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当前用户目录下不能存在表目录

    复制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 "001" --lines-terminated-by " "

    i. 导入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

    3、数据导出工具export

    所谓export,是将HDFS平台的数据导入到关系数据库,基本命令选项如下:

    选项

    义说

    --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

    使用批量模式导出

    场景应用:

    a. 导出到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

    b. 指定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

    c. 插入和更新

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

    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

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

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

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

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

    e. HBasemysql

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

    f. 导出空值处理

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

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

    4、其他常用工具介绍

    1)Codegen

    参数

    –bindir <dir>

    指定生成的java文件、编译成的class文件及将生成文件打包为JAR的JAR包文件输出路径

    –class-name <name>

    设定生成的Java文件指定的名称

    –outdir <dir>

    生成的java文件存放路径

    –package-name<name>

    包名,如cn.cnnic,则会生成cn和cnnic两级目录,生成的文件(如java文件)就存放在cnnic目录里

    –input-null-non-string<null-str>

    在生成的java文件中,可以将null字符串设为想要设定的值(比如空字符串’’)

    –input-null-string<null-str>

    同上,设定时,最好与上面的属性一起设置,且设置同样的值(比如空字符串等等)。

    –map-column-java<arg>

    数据库字段在生成的java文件中会映射为各种属性,且默认的数据类型与数据库类型保持对应,比如数据库中某字段的类型为bigint,则在Java文件中 的数据类型为long型,通过这个属性,可以改变数据库字段在java中映射的数据类型,格式如:–map-column-java DB_ID=String,id=Integer

    –null-non-string<null-str>

    在生成的java文件中,比如TBL_ID==null?”null”:””,通过这个属性设置可以将null字符串设置为其它值如ddd,TBL_ID==null “ddd”:””

    –null-string<null-str>

    同上,使用的时候最好和上面的属性一起用,且设置为相同的值

    –table <table-name>

    对应关系数据库的表名,生成的java文件中的各属性与该表的各字段一一对应。

    编译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

    5、常见处理

    1)事务处理

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

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

    --clear-staging-table

    2)字段名称问题

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

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

    ordersortreducecastdirectory

    3)参数处理

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

    6、sqoop2架构

    clip_image010

  • 相关阅读:
    linux中WDCP的日志彻底删除技巧
    jquery中页面Ajax方法$.load的功能
    PHP与MYSQL中UTF8 中文排序例子
    mysql获取group by的总记录行数方法
    jquery获取radio值
    python中数组与多维数组用法介绍
    php开启与关闭错误提示
    asp.net url址址中中文汉字参数传递乱码解决方法
    js事件之event.preventDefault()与(www.111cn.net)event.stopPropagation()用法区别
    css中position:fixed实现div居中
  • 原文地址:https://www.cnblogs.com/chaoren399/p/4783630.html
Copyright © 2020-2023  润新知