5

在 Map/Reduce 期间,有什么方法可以在 Hadoop 中设置和(稍后)获取自定义配置对象?

例如,假设一个应用程序预处理一个大文件并动态确定与该文件相关的一些特征。此外,假设这些特征保存在自定义 Java 对象(例如,一个Properties对象,但不排他地,因为有些可能不是字符串)中,并且随后对于每个映射和归约作业都是必需的。

应用程序如何“传播”这个配置,以便每个映射器和缩减器函数在需要时可以访问它?

一种方法可能是使用类的set(String, String)方法JobConf,例如,通过JSON第二个参数将配置对象序列化为字符串,但这可能太过分了,然后JobConf每个人都必须访问适当MapperReducer实例(例如,采用类似于前面问题中建议的方法)。

4

1 回答 1

9

除非我遗漏了什么,否则如果您有一个Properties包含 M/R 作业所需的所有属性的对象,您只需将Properties对象的内容写入 HadoopConfiguration对象即可。例如,像这样:

Configuration conf = new Configuration();
Properties params = getParameters(); // do whatever you need here to create your object
for (Entry<Object, Object> entry : params.entrySet()) {
    String propName = (String)entry.getKey();
    String propValue = (String)entry.getValue();
    conf.set(propName, propValue);
}

然后在您的 M/R 作业中,您可以使用该对象在映射器(函数)或归约器(函数)中Context取回您的对象,如下所示:Configurationmapreduce

public void map(MD5Hash key, OverlapDataWritable value, Context context)
    Configuration conf = context.getConfiguration();
    String someProperty = conf.get("something");
    ....
}

请注意,在使用Configuration对象时,您还可以访问Context和方法setupcleanup如果需要进行一些初始化很有用。

另外值得一提的是,您可能可以直接addResource从对象调用方法Configuration以将属性直接添加为InputStream文件或文件,但我相信这必须是像常规 Hadoop XML 配置一样的 XML 配置,所以这可能只是矫枉过正。

编辑:如果是非字符串对象,我建议使用序列化:您可以序列化您的对象,然后将它们转换为字符串(可能使用 Base64 对它们进行编码,因为我不确定如果您有不寻常的字符会发生什么),然后在映射器/归约器端反序列化您从内部属性中获得的字符串中的对象Configuration

另一种方法是执行相同的序列化技术,但改为写入 HDFS,然后将这些文件添加到DistributedCache. 听起来有点矫枉过正,但这可能会奏效。

于 2013-02-20T04:07:28.670 回答