在Hadoop中传播自定义配置值
在Map / Reduce期间,有没有办法设置和(稍后)在Hadoop中获取自定义配置对象?
例如,假设一个应用程序预处理一个大文件并动态确定与该文件相关的一些特征。 此外,假设这些特征保存在自定义Java对象中(例如, Properties
对象,但不是唯一的,因为一些可能不是字符串),并且随后对于每个映射和减少作业都是必需的。
应用程序如何“传播”此配置,以便每个映射器和reducerfunction可以在需要时访问它?
一种方法可能是使用JobConf
类的set(String, String)
方法,例如,通过第二个参数传递序列化为JSON
字符串的配置对象,但这可能是太多的黑客然后适当无论如何,每个Mapper
和Reducer
都必须访问JobConf
实例(例如,遵循前面问题中建议的方法)。
除非我遗漏了某些内容,否则如果您的M / R作业中包含您需要的每个属性的Properties
对象,则只需将Properties
对象的内容写入Hadoop Configuration
对象即可。 例如,像这样:
Configuration conf = new Configuration(); Properties params = getParameters(); // do whatever you need here to create your object for (Entry
然后在M / R作业中,您可以使用Context
对象在mapper( map
函数)或reducer( reduce
函数)中取回Configuration
,如下所示:
public void map(MD5Hash key, OverlapDataWritable value, Context context) Configuration conf = context.getConfiguration(); String someProperty = conf.get("something"); .... }
请注意,在使用Configuration
对象时,您还可以在setup
和cleanup
方法中访问Context
,这对于在需要时进行一些初始化很有用。
另外值得一提的是,您可以直接从Configuration
对象调用addResource
方法,直接将您的属性添加为InputStream
或文件,但我相信这必须是像常规Hadoop XML配置一样的XML配置,所以可能只是矫枉过正。
编辑 :如果是非String对象,我建议使用序列化:您可以序列化您的对象,然后将它们转换为字符串(可能使用Base64对它们进行编码,因为我不确定如果您有不寻常的字符会发生什么),然后在mapper / reducer端反序列化从Configuration
的属性获得的字符串中的对象。
另一种方法是执行相同的序列化技术,而是写入HDFS,然后将这些文件添加到DistributedCache
。 听起来有点矫枉过正,但这可能会奏效。
- 从FSDataInputStream转换为FileInputStream
- 如何在动作书中的mahout中运行示例
- 如何在Hadoop中使用CompressionCodec
- 从Java写入HDFS,“只能复制到0个节点而不是minReplication”
- SPARK到HBase写作
- 错误:java.lang.IllegalArgumentException:即使使用变通方法,比较方法也违反了其一般合同
- 执行mapreduce程序时ClassNotFoundException
- hadoop map中的InstantiationException减少程序
- 通过Java API从远程主机进行HDFS访问,用户身份validation