传统的应用程序管理系统,即应用程序与使用RDBMS的关系数据库的交互,是产生大数据的来源之一。由RDBMS生成的这种大数据存储在关系数据库结构中的关系数据库服务器中。
当大数据存储和Hadoop生态系统的MapReduce,Hive,HBase,Cassandra,Pig等分析器出现时,他们需要一种工具来与关系数据库服务器进行交互,以导入和导出驻留在其中的大数据。在这里,Sqoop在Hadoop生态系统中占据一席之地,以便在关系数据库服务器和Hadoop的HDFS之间提供可行的交互。
Sqoop - “SQL到Hadoop和Hadoop到SQL”
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。它由Apache软件基金会提供。
下图描述了Sqoop的工作流程。
导入工具从RDBMS向HDFS导入单独的表。表中的每一行都被视为HDFS中的记录。所有记录都以文本文件的形式存储在文本文件中或作为Avro和Sequence文件中的二进制数据存储。
导出工具将一组文件从HDFS导出回RDBMS。给Sqoop输入的文件包含记录,这些记录在表中被称为行。这些被读取并解析成一组记录并用用户指定的分隔符分隔。
由于Sqoop是Hadoop的子项目,因此它只能在Linux操作系统上运行。按照以下步骤在您的系统上安装Sqoop。
我们可以从以下链接下载最新版本的Sqoop 对于本教程,我们使用1.4.5版本,即sqoop-1.4.5.bin__hadoop-2.0.4-alpha.tar.gz。
以下命令用于提取Sqoop tar球并将其移至“/ usr / lib / sqoop”目录。
$tar -xvf sqoop-1.4.4.bin__hadoop-2.0.4-alpha.tar.gz
$ su
password:
# mv sqoop-1.4.4.bin__hadoop-2.0.4-alpha /usr/lib/sqoop
#exit
您必须通过在〜/ .bashrc文件中添加以下行来设置Sqoop环境-
#Sqoop
export SQOOP_HOME=/usr/lib/sqoop export PATH=$PATH:$SQOOP_HOME/bin
以下命令用于执行〜/ .bashrc文件。
$ source ~/.bashrc
为了用Hadoop配置Sqoop,你需要编辑sqoop-env.sh文件,该文件被放置在$ SQOOP_HOME / conf目录目录。首先,重定向到Sqoop config目录并使用以下命令复制模板文件 -
$ cd $SQOOP_HOME/conf
$ mv sqoop-env-template.sh sqoop-env.sh
打开sqoop-env.sh并编辑以下行 -
export HADOOP_COMMON_HOME=/usr/local/hadoop
export HADOOP_MAPRED_HOME=/usr/local/hadoop
我们可以从以下链接下载mysql-connector-java-5.1.30.tar.gz文件。
以下命令用于提取mysql-connector-java tarball并将mysql-connector-java-5.1.30-bin.jar移动到/ usr / lib / sqoop / lib目录。
$ tar -zxf mysql-connector-java-5.1.30.tar.gz
$ su
password:
# cd mysql-connector-java-5.1.30
# mv mysql-connector-java-5.1.30-bin.jar /usr/lib/sqoop/lib
以下命令用于验证Sqoop版本。
$ cd $SQOOP_HOME/bin
$ sqoop-version
输出 -
14/12/17 14:52:32 INFO sqoop.Sqoop: Running Sqoop version: 1.4.5
Sqoop 1.4.5 git commit id 5b34accaca7de251fc91161733f906af2eddbe83
Compiled by abe on Fri Aug 1 11:19:26 PDT 2014
Sqoop安装完成。
本章介绍如何将数据从MySQL数据库导入到Hadoop HDFS。“导入工具”从RDBMS将单个表导入HDFS。表中的每一行都被视为HDFS中的记录。所有记录均以文本数据的形式存储在文本文件中,或作为Avro和Sequence文件中的二进制数据存储。
以下语法用于将数据导入HDFS。
$ sqoop import (generic-args) (import-args)
$ sqoop-import (generic-args) (import-args)
让我们举一个名为emp,emp_add和emp_contact的三个表的示例,这些表位于MySQL数据库服务器中名为userdb的数据库中。这三张表格及其数据如下。
id | name | deg | salary | dept |
---|---|---|---|---|
1201 | gopal | manager | 50,000 | TP |
1202 | manisha | Proof reader | 50,000 | TP |
1203 | khalil | php dev | 30,000 | AC |
1204 | prasanth | php dev | 30,000 | AC |
1204 | kranthi | admin | 20,000 | TP |
id | hno | street | city |
---|---|---|---|
1201 | 288A | vgiri | jublee |
1202 | 108I | aoc | sec-bad |
1203 | 144Z | pgutta | hyd |
1204 | 78B | old city | sec-bad |
1205 | 720X | hitec | sec-bad |
id | phno | |
---|---|---|
1201 | 2356742 | [email protected] |
1202 | 1661663 | [email protected] |
1203 | 8887776 | [email protected] |
1204 | 9988774 | [email protected] |
1205 | 1231231 | [email protected] |
Sqoop工具“导入”用于将表格数据从表格导入到Hadoop文件系统,作为文本文件或二进制文件。
以下命令用于将emp表从MySQL数据库服务器导入到HDFS。
$ sqoop import \ --connect jdbc:mysql://localhost/userdb \ --username root \ --table emp --m 1
如果它成功执行,则会得到以下输出。
14/12/22 15:24:54 INFO sqoop.Sqoop: Running Sqoop version: 1.4.5 14/12/22 15:24:56 INFO manager.MySQLManager: Preparing to use a MySQL streaming resultset. 14/12/22 15:24:56 INFO tool.CodeGenTool: Beginning code generation 14/12/22 15:24:58 INFO manager.SqlManager: Executing SQL statement: SELECT t.* FROM `emp` AS t LIMIT 1 14/12/22 15:24:58 INFO manager.SqlManager: Executing SQL statement: SELECT t.* FROM `emp` AS t LIMIT 1 14/12/22 15:24:58 INFO orm.CompilationManager: HADOOP_MAPRED_HOME is /usr/local/hadoop 14/12/22 15:25:11 INFO orm.CompilationManager: Writing jar file: /tmp/sqoop-hadoop/compile/cebe706d23ebb1fd99c1f063ad51ebd7/emp.jar ----------------------------------------------------- ----------------------------------------------------- 14/12/22 15:25:40 INFO mapreduce.Job: The url to track the job: http://localhost:8088/proxy/application_1419242001831_0001/ 14/12/22 15:26:45 INFO mapreduce.Job: Job job_1419242001831_0001 running in uber mode : false 14/12/22 15:26:45 INFO mapreduce.Job: map 0% reduce 0% 14/12/22 15:28:08 INFO mapreduce.Job: map 100% reduce 0% 14/12/22 15:28:16 INFO mapreduce.Job: Job job_1419242001831_0001 completed successfully ----------------------------------------------------- ----------------------------------------------------- 14/12/22 15:28:17 INFO mapreduce.ImportJobBase: Transferred 145 bytes in 177.5849 seconds (0.8165 bytes/sec) 14/12/22 15:28:17 INFO mapreduce.ImportJobBase: Retrieved 5 records.
要在HDFS中验证导入的数据,请使用以下命令。
$ $HADOOP_HOME/bin/hadoop fs -cat /emp/part-m-*
它向您显示emp表数据和字段用逗号(,)分隔。
1201, gopal, manager, 50000, TP 1202, manisha, preader, 50000, TP 1203, kalil, php dev, 30000, AC 1204, prasanth, php dev, 30000, AC 1205, kranthi, admin, 20000, TP
我们可以在使用Sqoop导入工具将表格数据导入HDFS时指定目标目录。
以下是将目标目录指定为Sqoop导入命令的选项的语法。
--target-dir <new or exist directory in HDFS>
以下命令用于将emp_add表数据导入到'/ queryresult'目录中。
$ sqoop import \ --connect jdbc:mysql://localhost/userdb \ --username root \ --table emp_add \ --m 1 \ --target-dir /queryresult
以下命令用于在/ queryresult目录形式的emp_add表中验证导入的数据。
$ $HADOOP_HOME/bin/hadoop fs -cat /queryresult/part-m-*
它将显示带逗号(,)分隔字段的emp_add表数据。
1201, 288A, vgiri, jublee 1202, 108I, aoc, sec-bad 1203, 144Z, pgutta, hyd 1204, 78B, oldcity, sec-bad 1205, 720C, hitech, sec-bad
我们可以使用Sqoop导入工具中的'where'子句导入表的一个子集。它在相应的数据库服务器中执行相应的SQL查询,并将结果存储在HDFS中的目标目录中。
where子句的语法如下。
--where
以下命令用于导入emp_add表数据的子集。子集查询将检索居住在塞康德拉巴德市的员工ID和地址。
$ sqoop import \ --connect jdbc:mysql://localhost/userdb \ --username root \ --table emp_add \ --m 1 \ --where “city =’sec-bad’” \ --target-dir /wherequery
以下命令用于从emp_add表中验证/ wherequery目录中的导入数据。
$ $HADOOP_HOME/bin/hadoop fs -cat /wherequery/part-m-*
它将显示带逗号(,)分隔字段的emp_add表数据。
1202, 108I, aoc, sec-bad 1204, 78B, oldcity, sec-bad 1205, 720C, hitech, sec-bad
增量导入是一种仅导入表中新添加的行的技术。需要添加'incremental','check-column'和'last-value'选项来执行增量导入。
以下语法用于Sqoop导入命令中的增量选项。
--incremental--check-column <column name> --last value <last check column value>
让我们假设新添加到emp表中的数据如下 -
1206, satish p, grp des, 20000, GR
以下命令用于在emp表中执行增量导入。
$ sqoop import \ --connect jdbc:mysql://localhost/userdb \ --username root \ --table emp \ --m 1 \ --incremental append \ --check-column id \ -last value 1205
以下命令用于验证从emp表导入的数据到HDFS emp /目录。
$ $HADOOP_HOME/bin/hadoop fs -cat /emp/part-m-*
它以逗号(,)分隔字段向您显示emp表格数据。
1201, gopal, manager, 50000, TP 1202, manisha, preader, 50000, TP 1203, kalil, php dev, 30000, AC 1204, prasanth, php dev, 30000, AC 1205, kranthi, admin, 20000, TP 1206, satish p, grp des, 20000, GR
以下命令用于查看emp表中已修改或新添加的行。
$ $HADOOP_HOME/bin/hadoop fs -cat /emp/part-m-*1
它以逗号(,)分隔的字段向您显示emp表中新添加的行。
1206, satish p, grp des, 20000, GR
本章介绍如何将所有表从RDBMS数据库服务器导入到HDFS。每个表格数据存储在一个单独的目录中,并且目录名称与表格名称相同。
以下语法用于导入所有表。
$ sqoop import-all-tables (generic-args) (import-args) $ sqoop-import-all-tables (generic-args) (import-args)
让我们举一个从userdb数据库导入所有表的例子。数据库userdb包含的表的列表如下所示。
+--------------------+ | Tables | +--------------------+ | emp | | emp_add | | emp_contact | +--------------------+
以下命令用于从userdb数据库中导入所有表。
$ sqoop import-all-tables \ --connect jdbc:mysql://localhost/userdb \ --username root
注 - 如果使用的是全部导入表,则该数据库中的每个表都必须具有主键字段。
以下命令用于验证HDFS中的所有表数据到userdb数据库。
$ $HADOOP_HOME/bin/hadoop fs -ls
它将向您显示userdb数据库中的表名称列表作为目录。
drwxr-xr-x - hadoop supergroup 0 2014-12-22 22:50 _sqoop drwxr-xr-x - hadoop supergroup 0 2014-12-23 01:46 emp drwxr-xr-x - hadoop supergroup 0 2014-12-23 01:50 emp_add drwxr-xr-x - hadoop supergroup 0 2014-12-23 01:52 emp_contact
本章介绍如何将数据从HDFS导出回RDBMS数据库。目标表必须存在于目标数据库中。输入给Sqoop的文件包含记录,这些记录在表中称为行。这些被读取并解析成一组记录并用用户指定的分隔符分隔。
缺省操作是使用INSERT语句将输入文件中的所有记录插入到数据库表中。在更新模式下,Sqoop生成将现有记录替换到数据库中的UPDATE语句。
以下是导出命令的语法。
$ sqoop export (generic-args) (export-args) $ sqoop-export (generic-args) (export-args)
让我们以HDFS中的文件中的员工数据为例。雇员数据在HDFS的'emp /'目录中的emp_data文件中可用。该emp_data如下。
1201, gopal, manager, 50000, TP 1202, manisha, preader, 50000, TP 1203, kalil, php dev, 30000, AC 1204, prasanth, php dev, 30000, AC 1205, kranthi, admin, 20000, TP 1206, satish p, grp des, 20000, GR
必须手动创建要导出的表,并将其导出到数据库中。
以下查询用于在mysql命令行中创建表'employee'。
$ mysql mysql> USE db; mysql> CREATE TABLE employee ( id INT NOT NULL PRIMARY KEY, name VARCHAR(20), deg VARCHAR(20), salary INT, dept VARCHAR(10));
以下命令用于将表数据(位于HDFS上的emp_data文件中)导出到Mysql数据库服务器的db数据库中的employee表中。
$ sqoop export \ --connect jdbc:mysql://localhost/db \ --username root \ --table employee \ --export-dir /emp/emp_data
以下命令用于验证mysql命令行中的表。
mysql>select * from employee;
如果给定数据成功存储,则可以找到给定员工数据的下表。
+------+--------------+-------------+-------------------+--------+ | Id | Name | Designation | Salary | Dept | +------+--------------+-------------+-------------------+--------+ | 1201 | gopal | manager | 50000 | TP | | 1202 | manisha | preader | 50000 | TP | | 1203 | kalil | php dev | 30000 | AC | | 1204 | prasanth | php dev | 30000 | AC | | 1205 | kranthi | admin | 20000 | TP | | 1206 | satish p | grp des | 20000 | GR | +------+--------------+-------------+-------------------+--------+
本章介绍如何创建和维护Sqoop作业。Sqoop作业创建并保存导入和导出命令。它指定参数来识别和调用保存的作业。这种重新调用或重新执行用于增量导入,它可以将更新的行从RDBMS表导入HDFS。
以下是创建Sqoop作业的语法。
$ sqoop job (generic-args) (job-args) [-- [subtool-name] (subtool-args)] $ sqoop-job (generic-args) (job-args) [-- [subtool-name] (subtool-args)]
我们在这里创建一个名为myjob的作业,它可以将表数据从RDBMS表导入HDFS。以下命令用于创建将数据从db数据库中的employee表导入到HDFS文件的作业。
$ sqoop job --create myjob \ -- import \ --connect jdbc:mysql://localhost/db \ --username root \ --table employee --m 1
'--list'参数用于验证保存的作业。以下命令用于验证保存的Sqoop作业列表。
$ sqoop job --list
它显示保存的作业列表。
Available jobs: myjob
'--show'参数用于检查或验证特定作业及其细节。以下命令和示例输出用于验证名为myjob的作业。
$ sqoop job --show myjob
它显示了myjob中使用的工具及其选项。
Job: myjob Tool: import Options: ---------------------------- direct.import = true codegen.input.delimiters.record = 0 hdfs.append.dir = false db.table = employee ... incremental.last.value = 1206 ...
'--exec'选项用于执行保存的作业。以下命令用于执行名为myjob的保存作业。
$ sqoop job --exec myjob
它向您显示以下输出。
10/08/19 13:08:45 INFO tool.CodeGenTool: Beginning code generation ...
本章介绍'codegen'工具的重要性。从面向对象的应用程序的角度来看,每个数据库表都有一个DAO类,它包含用于初始化对象的'getter'和'setter'方法。该工具(-codegen)自动生成DAO类。
它根据表模式结构在Java中生成DAO类。Java定义被实例化为导入过程的一部分。这个工具的主要用途是检查Java是否丢失了Java代码。如果是这样,它将使用字段之间的默认分隔符创建Java的新版本。
以下是Sqoop codegen命令的语法。
$ sqoop codegen (generic-args) (codegen-args) $ sqoop-codegen (generic-args) (codegen-args)
让我们举一个例子来为userdb数据库中的emp表生成Java代码。
以下命令用于执行给定示例。
$ sqoop codegen \ --connect jdbc:mysql://localhost/userdb \ --username root \ --table emp
如果该命令执行成功,则它将在终端上产生以下输出。
14/12/23 02:34:40 INFO sqoop.Sqoop: Running Sqoop version: 1.4.5 14/12/23 02:34:41 INFO tool.CodeGenTool: Beginning code generation ………………. 14/12/23 02:34:42 INFO orm.CompilationManager: HADOOP_MAPRED_HOME is /usr/local/hadoop Note: /tmp/sqoop-hadoop/compile/9a300a1f94899df4a9b10f9935ed9f91/emp.java uses or overrides a deprecated API. Note: Recompile with -Xlint:deprecation for details. 14/12/23 02:34:47 INFO orm.CompilationManager: Writing jar file: /tmp/sqoop-hadoop/compile/9a300a1f94899df4a9b10f9935ed9f91/emp.jar
让我们看看输出。该粗体路径是emp表生成和存储的Java代码的位置。让我们使用以下命令来验证该位置中的文件。
$ cd /tmp/sqoop-hadoop/compile/9a300a1f94899df4a9b10f9935ed9f91/ $ ls emp.class emp.jar emp.java
如果要深入验证,请比较userdb数据库中的emp表和/tmp/sqoop-hadoop/compile/9a300a1f94899df4a9b10f9935ed9f91/.目录中的emp.java。
本章介绍如何使用Sqoop'eval'工具。它允许用户针对各自的数据库服务器执行用户定义的查询,并在控制台中预览结果。所以,用户可以期望导入结果表数据。使用eval,我们可以评估任何类型的可以是DDL或DML语句的SQL查询。
以下语法用于Sqoop eval命令。
$ sqoop eval (generic-args) (eval-args) $ sqoop-eval (generic-args) (eval-args)
使用eval工具,我们可以评估任何类型的SQL查询。让我们举一个在db数据库的employee表中选择有限行的例子。以下命令用于评估使用SQL查询的给定示例。
$ sqoop eval \ --connect jdbc:mysql://localhost/db \ --username root \ --query “SELECT * FROM employee LIMIT 3”
如果该命令执行成功,则它将在终端上产生以下输出。
+------+--------------+-------------+-------------------+--------+ | Id | Name | Designation | Salary | Dept | +------+--------------+-------------+-------------------+--------+ | 1201 | gopal | manager | 50000 | TP | | 1202 | manisha | preader | 50000 | TP | | 1203 | khalil | php dev | 30000 | AC | +------+--------------+-------------+-------------------+--------+
Sqoop评估工具可适用于建模和定义SQL语句。这意味着,我们也可以使用eval来插入语句。以下命令用于在db数据库的employee表中插入新行。
$ sqoop eval \ --connect jdbc:mysql://localhost/db \ --username root \ -e “INSERT INTO employee VALUES(1207,‘Raju’,‘UI dev’,15000,‘TP’)”
如果该命令成功执行,则会在控制台上显示更新行的状态。
否则,您可以在MySQL控制台上验证雇员表。以下命令用于使用select'query来验证db数据库的employee表的行。
mysql> mysql> use db; mysql> SELECT * FROM employee; +------+--------------+-------------+-------------------+--------+ | Id | Name | Designation | Salary | Dept | +------+--------------+-------------+-------------------+--------+ | 1201 | gopal | manager | 50000 | TP | | 1202 | manisha | preader | 50000 | TP | | 1203 | khalil | php dev | 30000 | AC | | 1204 | prasanth | php dev | 30000 | AC | | 1205 | kranthi | admin | 20000 | TP | | 1206 | satish p | grp des | 20000 | GR | | 1207 | Raju | UI dev | 15000 | TP | +------+--------------+-------------+-------------------+--------+
本章介绍如何使用Sqoop列出数据库。Sqoop list-databases工具解析并执行针对数据库服务器的'SHOW DATABASES'查询。此后,它列出了服务器上的当前数据库。
以下语法用于Sqoop list-databases命令。
$ sqoop list-databases (generic-args) (list-databases-args) $ sqoop-list-databases (generic-args) (list-databases-args)
以下命令用于列出MySQL数据库服务器中的所有数据库。
$ sqoop list-databases \ --connect jdbc:mysql://localhost/ \ --username root
如果该命令执行成功,则它将按如下方式显示MySQL数据库服务器中的数据库列表。
... 13/05/31 16:45:58 INFO manager.MySQLManager: Preparing to use a MySQL streaming resultset. mysql test userdb db
本章介绍如何使用Sqoop列出MySQL数据库服务器中特定数据库的表。Sqoop列表表工具解析并执行针对特定数据库的“SHOW TABLES”查询。此后,它列出了数据库中的当前表格。
以下语法用于Sqoop list-tables命令。
$ sqoop list-tables (generic-args) (list-tables-args) $ sqoop-list-tables (generic-args) (list-tables-args)
以下命令用于列出MySQL数据库服务器的userdb数据库中的所有表。
$ sqoop list-tables \ --connect jdbc:mysql://localhost/userdb \ --username root
如果该命令执行成功,则它将按如下方式显示userdb数据库中的表的列表。
... 13/05/31 16:45:58 INFO manager.MySQLManager: Preparing to use a MySQL streaming resultset. emp emp_add emp_contact