我有一个场景,我需要使用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
提前致谢。
答案 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导出,每次关系运行一次。