从一个部分文件(猪输出)到两个表的Sqoop

时间:2014-02-21 13:45:06

标签: hadoop apache-pig sqoop

我有一个场景,我需要使用hdfs加载数据并存储到Pig,并且此结果(pig输出/部分文件数据)应加载到mysql中的两个表使用Sqoop

这可以通过Sqoop完成吗?任何其他解决方案。

例如,如果我有这样的文件

    col1 col2 col3 col4
    .... .... .... ....
    .... .... .... ....
    .... .... .... ....

I want to export col1,col2 to table table1 and col3,col4 to table table 2 of some database

提前致谢。

2 个答案:

答案 0 :(得分:7)

我在下面的解决方案中使用MySQL,但同样适用于其他数据库。

在HDFS上创建以下平面文件:

$ hadoop fs -cat sqoop_export
W1, X1, Y1, Z1
W2, X2, Y2, Z2
W3, X3, Y3, Z3

在MySQL中创建两个表:

mysql> create table A (col1 VARCHAR(20), col2 VARCHAR(20));
Query OK, 0 rows affected (0.08 sec)

mysql> create table B (col3 VARCHAR(20), col4 VARCHAR(20));
Query OK, 0 rows affected (0.01 sec)

然后创建一个存储过程,它接受四个输入值,然后将前两个插入第一个表,最后两个插入第二个表:

mysql> delimiter //
mysql> CREATE PROCEDURE insert_two_tables (IN c1 VARCHAR(20), IN c2 VARCHAR(20), IN c3 VARCHAR(20), IN c4 VARCHAR(20)) BEGIN INSERT INTO A(col1, col2) VALUES(c1, c2); INSERT INTO B(col3, col4) VALUES(c3, c4); END//
Query OK, 0 rows affected (0.04 sec)

现在使用sqoop导出但不指定表名,而是使用--call选项调用上面创建的存储过程:

$ sqoop export --connect jdbc:mysql://localhost/sqoop_export --username xyz --password test --call insert_two_tables --export-dir sqoop_export

导出过程成功完成:

14/03/24 17:52:53 INFO mapred.JobClient:     Physical memory (bytes) snapshot=668643328
14/03/24 17:52:53 INFO mapred.JobClient:     Virtual memory (bytes) snapshot=7584153600
14/03/24 17:52:53 INFO mapred.JobClient:     Total committed heap usage (bytes)=1175584768
14/03/24 17:52:53 INFO mapreduce.ExportJobBase: Transferred 691 bytes in 16.8329 seconds (41.0506 bytes/sec)
14/03/24 17:52:53 INFO mapreduce.ExportJobBase: Exported 3 records

现在验证这两个表是否包含我们要查找的数据:

mysql> select * from A;
+------+------+
| col1 | col2 |
+------+------+
| W3   |  X3  |
| W2   |  X2  |
| W1   |  X1  |
+------+------+
3 rows in set (0.00 sec)

mysql> select * from B;
+------+------+
| col3 | col4 |
+------+------+
|  Y3  |  Z3  |
|  Y2  |  Z2  |
|  Y1  |  Z1  |
+------+------+
3 rows in set (0.00 sec)

因此,使用存储过程,HDFS上的一个平面文件可以导出到数据库中的多个表。

如果您不想使用存储过程,那么替代方法是使用pig在HDFS上创建两个平面文件 - 一个具有col1,col2,另一个具有col3,col4。然后,您可以在每个平面文件上单独导出两个sqoop导出到数据库上的相应表。

Sqoop导出功能--columns选项但仅当数据库端相对于HDFS上的平面文件有更多列时才有用。对于另一个方向,似乎存储过程是必要的。根据{{​​3}}调用存储过程而不指定表的能力在Sqoop 1.4.3及更高版本中可用。我在上面的例子中使用过Hadoop 2.0.0和Sqoop 1.4.3。

答案 1 :(得分:0)

轻松!只需使用PIG将数据分成两个关系:

-- given A:
A = 
col1 col2 col3 col4
.... .... .... ....
.... .... .... ....

-- split into two relations:
Acols1_and_2 = FOREACH A GENERATE col1, col2;
Acols3_and_4 = FOREACH A GENERATE col3, col4;

-- store those relations in HDFS
...

然后运行两次sqoop导出,每次关系运行一次。