将对象副本传递给hadoop中所有映射器的最佳实践

您好我正在学习Map Reduce,我正在尝试使用hadoop 1.0.4构建一个小作业。 我有一个停用词列表和一个模式列表。 在我的文件映射之前,我想在一个有效的数据结构(如地图)中加载stoppwords。 我还想从我的模式列表中构建一个正则表达式模式。 由于这些是串行任务,我想在映射前执行​​它们,并将每个映射器的副本传递给它们可以读/写的对象。 我想在我的驱动程序类中只使用一个带有getter的静态变量,但是将java调用对象作为指针原则这不起作用。 我当然可以在传递之前克隆对象,但这似乎不是一个好习惯。 我读了一些关于分布式缓存的东西,但据我所知,它只用于文件而不是对象,而且我可以让每个映射器读取stopp word / pattern文件。

谢谢你的帮助!

一种可能的解决方案是在运行作业之前将stopwords.txt复制到HDFS,然后在Mapper的setup方法中将其读入适当的数据结构。 例如:

MyMapper类:

... private Map stopwords = null; @Override public void setup(Context context) { Configuration conf = context.getConfiguration(); //hardcoded or set it in the jobrunner class and retrieve via this key String location = conf.get("job.stopwords.path"); if (location != null) { BufferedReader br = null; try { FileSystem fs = FileSystem.get(conf); Path path = new Path(location); if (fs.exists(path)) { stopwords = new HashMap(); FSDataInputStream fis = fs.open(path); br = new BufferedReader(new InputStreamReader(fis)); String line = null; while ((line = br.readLine()) != null && line.trim().length() > 0) { stopwords.put(line, null); } } } catch (IOException e) { //handle } finally { IOUtils.closeQuietly(br); } } } ... 

然后,您可以在map方法中使用停用词

另一种选择是使用jobrunner类中的停用词创建map对象,将其序列化为Base64编码的String,将其作为Configuration对象中某个键的值传递给映射器,并在setup方法中对其进行反序列化。

我选择第一个选项,不仅因为它更容易,而且因为通过Configuration对象传递更大量的数据不是一个好主意。

Hadoop分布式缓存是一种特定的机制,用于将一些引用数据传递给映射器。 从性能的角度来看,最好从HDFS加载 – 因为数据将从每个节点一次从HDFS传递到本地文件系统,而不是每个任务一次。
你完全正确 – 它只适用于文件和阅读文件并将它们转换为你的数据结构是你的责任。
据我所知,hadoop不支持传递对象。 虽然如果您在这些文件中使用某种序列化 – 它将接近您的要求。