Hadoop上小文件存储处理

Hadoop–小文件存储处理

本篇文章项目是Cloudera论坛中无意中看到的,虽然原文写于2009年,但是当前开来Hadoop的小文件存储方案并没有很好的解决方案,所以感觉作者写的很好,也很详细,于是就抽空翻译了。本次翻译主要针对对Hadoop感兴趣和工作中使用到Hadoop的开发人员提供有价值的中文资料,希望能够对大家的工作和学习有所帮助。

由于我英语水平有限,部分翻译虽能了解其大意,但是却没法很好的表达出来,所以有些地方翻译的不是很好。同时也由于能力见识有限,翻译过程中难免出现个人的主观或者客观原因导致与原文档有差异。在此,我还是建议有能力的童鞋能够自己去原文看看,同时如果大家发现更好的关于Hadoop小文件处理的文件,也建议大家提出来与大家一同分享。

 

小文件问题

February 2, 2009

By Tom White

32 Comments

Categories: General Hadoop

在Hadoop中小文件是一个大问题 — 或者说, 至少, 他们在用户的讨论区域是比较热门的话题. 在这篇文章中我将直面这个问题, 并提出一些常见的解决方案.

在HDFS中的小文件问题

这里讨论的小文件指的是那些在HDFS中小于HDFS块大小(默认是64M)的文件. 如果你存储了很多这种小文件, 或者你有很多这种小文件 (如果你并没有使用Hadoop), 这里讨论的问题是Hadoop不能处理大量的这种文件.

每一个文件, 目录和块在HDFS中代表一个对象存储在namenode的内存中, 它们每一个占用150 字节, 根据经验. 所以1000万个文件,每一个使用一个块, 将大约需要3GB的内存. 远远超过当前的硬件处理水平. 当然10亿个文件直接没法处理.

此外, HDFS是没有能力去有效地访问小文件:它主要是专为串行流式访问的大文件设计的. 阅读小文件通常会导致从一个DataNode到DataNode检索每个小文件, 所有的这些访问数据效率都是很低下的.

在MapReduce中小文件问题

Map任务每次能处理一个块的输入 (使用的是默认的 FileInputFormat). 如果文件非常小而且还很多, 导致每次Map任务产生非常小的输入, 同时这里需要大量的map任务, 这样增加了很多额外的开销. 比较一个1GB 文件分成16 64MB 块, 10,000 或者 100KB 文件. 10,000文件每个文件使用一个map任务, 这个任务比一个相等的大文件要慢10或者上百倍.

这里有一些特征能够减轻额外的开销:多个任务使用一个JVM, 从而避免了一些JVM启动开销 (看mapred.job.reuse.jvm.num.tasks 属性), 和MultiFileInputSplit 可以运行多个以上的分割任务.

小文件怎么产生的?

这里至少有两个场景

  1. 这些文件是一个更大的逻辑文件. 由于HDFS最近才支持追加,一个非常通用的保存无界文件(例如日志文件)的模式是写在HDFS块.
  2. 有的文件一直比较小. 想象一个大的图像库. 每一个文件是一个不同的文件, 没有自然的方法把它们组合成一个更大的文件.

这两者需要不同的解决方案. 对于第一个实例, 文件是有一个个记录组成, 这个问题可以通过调用 HDFS’s sync() 方法来避免 (这个是追加, 深入了解可以看 this discussion) 每一个如此频繁地写大文件. 另外,你可以通过写一个程序来把小文件连接在一起 (查看 Nathan Marz’s post 工具能够实现这种功能).

对于第二种情况,通过一些方式来对文件进行分组操作. Hadoop提供了几种方案.

HAR files

Hadoop Archives (HAR 文件)被引入到HDFS在0.18.0版本中为了减轻存放许多文件在namenode内存中的问题. HAR 文件的工作原理是在HDFS中建立一个分层的文件系统. 一个 HAR文件创建通过使用hadoop archive 命令,他通过运行一个MapReduce任务把HDFS中的小文件进行打包. 对于客户端使用HAR文件系统没有改变: 所有的原始文件是可见的和可访问的 (通过使用 har:// URL). 然而, 在HDFS上的文件数量并没有减少.

在HDFS上读文件比HAR上面效率要高一些, 事实上,可能会比较慢因为每个HAR文件访问需要两个索引文件的读取以及数据文件的读取(见下图). 虽然HAR文件能够作为MapReduce的输入文件 , HAR并没有准许在进行Map操作的时候把所有的文件当着一个块来操作. 它应该是提供一个输入的格式能够在HARs提升改进的地方, 实际上它并没有. 请注意 MultiFileInputSplit, 即使在 HADOOP-4565 通过选择本地文件分割来提高, 将也需要查询每一个小的文件. 通过与SequenceFile文件性能比较是很有趣的, 所以说.现在HARs最常使用的是来处理文档.

Sequence Files

通常回答关于“小文件问题” 是: 使用SequenceFile. SequenceFile文件的设计思想是使用文件名作为key文件内容作为值. 这在实践中很好. 回到10,000 100KB 文件问题, 你可以写一个程序把他们放到一个单独的SequenceFile文件里面, 并且你可以通过串流的形势对其进行访问(直接或者通过MapReduce) 在SequenceFile文件上进行操作. 更神奇的地方是. SequenceFiles文件能够被可拆分, 所以MapReduce可以打破成块,每一块独立操作. 它们也支持压缩, 不像HARs. 块压缩是大多数情况下最好的选择, 由于压缩了几个记录块(相当于每个记录).

它可以将现有的数据转化成为SequenceFiles. 然而,完全有可能在并行创建一系列sequencefiles. (Stuart Sierra 已经写了一篇很有用的关于 post 转换tar文件到SequenceFile文件 — 这种工具是很有益的, 看到更多的人会很好).最好的设计在写入数据的时候直接写入到SequenceFiles文件里面, 如果可能,而不是写小文件作为中间步骤.


不像HAR文件, SequenceFile文件没法罗列出所有的keys,简短的阅读需要获取通过整个文件. (MapFiles文件很像一个已经对key进行排序的 SequenceFiles 文件, 维护部分索引, 所以他们不能罗列所有它们的keys — 如图所示.)

SequenceFile文件相当于Java的核心. TFile文件被设计成跨平台的, 是一个可以替代的 SequenceFile, 但它尚未提供.

HBase

如果你产生了很多小文件, 然而, 根据访问模式, 不同类型的存储可能更合适. HBase 存储数据通过MapFiles (索引SequenceFiles), 是一个很好的选择如果你需要MapReduce流分析同时也需要随机访问查看. 如果延迟是一个问题, 然而这里有许多其他的选择 — 看Richard Jones’ 杰出的survey of key-value stores.

转载自 并发编程网 - ifeve.com

时间: 2024-10-04 19:29:35

Hadoop上小文件存储处理的相关文章

基于Hadoop的海量小文件存储方法的研究

基于Hadoop的海量小文件存储方法的研究 时倩 方睿 岳亮 彭榆峰 随着科学技术的发展,各行业及领域需要处理的数据呈爆炸式增长.Hadoop是大文件存储处理的理想平台,但Hadoop在处理海量小文件时的表现并不令人满意.本文首先对HDFS的系统架构作了简要介绍,进而分析了HDFS处理海量小文件时存在的问题,最后介绍了目前国内外对该问题提出的优化方案. 基于Hadoop的海量小文件存储方法的研究

转 海量小文件存储与Ceph实践

海量小文件存储(简称LOSF,lots of small files)出现后,就一直是业界的难题,众多博文(如[1])对此问题进行了阐述与分析,许多互联网公司也针对自己的具体场景研发了自己的存储方案(如taobao开源的TFS,facebook自主研发的Haystack),还有一些公司在现有开源项目(如hbase,fastdfs,mfs等)基础上做针对性改造优化以满足业务存储需求: 一. 通过对若干分布式存储系统的调研.测试与使用,与其它分布式系统相比,海量小文件存储更侧重于解决两个问题: 1.

Hdspace分布式机构知识库系统的小文件存储

Hdspace分布式机构知识库系统的小文件存储 卞艺杰 陈超  李亚冰 陆小亮 机构知识库作为一种新型的学术交流模式和开放获取活动的绿色通道已逐渐成为国内外图书情报界关注的新焦点, 随着机构库的发展其数据规模也在不断扩大,  传统的存储模式已经不能满足日益增长的存储需求. 在对机构库内容存储特点的研究基础上建立基于 HDFS与Dspace 的分布式机构库 Hdspace.  首先提出一种小文件合并生成新的存储文件,  并对文件提出基于学科分类的两级索引,  结合索引预缓存机制提高小文件的读取响应

基于Hadoop的云盘系统客户端技术难点之三 小文件存储优化

作者:张子良 版权所有,转载请注明出处. 一.概述 首先明确概念,这里的小文件是指小于HDFS系统Block大小的文件(默认64M),如果使用HDFS存储大量的小文件,将会是一场灾难,这取决于HDFS的实现机制和框架结构,每一个存储在HDFS中的文件.目录和块映射为一个对象存储在NameNode服务器内存中,通常占用150个字节.如果有1千万个文件,就需要消耗大约3G的内存空间.如果是10亿个文件呢,简直不可想象.这里需要特别说明的是,每一个小于Block大小的文件,存储是实际占用的存储空间仍然

Hadoop中pid文件存储

我的hadoop集群部署在自己电脑虚拟机上,有时候我是挂起虚拟机,第二天再打开发现有些线程就挂了,比如namenode,好奇怪,当时看了一些帖子说是和pid存储有关,找到log看到找不到pid.因为基于java开发的程序,想要停止程序,必须通过进程pid来确定,而hadoop和hbase默认的情况下,会把pid文件存储在Linux上的/tmp目录的某个目录,进程名命令规则一般是框架名-用户名-角色名.pid,而默认情况下,linux的tmp里面的东西,一天会删除一次. 其实每次不用的时候挂壁,用

Hadoop上传文件报错: name node is in safe mode

将本地文件拷贝到hdfs上去,结果上错误:Name node is in safe mode 这是因为在分布式文件系统启动的时候,开始的时候会有安全模式,当分布式文件系统处于安全模式的情况下,文件系统中的内容不允许修改也不允许删除,直到安全模式结束.安全模式主要是为了系统启动的时候检查各个DataNode上数据块的有效性,同时根据策略必要的复制或者删除部分数据块.运行期通过命令也可以进入安全模式.在实践过程中,系统启动的时候去修改和删除文件也会有安全模式不允许修改的出错提示,只需要等待一会儿即可

grep-用shell脚本读取Hadoop集群上的文件

问题描述 用shell脚本读取Hadoop集群上的文件 我想用grep -Ff 命令提取hadoop上两个文件中相同的内容, 例如hadoop上的文件位置为/hadoop/file1和/hadoop/file2, 我想在本地用shell脚本编写比较hadoop上这两个文件内容的代码,求指点 解决方案 需要脚步跑到Hadoop.本地没法获取

基于小文件的内存云存储优化策略

基于小文件的内存云存储优化策略 英昌甜 于炯 鲁亮 刘建矿 由于内存云RAMCloud采用日志段的方式存储数据,因此当大量小文件存储于RAMCloud集群时,每个小文件独占整个段,会产生较多的段内碎片,从而导致内存的有效利用率较低以及大量的内存空间浪费.为了解决这个问题,提出基于文件分类的RAMCloud小文件存储优化策略.该策略首先根据文件的相关特性将小文件分为结构相关文件.逻辑相关文件以及相互独立文件三类;然后在存储时对结构相关的文件使用文件合并算法,逻辑相关和相互独立的小文件则使用分组算法

一种提高云存储中小文件存储效率的方案

针对基于HDFS的云存储系统中小文件存储效率不高的问题,采用序列文件技术设计了一个云存储系统中小文件的处理方案.该方案利用多维属性决策理论,综合读文件时间.合并文件时间及节省内存空间大小等指标,得出合并小文件的最优方式,能够在消耗的时间和节省的内存空间之间取得平衡:设计基于层次分析法的系统负载预测算法对系统负载进行预测,从而实现负载均衡的目的:利用序列文件技术对小文件进行合并. 实验结果表明,在不影响存储系统运行状况的基础上,该方案提高了HDFS(Hadoop distributed file