在Map / Reduce期间,有没有办法设置和(稍后)在Hadoop中获取自定义配置对象?
例如,假设一个应用程序预处理一个大文件并动态确定与该文件相关的一些特征。此外,假设这些特征保存在自定义Java对象(例如,Properties
对象中,但不是唯一的,因为某些特征可能不是字符串),并且随后对于每个映射和减少作业都是必需的。
应用程序如何“传播”此配置,以便每个mapper和reducer函数可以在需要时访问它?
一种方法可能是使用set(String, String)
类的JobConf
方法,例如,通过第二个参数传递序列化为JSON
字符串的配置对象,但这可能是太过分了,然后每个JobConf
和Mapper
必须访问相应的Reducer
实例(例如,遵循earlier question中建议的方法)。
答案 0 :(得分:8)
除非我遗漏了某些内容,否则如果您有一个Properties
对象,其中包含您在M / R作业中需要的所有属性,则只需要将Properties
对象的内容写入Hadoop Configuration
对象。例如,像这样:
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
对象在映射器(Configuration
函数)或缩减器({{{}中取回map
1}} function),像这样:
reduce
请注意,使用public void map(MD5Hash key, OverlapDataWritable value, Context context)
Configuration conf = context.getConfiguration();
String someProperty = conf.get("something");
....
}
对象时,您还可以访问Configuration
和Context
方法中的setup
,如果需要,可以进行一些初始化。
另外值得一提的是,您可以直接从cleanup
对象调用addResource
方法,将您的属性直接添加为Configuration
或文件,但我相信这必须是像常规Hadoop XML配置一样的XML配置,所以这可能只是过度杀伤。
编辑:对于非String对象,我建议使用序列化:您可以序列化您的对象,然后将它们转换为字符串(可能使用Base64对它们进行编码,因为我和#39 ;我不确定如果你有不寻常的字符会发生什么),然后在mapper / reducer一侧反序列化你从InputStream
内的属性获得的字符串中的对象。
另一种方法是使用相同的序列化技术,而是写入HDFS,然后将这些文件添加到Configuration
。听起来有点矫枉过正,但这可能有用。