在安装了Sqoop之后,可以用它将数据导入Hadoop。在本章的所有示例中我们都使用支持很多平台的易用数据库系统MySQL作为外部数据源。
基于Debian的Linux系统(如Ubuntu)的用户可以通过键入sudo apt-get install mysql-client mysql-server进行安装;RedHat的用户可以通过键入sudo yum install mysql mysql-server进行安装。
现在,MySQL已经安装好,让我们先登录,然后创建一个数据库(范例15-1)。
范例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-lubuntu5.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用户的密码,就像root用户通过密码进行shell登录一样。如果你正在使用Ubuntu或其他不支持root直接登录的Linux系统,则键入安装MySQL时设定的密码。
在这个会话中,我们创建了一个新的名为hadoopguide的数据库模式,本章中我们将一直使用这个数据库模式,接着我们允许所有本地用户査看和修改hadoopguide模式的内容;最后,关闭这个会话。
现在让我们登录到数据库(这次不是作为root,而是你自己),然后创建一个将被导入HDFS的表(范例15-2)。
范例15-2.填充数据库
% mysql hadoopguide Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 352 Server version: 5.1.37-lubuntu5.4 (Ubuntu) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> CREATE TABLE widgetS(id INT NOT NULL PRIMARY KEY AUTO.INCREMENT, -> widget_name VARCHAR(64) NOT NULL, -> price DECIMAL(10,2), -> design_date DATE, -> version INT, -> design_comment VARCHAR(100)); Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO widgets VALUER (NULL, 'sprocket', 0.25, '2010-02-10', -> 1, 'Connects two gizmos'); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO widgets VALUES (NULL, 'gizmo'、 4.00, '2009-11-30', 4, -> NULL); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO widgets VALUES (NULL, 'gadget', 99.99, '1983-08-13', -> 13, 'Our flagship product'); Query OK, 1 row affected (0.00 sec) mysql> quit;
在上面的示例中,我们创建了一个名为widgets的新表。在本章更多的例子中我们都将使用这个虚构的产品数据库。widgets表有几个不同数据类型的字段。
现在让我们使用Sqoop将这个表导入HDFS:
% sqoop import --connect jdbc:mysql://localhost/hadoopguide \ > --table widgets -m 1 10/06/23 14:44:18 INFO tool.CodeGenTool: Beginning code generation ... 10/06/23 14:44:20 INFO mapred.JobClient: Running job: job_201006231439_0002 10/06/23 14:44:21 INFO mapred.JobClient: map 0% reduce 0% 10/06/23 14:44:32 INFO mapred.JobClient: map 100% reduce 0% 10/06/23 14:44:34 INFO mapred.JobClient: Job complete: job_201006231439_0002 ... 10/06/23 14:44:34 INFO mapreduce.ImportJobBase: Retrieved 3 records.
Sqoop的import工具会运行一个MapReduce作业,该作业会连接MySQL数据库并读取表中的数据。默认情况下,该作业会并行使用4个map任务来加速导入过程。每个任务都会将其所导入的数据写到一个单独的文件,但所有4个文件都位于同一个目录中。在本例中,由于我们知道只有三行可以导入的数据,因此指定Sqoop只使用一个map任务(-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,0ur flagship product
在本例中使用了连接字符串(jdbc:mysql://localhost/hadoopguide),表明需要从本地机器上的数据库中读取数据。如果使用了分布式Hadoop集群,则在连接字符串中不能使用localhost,否则,与数据库不在同一台机器上运行的map任务都将无法连接到数据库。即使是从数据库服务器所在主机上运行Sqoop,也需要为数据库服务器指定完整的主机名。
在默认情况下,Sqoop会将我们导入的数据保存为逗号分隔的文本文件。如果导入数据的字段内容中存在分隔符,我们可以另外指定分隔符、字段包围字符和转义字符。使用命令行参数可以指定分隔符、文件格式、压缩以及对导入过程进行更细粒度的控制,Sqoop自带的《Sqoop使用指南》或 Sqoop的在线帮助(sqoop help import,在 CDH 中使用 man sqoop-import可以找到对相关参数的描述。
文本和二进制文件格式
Sqoop可以将数据导入成几种不同的格式。文本文件(默认)是一种人类可读的数据表示形式,并且是平台独立和最简单的数据格式。但是,文本文件不能保存二进制字段(例如数据库中类型为VARBINARY的列),并且在区分null值和字符串null时可能会出现问题(尽管使用–null-string选项可以控制空值的表示方式)。
为了处理这些情况,应该使用Sqoop的SequenceFile格式或Avro格式。Avro和SequenceFile格式的文件能够为导入的数据提供最精确的表示方式,同时还允许对数据进行压缩,并支持MapReduce并行处理同一文件的不同部分。然而,Sqoop的目前版本还不能将Avro或SequenceFile文件加载到Hive中(尽管可以手动地将Avro数据文件加载到Hive中)。SequenceFile文件格式的最后一个缺点是它只支持java语言,而Avro数据文件却可以被很多种语言处理。
转载请注明:全栈大数据 » 15.3. 一个导入的例子