您的位置:首页 > 运维架构

Sqoop使用与原理

2020-08-23 22:53 1861 查看

目录

一、概述

二、工作机制

1、导入

2、导出

三、安装

1、前提概述

2、软件下载

3、安装步骤

4、 修改配置文件

5、拷贝JDBC驱动

6、配置系统环境变量

7、验证安装是否成功

 8、测试Sqoop是否能够成功连接数据库

四、Sqoop的基本命令

基本操作

五、Sqoop的数据导入

1、从RDBMS导入到HDFS中

2、把MySQL数据库中的表数据导入到Hive中

3、把MySQL数据库中的表数据导入到hbase

一、概述

sqoop 是 apache 旗下一款“Hadoop 和关系数据库服务器之间传送数据”的工具。

sqoop(SQL TO HADOOP),是hadoop的协作框架之一

sqoop以Hadoop 为主体,RDBMS为客体,使用sqoop的主要功能

[code]对于hadoop进行大数据处理的数据来源主要有两部分
(1)关系数据库,RDBMS(Oracle,MySQL,DB2…)
(2)文件(apache,nginx日志数据)
hadoop 对于大数据的处理,是将数据存储在HDFS上,sqoop的功能就是将RDBMS中的数据导入HDFS,或者将HDFS中的数据导出到RDBMS。对于文件系统中的数据导入HDFS,可以使用Flume(实时抽取)。

核心的功能有两个:【导入、迁入】、【导出、迁出】

导入数据:MySQL,Oracle 导入数据到 Hadoop 的 HDFS、HIVE、HBASE 等数据存储系统

导出数据:从 Hadoop 的文件系统中导出数据到关系数据库 mysql 等 Sqoop 的本质还是一个命令行工具,和 HDFS,Hive 相比,并没有什么高深的理论。

sqoop:

工具   ===>  本质就是迁移数据, 迁移的方式:就是把sqoop的迁移命令转换成MR程序

hive   === > 工具:本质就是执行计算,依赖于HDFS存储数据,把SQL转换成MR程序

 

二、工作机制

将导入或导出命令翻译成 MapReduce 程序来实现 在翻译出的 MapReduce 中主要是对 InputFormat 和 OutputFormat 进行定制

1、导入

在导入开始之前,Sqoop使用JDBC来检查将要导入的表。他检索出表中所有的列以及列的SQL数据类型。这些SQL类型(VARCHAR、INTEGER)被映射到Java数据类型(String、Integer等),在MapReduce应用中将使用这些对应的java类型来保存字段的值。Sqoop的代码生成器使用这些信息来创建对应表的类,用于保存从表中抽取的记录。例如前面提到过的example类。

[code]对于导入来说,更关键的是DBWritable接口的序列化方法,这些方法能使Widget类和JDBC进行交互:

​ Public void readFields(resultSet _dbResults)throws SQLException;
Public void write(PreparedStatement _dbstmt)throws SQLException;

JDBC的ResultSet接口提供了一个用户从检查结果中检索记录的游标;这里的readFields()方法将用ResultSet中一行数据的列来填充Example对象的字段。

Sqoop启动的MapReduce作业用到一个InputFormat,他可以通过JDBC从一个数据库表中读取部分内容。Hadoop提供的DataDriverDBInputFormat能够为几个Map任务对查询结果进行划分。为了获取更好的导入性能,查询会根据一个“划分列”来进行划分的。Sqoop会选择一个合适的列作为划分列(通常是表的主键)。

在生成反序列化代码和配置InputFormat之后,Sqoop将作业发送到MapReduce集群。Map任务将执行查询并将ResultSet中的数据反序列化到生成类的实例,这些数据要么直接保存在SequenceFile文件中,要么在写到HDFS之前被转换成分割的文本。

Sqoop不需要每次都导入整张表,用户也可以在查询中加入到where子句,以此来限定需要导入的记录:Sqoop –query (SQL)。

​ 导入和一致性:在向HDFS导入数据时,重要的是要确保访问的是数据源的一致性快照。从一个数据库中并行读取数据的MAP任务分别运行在不同的进程中。因此,他们不能共享一个数据库任务。保证一致性的最好方法就是在导入时不允许运行任何进行对表中现有数据进行更新。

2、导出

Sqoop导出功能的架构与其导入功能非常相似,在执行导出操作之前,sqoop会根据数据库连接字符串来选择一个导出方法。一般为jdbc。然后,sqoop会根据目标表的定义生成一个java类。这个生成的类能够从文本文件中解析记录,并能够向表中插入类型合适的值。接着会启动一个MapReduce作业,从HDFS中读取源数据文件,使用生成的类解析记录,并且执行选定的导出方法。

基于jdbc的导出方法会产生一批insert语句,每条语句都会向目标表中插入多条记录。多个单独的线程被用于从HDFS读取数据并与数据库进行通信,以确保涉及不同系统的I/O操作能够尽可能重叠执行。

虽然HDFS读取数据的MapReduce作业大多根据所处理文件的数量和大小来选择并行度(map任务的数量),但sqoop的导出工具允许用户明确设定任务的数量。由于导出性能会受并行的数据库写入线程数量的影响,所以sqoop使用combinefileinput类将输入文件分组分配给少数几个map任务去执行。

系统使用固定大小的缓冲区来存储事务数据,这时一个任务中的所有操作不可能在一个事务中完成。因此,在导出操作进行过程中,提交过的中间结果都是可见的。在导出过程完成前,不要启动那些使用导出结果的应用程序,否则这些应用会看到不完整的导出结果。

更有问题的是,如果任务失败,他会从头开始重新导入自己负责的那部分数据,因此可能会插入重复的记录。当前sqoop还不能避免这种可能性。在启动导出作业前,应当在数据库中设置表的约束(例如,定义一个主键列)以保证数据行的唯一性。

​ Sqoop还可以将存储在SequenceFile中的记录导出到输出表,不过有一些限制。SequenceFile中可以保存任意类型的记录。Sqoop的导出工具从SequenceFile中读取对象,然后直接发送到OutputCollector,由他将这些对象传递给数据库导出OutputFormat。为了能让Sqoop使用,记录必须被保存在SequenceFile键值对格式的值部分,并且必须继承抽象类com.cloudera.sqoop.lib.SqoopRecord。

三、安装

1、前提概述

将来sqoop在使用的时候有可能会跟那些系统或者组件打交道?

HDFS, MapReduce, YARN, ZooKeeper, Hive, HBase, MySQL

sqoop就是一个工具, 只需要在一个节点上进行安装即可。

[code]补充一点: 如果你的sqoop工具将来要进行hive或者hbase等等的系统和MySQL之间的交互
你安装的SQOOP软件的节点一定要包含以上你要使用的集群或者软件系统的安装包

补充一点: 将来要使用的azakban这个软件 除了会调度 hadoop的任务或者hbase或者hive的任务之外, 还会调度sqoop的任务
azkaban这个软件的安装节点也必须包含以上这些软件系统的客户端/2、

2、软件下载

[code]下载地址http://mirrors.hust.edu.cn/apache/

sqoop版本说明
绝大部分企业所使用的sqoop的版本都是 sqoop1
sqoop-1.4.6 或者 sqoop-1.4.7 它是 sqoop1
sqoop-1.99.4----都是 sqoop2
此处使用sqoop-1.4.6版本sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz

 

3、安装步骤

1)上传安装包sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz到hadoop102的/opt/software路径中

2)解压sqoop安装包到指定目录,如:

[code][Mark@hadoop102 software]$ tar -zxf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz -C /opt/module/

3)解压sqoop安装包到指定目录,如:

[code][Mark@hadoop102 module]$ mv sqoop-1.4.6.bin__hadoop-2.0.4-alpha/ sqoop

4、 修改配置文件

1) 进入到/opt/module/sqoop/conf目录,重命名配置文件

[code][Mark@hadoop102 conf]$ mv sqoop-env-template.sh sqoop-env.sh

2) 修改配置文件

[code][Mar@hadoop102 conf]$ vim sqoop-env.sh

增加如下内容

[code]export HADOOP_COMMON_HOME=/opt/module/hadoop-3.1.3

#Set path to where hadoop-*-core.jar is available
export HADOOP_MAPRED_HOME=/opt/module/hadoop-3.1.3

#set the path to where bin/hbase is available
export HBASE_HOME=/home/hadoop/apps/hbase-1.2.6

#Set the path to where bin/hive is available
export HIVE_HOME=/opt/module/hive

export ZOOKEEPER_HOME=/opt/module/zookeeper-3.5.7

#Set the path for where zookeper config dir is
export ZOOCFGDIR=/opt/module/zookeeper-3.5.7/conf

 为什么在sqoop-env.sh 文件中会要求分别进行 common和mapreduce的配置呢???

[code]在apache的hadoop的安装中;四大组件都是安装在同一个hadoop_home中的
但是在CDH, HDP中, 这些组件都是可选的。
在安装hadoop的时候,可以选择性的只安装HDFS或者YARN,
CDH,HDP在安装hadoop的时候,会把HDFS和MapReduce有可能分别安装在不同的地方

5、拷贝JDBC驱动

1)将mysql-connector-java-5.1.48.jar 上传到/opt/software路径

2)进入到/opt/software/路径,拷贝jdbc驱动到sqoop的lib目录下。

[code][Mar@hadoop102 software]$ cp mysql-connector-java-5.1.48.jar /opt/module/sqoop/lib/

6、配置系统环境变量

[code][Mark@hadoop102 ~]$ vi /etc/profile.d/my_eny

#Sqoop
export SQOOP_HOME=/opt/module/sqoop-1.4.6
export PATH=$PATH:$SQOOP_HOME/bin

保存退出使其立即生效

[code][Mark@Hadoop102~]source /etc/profile.d/my_eny

7、验证安装是否成功

 sqoop-version 或者 sqoop version

 8、测试Sqoop是否能够成功连接数据库

[code][Mark@hadoop102 sqoop]$ bin/sqoop list-databases
--connect
jdbc:mysql://hadoop102:3306/
--username root
--password 000000

出现如下输出:

[code]information_schema
metastore
mysql
oozie
performance_schema

四、Sqoop的基本命令

基本操作

首先,我们可以使用 sqoop help 来查看,sqoop 支持哪些命令

[code][Mark@hadoop102 ~]$ sqoop help
Warning: /home/hadoop/apps/sqoop-1.4.6/../hcatalog does not exist! HCatalog jobs will fail.
Please set $HCAT_HOME to the root of your HCatalog installation.
Warning: /home/hadoop/apps/sqoop-1.4.6/../accumulo does not exist! Accumulo imports will fail.
Please set $ACCUMULO_HOME to the root of your Accumulo installation.
18/04/12 13:37:19 INFO sqoop.Sqoop: Running Sqoop version: 1.4.6
usage: sqoop COMMAND [ARGS]

Available commands:
codegen            Generate code to interact with database records
create-hive-table  Import a table definition into Hive
eval               Evaluate a SQL statement and display the results
export             Export an HDFS directory to a database table
help               List available commands
import             Import a table from a database to HDFS
import-all-tables  Import tables from a database to HDFS
import-mainframe   Import datasets from a mainframe server to HDFS
job                Work with saved 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
version            Display version information

See 'sqoop help COMMAND' for information on a specific command.

五、Sqoop的数据导入

“导入工具”导入单个表从 RDBMS 到 HDFS。表中的每一行被视为 HDFS 的记录。所有记录 都存储为文本文件的文本数据(或者 Avro、sequence 文件等二进制数据) 

1、从RDBMS导入到HDFS中

语法格式

[code]sqoop import (generic-args) (import-args)

常用参数

[code]--connect <jdbc-uri> jdbc 连接地址
--connection-manager <class-name> 连接管理者
--driver <class-name> 驱动类
--hadoop-mapred-home <dir> $HADOOP_MAPRED_HOME
--help help 信息
-P 从命令行输入密码
--password <password> 密码
--username <username> 账号
--verbose 打印流程信息
--connection-param-file <filename> 可选参数

示例

普通导入:导入mysql库中的help_keyword的数据到HDFS上

导入的默认路径:/user/hadoop/help_keyword

[code]sqoop import   \
--connect jdbc:mysql://hadoop1:3306/mysql   \
--username root  \
--password root   \
--table help_keyword   \
-m 1

导入: 指定分隔符和导入路径

[code]sqoop import   \
--connect jdbc:mysql://hadoop1:3306/mysql   \
--username root  \
--password root   \
--table help_keyword   \
--target-dir /user/hadoop11/my_help_keyword1  \
--fields-terminated-by '\t'  \
-m 2

导入数据:带where条件

[code]sqoop import   \
--connect jdbc:mysql://hadoop1:3306/mysql   \
--username root  \
--password root   \
--where "name='STRING' " \
--table help_keyword   \
--target-dir /sqoop/hadoop11/myoutport1  \
-m 1

查询指定列

[code]sqoop import   \
--connect jdbc:mysql://hadoop1:3306/mysql   \
--username root  \
--password root   \
--columns "name" \
--where "name='STRING' " \
--table help_keyword  \
--target-dir /sqoop/hadoop11/myoutport22  \
-m 1
selct name from help_keyword where name = "string"

导入:指定自定义查询SQL

[code]sqoop import   \
--connect jdbc:mysql://hadoop1:3306/  \
--username root  \
--password root   \
--target-dir /user/hadoop/myimport33_1  \
--query 'select help_keyword_id,name from mysql.help_keyword where $CONDITIONS and name = "STRING"' \
--split-by  help_keyword_id \
--fields-terminated-by '\t'  \
-m 4

在以上需要按照自定义SQL语句导出数据到HDFS的情况下:
1、引号问题,要么外层使用单引号,内层使用双引号,$CONDITIONS的$符号不用转义, 要么外层使用双引号,那么内层使用单引号,然后$CONDITIONS的$符号需要转义
2、自定义的SQL语句中必须带有WHERE \$CONDITIONS

2、把MySQL数据库中的表数据导入到Hive中

Sqoop 导入关系型数据到 hive 的过程是先导入到 hdfs,然后再 load 进入 hive

普通导入:数据存储在默认的default hive库中,表名就是对应的mysql的表名:

[code]sqoop import   \
--connect jdbc:mysql://hadoop1:3306/mysql   \
--username root  \
--password root   \
--table help_keyword   \
--hive-import \
-m 1

导入过程

[code]第一步:导入mysql.help_keyword的数据到hdfs的默认路径
第二步:自动仿造mysql.help_keyword去创建一张hive表, 创建在默认的default库中
第三步:把临时目录中的数据导入到hive表中

指定行分隔符和列分隔符,指定hive-import,指定覆盖导入,指定自动创建hive表,指定表名,指定删除中间结果数据目录

[code]sqoop import  \
--connect jdbc:mysql://hadoop1:3306/mysql  \
--username root  \
--password root  \
--table help_keyword  \
--fields-terminated-by "\t"  \
--lines-terminated-by "\n"  \
--hive-import  \
--hive-overwrite  \
--create-hive-table  \
--delete-target-dir \
--hive-database  mydb_test \
--hive-table new_help_keyword

报错原因是hive-import 当前这个导入命令。 sqoop会自动给创建hive的表。 但是不会自动创建不存在的库

手动创建mydb_test数据块

[code]hive> create database mydb_test;
OK
Time taken: 6.147 seconds
hive>

之后再执行上面的语句没有报错

增量导入

执行增量导入之前,先清空hive数据库中的help_keyword表中的数据

[code]truncate table help_keyword
[code]sqoop import   \
--connect jdbc:mysql://hadoop1:3306/mysql   \
--username root  \
--password root   \
--table help_keyword  \
--target-dir /user/hadoop/myimport_add  \
--incremental  append  \
--check-column  help_keyword_id \
--last-value 500  \
-m 1

3、把MySQL数据库中的表数据导入到hbase

 普通导入

[code]sqoop import \
--connect jdbc:mysql://hadoop1:3306/mysql \
--username root \
--password root \
--table help_keyword \
--hbase-table new_help_keyword \
--column-family person \
--hbase-row-key help_keyword_id

此时会报错,因为需要先创建Hbase里面的表,再执行导入的语句

[code]hbase(main):001:0> create 'new_help_keyword', 'base_info'
0 row(s) in 3.6280 seconds

=> Hbase::Table - new_help_keyword
hbase(main):002:0>

 部分参数说明:

序号 参数 说明
1 —append 将数据追加到HDFS中已经存在的DataSet中,如果使用该参数,sqoop会把数据先导入到临时文件目录,再合并。
2 —as-avrodatafile 将数据导入到一个Avro数据文件中
3 —as-sequencefile 将数据导入到一个sequence文件中
4 —as-textfile 将数据导入到一个普通文本文件中
5 —boundary-query (statement) 边界查询,导入的数据为该参数的值(一条sql语句)所执行的结果区间内的数据。
6 —columns 指定要导入的字段
7 —direct 直接导入模式,使用的是关系数据库自带的导入导出工具,以便加快导入导出过程。
8 —direct-split-size 在使用上面direct直接导入的基础上,对导入的流按字节分块,即达到该阈值就产生一个新的文件
9 —inline-lob-limit 设定大对象数据类型的最大值
10 —m或–num-mappers 启动N个map来并行导入数据,默认4个。
11 —query或—e (statement) 将查询结果的数据导入,使用时必须伴随参—target-dir,—hive-table,如果查询中有where条件,则条件后必须加上$CONDITIONS关键字
12 —split-by <column-name) 按照某一列来切分表的工作单元,不能与—autoreset-to-one-mapper连用(请参考官方文档)
13 —table (table-name) 关系数据库的表名
14 —target-dir (dir) 指定HDFS路径
15 —warehouse-dir (dir) 与14参数不能同时使用,导入数据到HDFS时指定的目录
16 —where 从关系数据库导入数据时的查询条件
17 —z或—compress 允许压缩
18 —compression-codec 指定hadoop压缩编码类,默认为gzip(Use Hadoop codec default gzip)
19 —null-string (null-string) string类型的列如果null,替换为指定字符串
20 —null-non-string (null-string) 非string类型的列如果null,替换为指定字符串
21 —check-column (col) 作为增量导入判断的列名
22 —incremental (mode) mode:append或lastmodified
23 —last-value (value) 指定某一个值,用于标记增量导入的位置
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: