Hadoop平台的一个强大的地方是它处理不同格式数据的能力。HDFS能够稳定的存储日志和
其它很多种来源的数据,并且Mapreduce程序可以处理各种各样的数据格式,然后抽取相关的数据并且组合各种各样的数据成为一个有用的结果。
但是,和HDFS之外的存储仓库交互数据的时候,Mapreduce程序需要使用外部的API来得到这些数据。通常,有价值的数据存储在RDBMS中。Sqoop是一个允许用户从其它RDBMS中抽取数据到Hadoop中,以便进一步分析处理。对数据的分析处理,可以使用Mapreduce程序或者其它更高级的工具,例如Hive。
当一个分析管道的最终结果出来的时候,Sqoop可以将这些结果导回到数据库,以便其它的
客户端使用这些数据。
本章,我们将研究Sqoop是怎样工作的和在你的数据处理管道中怎样使用它。
获得Sqoop
Sqoop在很多地方可以下载到。http://github.com/cloudera/sqoop是项目的主页。这个仓库包括Sqoop的所有源码和文档。本网站上面有官方发行版本,同样也有正在开发的版本,在它们的代码仓库中包括编译项目的指导。相应的,Cloudera的发布Hadoop版本包括与Hadoop或其它的工具(像Hive)兼容的Sqoop安装包。
如果你从github上下载了版本,他会放在类似这样的目录下,/home/yourname/sqoop-x.y.z/。我们称这个目录为$SQOOP_HOME。
你可以用可执行的script命令$SQOOP_HOME/bin/sqoop来运行Sqoop。
如果你从Cloudra上安装了版本,安装包会把Sqoop的脚本放在标准位置例
如:/usr/bin/sqoop。你可以在命令窗口敲入sqoop就可以运行Sqoop了。
Sqoop命令不带任何参数的时候 是没有很多意义的,
% sqoop
Try sqoop help for usage.
Sqoop是由一系列工具和命令组织成的。不选择一个工具,Sqoop不知道做什么。help是这
样的一种工具,它能够打印出可用的工具。
% sqoop help
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
list-databases List available databases on a server
list-tables List available tables in a database
version Display version information
当输入如下的命令时,会打印出具体工具的使用说明。
% sqoop help import
usage: sqoop import [GENERIC-ARGS] [TOOL-ARGS]
Common arguments:
–connect <jdbc-uri> Specify JDBC connect string
–driver <class-name> Manually specify JDBC driver class to use
–hadoop-home <dir> Override $HADOOP_HOME
–help Print usage instructions
-P Read password from console
–password <password> Set authentication password
–username <username> Set authentication username
–verbose Print more information while working
…
运行Sqoo工具的一个替代的方法是用tool-specific脚本命令。类似sqoop-toolname的命令
,例如:sqoop-help, sqoop-import, etc.
导入数据的一个例子
安装完Sqoop之后,你就可以用它往Hadoop里面导入数据了。
使用Sqoop从数据库中导出数据,如果你还没有安装数据服务器,你需要选择一个,对于大多数平台来说,MySql是一个简便易用的数据库。
安装和配置MySql,参考下面的文档,http://dev.mysql.com/doc/refman/5.1/en/。第二章的内容会有帮助。Debin用户使用如下命令安装,sudo aptget install mysql-client mysql-server
RedHat用户使用以下命令:sudo yum install mysql mysql-server
MySql安装好之后,我们登录进去并且创建数据库。
例子15-1:创建一个MySql数据库模式。
% mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 349
Server version: 5.1.37-1ubuntu5.4 (Ubuntu)
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input
statement.
mysql> CREATE DATABASE hadoopguide;
Query OK, 1 row affected (0.02 sec)
mysql> GRANT ALL PRIVILEGES ON hadoopguide.* TO ‘%’@’localhost';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT ALL PRIVILEGES ON hadoopguide.* TO ”@’localhost';
Query OK, 0 rows affected (0.00 sec)
mysql> quit;
Bye
上面提到的密码是你的root用户密码。一般是你的shell登录密码。如果你运行的是Ubuntu
或其它的Linux版本,使用root密码无法直接登录时,你就用安装时候设置的密码登录。
在这个会话中,我们创建了一个新的数据模式叫做,hadoopguide,在本章节中,我们将都
会用它。然后我们允许任何的本地用户都可以查看和修改hadoopguide的内容,并且关闭会
话。当然了,在生产开发中,我们需要更多的关心权限的控制,但是我们这个服务器是临
时使用的。上面赋予的权限也是假设你运行在伪分布式上面。如果你工作在分布式集群中
,你需要保证至少一个用户,激活了远程访问,这个用户用来执行通过Sqoop导入和导出。
Sqoop的导入工具会运行一个Mapreduce job,这个job连接到MySQL数据库并且读取数据库中的表。默认情况下,这个过程会并发的使用四个map tasks 来加快导入数据的过程。每个 task 会把它的导入结果写入到一个不同的文件中,但是,所有文件都在同一个目录下面。
在这个例子中,我们只导入三行数据,所以我们指定Sqoop使用一个单独的map task (-m 1),这样我们在HDFS中只生成一个文件。
我们可以通过如下命令查看文件的内容:
% hadoop fs -cat widgets/part-m-00000
1,sprocket,0.25,2010-02-10,1,Connects two gizmos
2,gizmo,4.00,2009-11-30,4,null
3,gadget,99.99,1983-08-13,13,Our flagship product
例子中的连接字符串(jdbc:mysql://localhost/hadoopguide)会从本机的数据库中读取数据。如果使用的是一个分布式的Hadoop集群,那么,在连接字符串中不应该指定位localhost主机名(译注:指定主机名后,就特定的只连接那台主机);map tasks 没有运行在相同的机器上面,因为连接数据库可能失败。只有当Sqoop与数据库服务器运行在同一个主机上面时,才应该指明完整的主机名。
在默认情况下,Sqoop会把我们导入的数据,生成逗号分隔符分开的文本文件。分隔符可以自己指定。命令行中的参数可以指定分隔符,文件格式,压缩格式,和更多的对导入过程的细致的控制。
注:文本和二进制文件格式
Sqoop可以导入数据到一些不同的文件格式。文本格式(默认格式)提供一种便于人阅读的数据格式,这种格式平台无关性,是最简单的结构。
但是,这种文件格式,不可以处理二进制字段(例如数据库中列中的可变二进制类型字段);不能区分出空值和包含null的字符串。
为了解决这种情况,你应该使用Sqoop的基于Sequence的文件格式。序列化文件的缺点是,他们是Java特定的,并且目前Sqoop版本不能将其导入到Hive中。
但是,序列化文件提供了,更精确的导入数据的替代方法的可能性。它也允许数据压缩,同时保持了Mapreduce平行的处理同一个文件不同部分的能力。