Hadoop:如何通过map / reduce访问(很多)照片图像?

时间:2012-01-06 02:43:06

标签: hadoop mapreduce hdfs

我在本地文件系统上保存了10M +照片。现在我想通过他们每个人来分析照片的二进制文件,看看它是不是一只狗。我基本上想要在集群hadoop环境中进行分析。问题是,我应该如何为map方法设计输入?让我们说,在map方法中, new FaceDetection(photoInputStream).isDog()是分析的所有基础逻辑。

具体而言, 我应该将所有照片上传到HDFS吗?假设是,

  1. 如何在map方法中使用它们?

  2. 是否可以将输入(到map)作为包含所有照片路径(在HDFS中)的文本文件与每一行,以及在map方法中,加载二进制文件,如:photoInputStream = getImageFromHDFS(photopath);(实际上,什么是在执行map方法期间从HDFS加载文件的正确方法?)

  3. 我似乎错过了一些关于hadoopmap/reducehdfs的基本原则的知识,但是请您根据上述问题指出我,谢谢!

3 个答案:

答案 0 :(得分:18)

  

如何在map方法中使用它们?

主要问题是每个文件都在一个文件中。因此,如果您有10M文件,那么您将拥有10M的映射器,这听起来不太合理。您可能需要考虑将文件预序列化为SequenceFiles(每个键值对一个图像)。这将使数据加载到MapReduce作业本机中,因此您不必编写任何棘手的代码。此外,如果您愿意,您还可以将所有数据存储到一个SequenceFile中。 Hadoop可以很好地处理分裂SequenceFiles。

基本上,它的工作方式是,你将有一个单独的Java进程,它接受几个图像文件,将光线字节读入内存,然后将数据存储到SequenceFile中的键值对。继续前进并继续写入HDFS。这可能需要一段时间,但您只需要执行一次。


  

是否可以将输入(到地图)作为包含所有照片路径(在HDFS中)的文本文件与每一行,并在map方法中,加载二进制文件,如:photoInputStream = getImageFromHDFS(photopath) ); (实际上,在执行map方法期间从HDFS加载文件的正确方法是什么?)

如果您有任何合理的集群(如果您正在考虑使用Hadoop,那么您应该这样做)并且您实际上想要使用Hadoop的强大功能。您的MapReduce作业将启动并加载文件,但映射器将运行数据本地文本文件,而不是图像!因此,基本上,由于JobTracker没有将任务放在文件所在的位置,因此您将在任何地方对图像文件进行洗牌。这将导致大量的网络开销。如果您有1TB的图像,如果您有多个节点,则可以预期它们中的很多将通过网络进行流式传输。根据您的情况和群集大小(少于几个节点),这可能不是那么糟糕。

如果您确实想这样做,可以使用FileSystem API创建文件(您需要open方法)。

答案 1 :(得分:7)

  

I have 10M+ photos saved on the local file system.

假设将每个文件放入序列文件需要一秒钟。将单个文件转换为序列文件需要大约115天。通过在一台机器上进行并行处理,我没有看到太多改进,因为磁盘读/写将是读取照片文件和编写序列文件的瓶颈。查看small files problem上的这篇Cloudera文章。还有一个脚本的引用,该脚本将tar文件转换为序列文件以及转换所花费的时间。

基本上,照片必须以分布式方式处理,以便将它们转换为序列。回到Hadoop:)

根据Hadoop - The Definitive Guide

  

根据经验,每个文件,目录和块大约需要150个字节。因此,例如,如果你有一百万个文件,每个文件占一个块,你需要至少300 MB的内存。

因此,直接加载10M的文件需要大约3,000 MB的内存才能在NameNode上存储命名空间。忘记在执行作业期间跨节点流式传输照片。

应该有更好的方法来解决这个问题。


另一种方法是将文件按原样加载到HDFS中,并使用CombineFileInputFormat将小文件组合成输入分割,并在计算输入分割时考虑数据局部性。这种方法的优点是文件可以按原样加载到HDFS中而无需任何转换,并且节点之间也没有太多的数据混乱。

答案 2 :(得分:0)

我曾经在一个项目上(2008年?),我们做了一些与Hadoop非常相似的事情。我相信我们最初使用HDFS来存储图片,然后我们创建了一个列出要处理的文件的文本文件。这个概念是你使用map / reduce将文本文件分解成碎片并将其传播到整个云中,让每个节点根据它们收到的列表部分处理一些文件。对不起,我不记得更明确的细节,但这是一般方法。