Hadoop笔记汇总系列第七篇-HDFS存储小文件

767 阅读5分钟

这是我参与更文挑战的第13天,活动详情查看: 更文挑战

背景

这是Hadoop笔记汇总系列的第七篇,在之前学习研究HDFS的时候,整理了一些HDFS存储小文件的资料,今天把这一部分汇总一下.

HDFS存储小文件的场景

块报告机制的适用场景

DataNode会向NameNode进行两种类型的块报告:增量报告与全量报告,DataNode接收到块,或者删除块会立即向NM报告,这属于增量报告;全量报告周期性发生,定时将当前DN上所有数据块信息报告给NM NM处理块报告时会将NM锁住,其它请求会被阻塞,当面向大文件处理时,这个不是问题,而且hadoop也是处理离线数据,若是小文件,带来的问题:

  • DN扫描本地磁盘时,DN会被锁住,发送心跳也会阻塞,NM可能会认为DN死掉
  • Linux中每个文件读取操作经过三次磁盘IO:目录元数据,inode,文件内容,若小文件太多,会造成大量磁盘IO(解决方法:将小文件写到大文件,将随机写改为顺序写)
  • DN周期性报告太多块,会占用NM大量处理时间,此时会阻塞NM的响应
  • 大量网络IO,给NM网卡的压力
  • 对NM内存的压力

解决方法:

  • 提供选择更大内存,更多core的机器作为NM
  • 单节点启动多DN(根据机器实际情况而定,如果太多也会导致DN速度变慢,同时需要改造数据块分配策略)
  • 周期性报告块由全量变为分批进行处理
  • 如果NM压力过大或者响应太低,就需要换成Federation解决方案了
  • 单DN扫描本地目录及其数据块导致长时间锁住的问题可改造成分批次加锁解决

小文件和Federation

HDFS不适合大量小文件的存储,因NameNode将文件系统的元数据存放在内存中,因此存储的文件数目受限于NameNode的内存大小。HDFS中每个文件、目录、数据块占用150Bytes。如果存放1million的文件至少消耗300MB内存,如果要存放1billion的文件数目的话会超出硬件能力,但是目前HDFS版本引入了Federation这种多NameNode的机制,可以支持NameNode的横向扩展;同时也可以适用HDFS的小文件合并为大文件的机制

HDFS的应用场景

  1. HDFS不适合大量小文件的存储,因NameNode将文件系统的元数据存放在内存中,因此存储的文件数目受限于NameNode的内存大小。HDFS中每个文件、目录、数据块占用150Bytes。如果存放1million的文件至少消耗300MB内存,如果要存放1billion的文件数目的话会超出硬件能力,但是目前HDFS版本引入了Federation这种多NameNode的机制,可以支持NameNode的横向扩展;同时也可以适用HDFS的小文件合并为大文件的机制;
  2. HDFS适用于高吞吐量,而不适合低时间延迟的访问(因为写文件可能存在初始化socket,初始化RPC,及其多次通信等)。如果同时存入1million的files,那么HDFS 将花费几个小时的时间;
  3. 流式读取的方式,不适合多用户写入一个文件(一个文件同时只能被一个客户端写),以及任意位置写入(不支持随机写),支持文件尾部apend操作,或者文件的覆盖操作;
  4. HDFS更加适合写入一次,读取多次的应用场景,通过线上HDFS集群的监控,hadoop目前业务的读写比为10:1,在设计上也是考虑了这一点,读速度比较快

HDFS写入过程

HDFS不适合低延迟的访问,原因是写入一个文件,经过的通信次数比较多;如果对于一个大文件,它写数据流的时间远远大于RPC通信,socket建立连接,及其磁盘寻址等时间,因此大文件比较适合

  1. Client和NM创建RPC连接(客户端可创建一次,不再创建);
  2. Client发送Create()操作,创建文件元数据
  3. Client请求为文件分配块(文件有几个数据块,就请求分配几次);
  4. Client与DataNode,DataNode自己之间建立socket(4,5,6),并且几者之间socket均建立成功才算成功,才能进行数据块的写入操作;
  5. 每个DataNode接收完某个块会向NameNode进行报告;
  6. 如果一个文件的每个块的三个副本中,只要有一个副本报告给NameNode,客户端发送消息给NameNode确认文件完成;

HDFS自带的小文件存储解决方案

对于小文件问题,hadoop自身提供了三种解决方案:Hadoop Archive、 Sequence File 和 CombineFileInputFormat

  1. Hadoop Archive 核心方法是把多个小文件归档为一个大文件,创建存档文件的问题:
  • 存档文件的源文件目录以及源文件都不会自动删除需要手动删除
  • 存档的过程实际是一个mapreduce过程,所以需要需要hadoop的mapreduce的支持
  • 存档文件本身不支持压缩
  • 存档文件一旦创建便不可修改,要想从中删除或者增加文件,必须重新建立存档文件
  • 创建存档文件会创建原始文件的副本,所以至少需要有与存档文件容量相同的磁盘空间
  1. Sequence File
  • sequence file由一系列的二进制的对组成,其中key为小文件的名字,value的file content。
  • 创建sequence file的过程可以使用mapreduce工作方式完成
  • 对于index,需要改进查找算法
  • 对小文件的存取都比较自由,也不限制用户和文件的多少,但是该方法不能使用append方法,所以适合一次性写入大量小文件的场景
  1. CombineFileInputFormat
  • CombineFileInputFormat是一种新的inputformat,用于将多个文件合并成一个单独的split,另外,它会考虑数据的存储位置
  • 该方案版本比较老,网上资料甚少,从资料来看应该没有第二种方案好。