2012-03-26 52 views
1

我正在运行的某个作业需要在处理某些大型HDFS文件之前从数据库(MySQL,尽管这不相关)收集一些元数据。该元数据将被添加到文件中的数据中,并传递到更高版本的map/combine/reduce阶段。结合Hadoop MapReduce和数据库查询

我想知道把这个查询放在哪里“正确”的地方。我需要元数据在映射器开始时可用,但将其放置在那里似乎是多余的,因为每个映射器都将执行相同的查询。我如何(如果有的话)执行一次查询并在所有映射器上分享其结果?在执行任务的所有节点之间共享数据(除了写入HDFS之外)是否有共同的方法?谢谢。

回答

3

您可以在主函数中使用MYSQL查询,查询结果可以存储在字符串中。然后,您可以将该变量设置为Hadoop作业配置对象。所有映射器都可以访问Configuration对象中设置的变量。

主类看起来是这样的....
JobConf conf = new JobConf(Driver.class);
String metainfo = <You metadata Info goes here>;
conf.set("metadata",metainfo);



所以在你地图类,你可以如下

publi class Map(...){访问元数据值

String sMetaInfo="";

public void configure(JobConf job) {

sMetaInfo= job.get("metadata"); // Getting the metadata value from Job Configureation Object

}
public void map(....){

// Map Function
}

}

+3

此外,如果您的元数据太大而无法存储在配置中,那么您应该查看使用DistributedCache。从驱动程序中的数据库中获取元数据,保存到文件中,然后将文件添加到DistributedCache中 - 然后该文件将在每个映射器中可用,以便加载到内存并根据需要追加 – 2012-03-26 10:14:57

+0

这两个答案都非常好,谢谢! – sa125 2012-03-26 11:39:48

0

如果你有cloude我会用飞扑ra分配方便。我通常在java中使用cascading进行编程,而对于db源使用dbmigrate作为源“tap”使得dbs成为头等公民。在dbmigrate中使用pks时,性能已经足够。

+0

https://github.com/Cascading/cascading-dbmigrate – 2012-03-27 13:34:16