https://eldadlevy.wordpress.com/2011/02/05/hadoop-binary-files-processing-entroduced-by-image-duplicates-finder/              翻译

Hadoop 图像去重的二进制文件处理

这篇文章探讨了使用hadoop来处理二进制文件的可能性,同时用一个图片的案例来解释它。图片的副本解决了hadoop job读取多个相对较小的困境,同时也展示了如何在map/reduce job中读取二进制数据。因此,他阐述了Hadoop如何处理二进制文件的过程。本文通过实际操作给出了部分代码,你可以使用它们应用到你的具体环境。
我们大多数时间看到map/reduce算法使在处理文本数据,从著名的wordcount案例到去多其它的hadoop job,一个可以确信的是全部的hadoop框架的设计都是为了处理文本数据。好吧,虽然他可能是真的,hadoop的设计也解决了大量的非文本数据的处理。
为了测试我们所讨论的内容,首先你应该拥有一个hadoop的环境。最快的方法是使用cloudera提供的训练虚拟机,我的好朋友Philippe Adjiman写了一篇文章 nice tutorial 介绍了使用cloudera搭建hadoop环境。

问题:
我们的图片系统通过搜索的字符串从互联网上下载图片,一些图片可能是完全相同的但是被使用在不同的网站,因此我们希望系统能够过滤掉这些重复的图片。我们可以期待的大量的数据,这就是为什么选择hadoop 来解决它的原因。

输入是充满了jpg格式图片的目录,输出的应该是具有唯一的图片的列表。

困境:
Hadoop正在从巨大的数据文件中读取数据,同时将处理分布在多个代理上。使用优化的处理单元为主的本地数据作为输入进行处理。如果我们使用大量的像图片一样的小文件,处理过程将会发生什么?
显然将会产生大量的开销,HDFS为每个文件保持了相对大的开销,以便能够支持在多个机器上分割文件并在不同机器上用多个副本备份每个文件的功能。至于处理时间,也会受到影响。默认情况下,每个输入文件都会被发送到自己的map任务下,因此,大量的文件意味着需要大量的map任务。拥有大量的map任务可以显著的减慢应用程序的每一个任务的开销。对于超多一个文件分割,可以通过反复利用任务的JVM机制和MultiFileInputSplit来减缓开销。
更多的 小文件问题和 一些处理大量图片项目的总结。

使用hadoop Sequence Files
因此,我们应该采用什么方法来解决大量的图片问题呢? 使用Hadoop sequence files!这些mapfiles可以由map reduce应用程序读取的映射文件——Sequence files的特殊输入格式,它们通过mapreduce 分割,因此,我们可以由许多map任务的输入组成一个巨大的文件。通过使用这些sequence files我们就可以发挥hadoop的优势。我们可以把任务分割成块,以便并行处理,但是分割的块足以使进程保持高效。
由于序列文件是映射文件,所需的格式是键将是文本并保存HDFS文件名,值将为BytesWritable,并且将包含文件的图像内容。备注 -这个例子,它是更好的存储处理的二进制文件,而不是文件的整个字节。我的兴趣在展示如何读取和写入二进制文件,所以我们坚持BytesWritable。
但是如何从图片文件生成一个sequence files呢?事实证明,这并不是一个简单的任务。下面是一些我想到的方法:
1、 如果可能,最好的方法是在获取图像后立即生成序列文件。这种方式,系统总是准备好进行图像处理,而不需要进行一些预处理来生成序列文件。因为sequence files可以被追加,因此不需要一次检索所有的图像文件。我们可以使用org.apache.hadoop.io.SequenceFile.Writer。 example
2、 将所有图像存储为tar文件,并使用由Stuart Sierra编写的工具将其转换为序列文件。tool
3、 使用mapreduce 任务收集所有图像文件,并将其存储为sequence files。Map的输入时这些图片在hdfs上的路径,map的输出则是sequence files(这个案例中没有reduce任务)。使用hadoop的可扩展优势,以防你真的有大量的文件。这是受到Ryan Balfanz编写的一个简单工具的启发。
我将要阐述根据第三种选择的方式来创建sequence files ,因为我相信这是最通用的方式。
在写代码之前我们有一个亟需解决的问题。如果我无法加载所有的图像字节到内存中,以便将它们写入sequence files,我不会遭受所有与上面提到的大量小文件相关的问题吗?而且如果图像加载到内存中不是最好的做图像处理的方法——查找文件副本,在这个阶段,而不是创建一个顺序文件,然后再试着找到重复的?
答案有两个不同的方面——:
 如果图像处理过程不仅包含图片查重,并且存在多于一个的需要读取所有图像的mapreduce 作业,那么你希望它作为一个序列文件,以便更好地执行。
 如果我们没有全部的图片,可以独立地为每个图像完成将图像转换为序列文件的预处理。然而,重复查找器是需要所有图像被处理的过程。在一些情况下,可以使用将创建sequence files的作业与找到副本的作业解耦,以便即使在所有图像存在之前将在图像上调用序列文件创建的方式来设计系统

预处理作业 - 生成sequence files:
目标索引文件是使文件名当做 key值,把BytesWritable作为value值。输入是一个包含所有图像文件的文件作为HDFS文件名。例如:
hdfs://localhost:8022/user/elevy/smallArchiveImages/WonderWoman.jpg
所以我们的mapreduce作业将只包含一个map一次只读一个文件并使用SequenceFileOutputFormat写入到sequence files中。它使用FileSystem对象为了打开hdfs上的文件,使用FSDataInputStream去读文件。字节数组被作为可替换字符写入上下文。由于作业的输出格式是SequenceFileOutputFormat类,输出的map将被写入sequence files中。
这在 BinaryFilesToHadoopSequenceFile.java中实现了预处理工作。

图像查重工作:
现在我们有一个包含所有文件二进制数据的序列文件,它是过滤重复项的实际作业的时间。我们将使用MD5算法来对每个图像生成一个唯一的key,并通过比较key值发现重复的图片。我们的mapreduce 作业将包括以下几点:

 mapper,将读取所有映像文件的二进制映像数据,并将为每个文件创建MD5。它会将此数据传递给reducer,其中键将是MD5字符串,而值将是文件名。因此,所有的重复图片将会通过hadoop framework集合到一起。
public void map(Text key, BytesWritable value, Context context) throws IOException,InterruptedException { //get the md5 for this specific file String md5Str; 
try { md5Str = calculateMd5(value.getBytes()); } 
catch (NoSuchAlgorithmException e) { e.printStackTrace(); context.setStatus("Internal error - can't find the algorithm for calculating the md5"); 
return; } 
Text md5Text = new Text(md5Str);  //put the file in the map where the md5 is the key, so duplicates  //will be grouped together for the reduce function 
context.write(md5Text, key); } static String calculateMd5(byte[] imageData) throws NoSuchAlgorithmException { //get the md5 for this specific data 
MessageDigest md = MessageDigest.getInstance("MD5"); md.update(imageData); byte[] hash = md.digest(); // Below code of converting Byte Array to hex String hexString = new String(); 
for (int i=0; i < hash.length; i++) { 
hexString += Integer.toString( ( hash[i] & 0xff ) + 0x100, 16).substring( 1 ); 
} return hexString; }

 一个非常简单的reducer,它只会获取每个MD5哈希的第一个文件名。这样,每个相同图像将只有一个文件名,并且所有重复项都被过滤。输出是一个映射文件,其中键是文件名,值是MD5哈希值。

public void reduce(Text key, Iterable<Text> values,
  Context context) throws IOException, InterruptedException {
   //Key here is the md5 hash while the values are all the image files that
 // are associated with it. for each md5 value we need to take only
 // one file (the first)
  Text imageFilePath = null;
  for (Text filePath : values) {
    imageFilePath = filePath;
    break;//only the first one
  }
  // In the result file the key will be again the image file path. 
  context.write(imageFilePath, key);
}
所有这些东西都在类 ImageDuplicatesRemover.java中演示,它实现了重复删除作业。

Hadoop 图像小文件查重方法相关推荐

  1. Unity编辑器小工具——文件查重(MD5)

    Unity编辑器小工具--文件查重(MD5) 算法思想: 在Unity中,每一个不同资源.文件所生成MD5码是不同的,但是相同文件,路径不同.文件名不同的同一类文件的MD5码是相同的,所以可以通过生成 ...

  2. python文件查重_文件查重 我使用的是面向局部敏感的最小哈希签名的方法进行文档查重 联合开发网 - pudn.com...

    文件查重 所属分类:其他 开发工具:Python 文件大小:39KB 下载次数:7 上传日期:2017-12-20 16:45:32 上 传 者:lala_ 说明:  我使用的是面向局部敏感的最小哈希 ...

  3. 学习项目---文件查重

    声明:本项目在deepin系统下vim编译的,利用了jieba分词工具,如果在vs编译的话需要设置文件路径,还需要把GDK转成UTF8,在读的时候用UTF8转成GDK 1.文件查重原理: 1.1中文分 ...

  4. 计算机类sci查重,SCI科研写作:国自然标书查重方法

    就在今天,国家自然科学基金立项结果公布了,可能大家的心情会非常忐忑,无论中标与否,大家都想去分析:怎么样才能离中标更进一步呢?小编在这里整理一些关于国自然的资料,有备无患,查漏补缺,看看自己的问题出在 ...

  5. 小论文查重率一般小于多少?

    小论文是研究生期间每个学生在各种学术杂志上发表的论文,字数一般要求在5000字以内,所以叫小论文.众所周知,本科毕业论文需要重复检测,小论文也需要重复检测.小论文的重复率和本科毕业论文的重复率一样吗? ...

  6. 用java设计一个文件查重程序,输入两个文本文件,输出两个文本文件的重复率(最长公共子序列的应用)...

    你可以使用java代码来设计一个文件查重程序.首先,你需要读取两个文本文件的内容,将它们存储在字符串变量中.然后,你可以使用最长公共子序列(LCS)算法来计算两个字符串的重复率. LCS算法的实现方法 ...

  7. 文件查重程序 v1.5.4 官网

    Welcome to my blog! <script language="javascript" src="http://avss.b15.cnwg.cn/cou ...

  8. 毕业生查重必备!!论文降重小技巧 + 查重网站哪家强

    我们学校有三次查重机会,所以第一次我头一热没有自己降重,就直接上传了.重复率44%,所以在多数人不需要担心是否在30%以内时,我就很惴惴不安,要努力降重!以下就介绍了我写论文的降重方法和查重网站的使用 ...

  9. centos7 应用笔记: fslint 文件查重

    centos7 应用笔记: fslint 文件查重 fslint 可以用于文件的查重. fslint 扫描的是文件的内容.如果内容一致,则会认为文件一致.而不论文件名是否一致. 安装 fslint # ...

最新文章

  1. 使用RMAN恢复数据库
  2. GridView导出到Excel和开源图表工具
  3. 用Swashbuckle给ASP.NET Core的项目自动生成Swagger的API帮助文档
  4. 力扣53. 最大子序和
  5. Win11怎么设置桌面软件小图标 Win11设置桌面软件小图标教程
  6. c语言中格式化字符串系列函数包括,解析C语言中常用的格式化输入、输出函数...
  7. 没车牌也能开上国产特斯拉:北京3年租赁每月1万1,全国最低7千
  8. 找零程序Java_JAVA解惑--找零时刻
  9. Codeforces Round #430 D. Vitya and Strange Lesson
  10. Linux网络编程之connect创建
  11. 程序员必备的网站推荐
  12. bpsk调制及解调实验_调制的理解
  13. Quartz CronTrigger最完整触发时间配置说明
  14. 【Docker】安装-win7
  15. P4234 最小差值生成树
  16. C++20新特性个人总结
  17. 为什么要进行网站流量分析?从6个方面告诉你答案
  18. TypeScript超详细入门教程(上)
  19. uniapp设置整个页面背景颜色渐变,设置单个页面背景颜色
  20. 【笔记】为什么现代人变得越来越娱乐至死

热门文章

  1. Linux 交换分区
  2. 程序人生——Hello P2P
  3. 如何双开或多开skype
  4. 现代信息技术的特点和趋势
  5. SourceTree - 学习/使用
  6. 台式计算机idc数据排名,2019年电脑销量排行_IDC:2019年中国PC市场预测销量持续走低...
  7. IDC:阿里云获2021中国数据治理平台市场份额第一
  8. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java宠物医院管理系统fy9ez
  9. Vue移动端项目知识点
  10. Android扭曲图像(水面落叶壁纸初步实现)