Hdfs小文件治理策略以及治理经验

小文件是 Hadoop 集群运维中的常见挑战,尤其对于大规模运行的集群来说可谓至关重要。如果处理不好,可能会导致许多并发症。Hadoop集群本质是为了TB,PB规模的数据存储和计算因运而生的。为啥大数据开发都说小文件的治理重要,说HDFS 存储小文件效率低下,比如增加namenode负载等,降低访问效率等?究竟本质上为什么重要?以及如何从本质上剖析小文件,治理小文件呢?今天就带你走进小文件的世界。

 1. 什么是小文件?

日常生产中HDFS上小文件产生是一个很正常的事情,有些甚至是不可避免,比如jar,xml配置文件,tmp临时文件,流式任务等都是小文件的组成部分。当然更多的是因为集群设置不合理,造成一些意料之外的小文件产生。实际公司生产中对于小文件的大小没有一个统一的定义。一般公司集群的blocksize的大小在128/256两者居多。首先小文件大小肯定是要远小于blocksize的文件。一般公司小文件的大小定义如1Mb,8Mb,甚至16Mb,32Mb更大。根据公司实际集群状态定义,因为有些情况合并小文件需要消耗额外的资源。

既然剖析小文件,那么不可避免的要先剖析hdfs的存储原理。众多周知了,HDFS上文件的数据存储分为namenode元数据管理和实际数据文件。hdfs上的数据文件被拆分成块block,这些块block在整个集群中的datanode的本地文件系统上存储和复制,每个块也维护者自己的blockmeta信息。namenode主要维护这些文件的元数据信息,具体namenode的解析参考我的其他博客。

如下一个某个文件的某个block在data上存储的情况。

2.小文件的危害

2.1 小文件对namenod的影响

如下图1,一个文件192Mb,默认blocksize=128Mb,副本个数为3,存储为2个block。

如下图2,同样一个文件192Mb,默认blocksize=128Mb,副本个数为3,存储为192个block

 namenode的namespace中主要占存储对象是文件的目录个数,文件(文件名长度)以及文件block数根据namenode实际使用经验来看,一个存储对象大概占用150字节的空间。HDFS上存储文件占用的namenode内存计算公式如下:

Memory=150bytes*(1个文件inode+(文件的块数*副本个数))

如上图1 , 一个文件192Mb,默认blocksize=128Mb,副本个数为3,存储为2个block,需要namenode内存=150*(1+2*3)=1050  Bytes

同理图2, 一个文件192Mb,默认blocksize=128Mb,副本个数为3,存储为192个block,需要namenode内存=150 x (192 + (192 x 3)) = 115200 Bytes


总结

  1. 从上面可以看出,同样的一个文件,大小不同形态的存储占用namenode的内存之比相差了109倍之多。所以如果对于单namenode的集群来说,大量的小文件的会占用大量的namenode堆内存空间,给集群的存储造成瓶颈。有些人可能会说我们联邦,多组namenode不就没有这个问题了,其实不然,且往下看

  2. 当 NameNode 重新启动时(虽然生产上这种情况很少),它必须将文件系统元数据fsimage从本地磁盘加载到内存中。这意味着如果 namenode 元数据很大,重启会更慢(以我们公司3亿block,5万多个文件对象来说,重启一次1.5小时,期间应用不可用)其次,datanode 还通过网络向 NameNode 报告块更改;更多的块意味着要通过网络报告更多的变化,等待时间更长。

  3. 更多的文件,更多的block,意味着更多的读取请求需要由 NameNode 提供服务,这将增加 RPC 队列和处理延迟,进而导致namenode性能和响应能力下降。官方介绍说接近 40K~50K RPCs/s 人为是极高的负载。实际使用来看比这低时对于namenode来说性能都会打很大的折扣。

2.2 小文件对datanode影响

文件的block存储是存储在datanode本地系统上,底层的磁盘上,甚至不同的挂载目录,不同的磁盘上。大量的小文件,意味着数据着寻址需要花费很多时间,尤其对于高负载的集群来说,磁盘使用率50%以上的集群,花费在寻址的时间比文件读取写入的时间更多。这种就违背了blocksize大小设计的初衷(实践显示最佳效果是:寻址时间仅占传输时间的1%)。这样会造成磁盘的读写会很慢,拥有大量小文件会导致更多的磁盘搜索。如下磁盘延迟:


2.3 小文件对计算的影响

基于HDFS文件系统的计算,blokc块是最小粒度的数据处理单元。块的多少往往影响应用程序的吞吐量。更多的文件,意味着更多的块,以及更多的节点分布。

比如以MapReduce任务为例(hive等),在 MapReduce 中,会为每个读取的块生成一个单独的 Map 任务,如果大量小文件,大量的块,意味着着更多任务调度,任务创建开销,以及更多的任务管理开销(MapReduce 作业的 application master 是一个 Java 应用,它的主类是 MRAppMaster。它通过创建一定数量的bookkeeping object跟踪作业进度来初始化作业,该对象接受任务报告的进度和完成情况)。虽然可以开启map前文件合并,但是这也需要不停地从不同节点建立连接,数据读取,网络传输,然后进行合并,同样会增加消耗资源和增加计算时间,成本也很高。

同样,如果是spark计算引擎,executor的一次读取和处理一个分区,默认情况下,每个分区是一个 HDFS 块,如果大量的小文件,每个文件都在不同的分区中读取,这将导致大量的任务调度开销,同时每个 CPU 内核的吞吐量降低。



3. 小文件的产生

  1. 流式数据,如flume,kafak,sparkstreaming,storm,flink等,流式增量文件,小窗口文件,如几分钟一次等。

  2. MapReduce引擎任务:如果纯map任务,大量的map;如果mapreduce任务,大量的reduce;两者都会造成大量的文件。出现这种情况的原因很多,果分布表的过度分区,输入大量的小文件,参数设置的不合理等,输出没有文件合并等。

  3. spark任务过度并行化,Spark 分区越多,写入的文件就越多。

  4. 文件的压缩与存储格式不合理;一般生产公司很少使用textfile这种低效的文件格式了。

使用压缩,降低文件的大小,同时也会降低文件的总块数。注意文件存储格式和压缩不合理只是加剧小文件问题,不是产生小文件的本质。

4. HDFS小文件监控

HDFS的fsimage是HDFS文件系统的一个重要组成部分,记录了HDFS文件系统的元数据信息,包括文件、目录、权限、块等信息。通过监控HDFS的fsimage,可以了解HDFS文件系统的整体情况,包括文件数量、文件大小、文件类型等信息,进而实现对HDFS小文件的监控和治理。

具体来说,可以通过以下步骤对HDFS小文件进行监控:

  1. 获取HDFS的fsimage:使用Hadoop自带的命令hdfs oiv -p XML -i fsimage命令获取HDFS的fsimage文件。该命令会将HDFS的fsimage文件以XML格式输出,包括HDFS中所有文件和目录的元数据信息;

  2. 解析fsimage文件:使用Python等脚本语言解析获取到的fsimage文件,提取其中的文件、目录、块等信息。可以使用Python的ElementTree模块等工具对XML文件进行解析,提取需要的信息;

  3. 统计文件数量和文件大小:根据解析后的文件信息,统计HDFS中小文件的数量和大小。通常可以根据文件大小和文件数量的阈值来定义小文件,例如文件大小小于128MB或文件数量小于1000个等;

  4. 可视化展示:使用可视化工具,如Grafana、Kibana等将统计结果进行可视化展示,以便于对HDFS小文件的监控和管理。

解析fsimage文件为txt文件

hdfs oiv -i  fsimage_0000000192578352133 -o /data2/data/fsimage/$day/fsimage.txt -p Delimited -t /data2/data/fsimage/$day/tmp1.

fsimage文件重要的字段释义

INODE_ID:文件或目录的唯一标识符;
NAME:文件或目录的名称;
PARENT_ID:父目录的INODE_ID;
MODIFICATION_TIME:最后修改时间;
ACCESS_TIME:最后访问时间;
BLOCK_IDS:文件的数据块ID列表;
BLOCK_SIZE:数据块大小;
NUM_BLOCKS:数据块数量;
PERMISSIONS:文件或目录的权限信息;
USER_NAME:文件或目录所属用户;
GROUP_NAME:文件或目录所属用户组;
SYMLINK:如果是符号链接,则包含符号链接的目标路径;
UNDER_CONSTRUCTION:如果文件正在写入中,则为true;
UNDER_RECOVERY:如果文件正在恢复中,则为true;
FILE_LENGTH:文件长度;
NS_QUOTA:命名空间配额;
DS_QUOTA:磁盘配额;
STORAGE_POLICY:存储策略。

通过编写脚本采集相关指标,并存入相关数据库,能够进行绘制可观测图,便于监控小文件的状态,便于后续进行小文件治理

5. HDFS小文件的治理方法

针对HDFS小文件的问题,有以下几种治理方法:

  1. 合并小文件:将多个小文件合并为一个大文件,减少文件数量。这种方法需要注意文件的内容和格式,以免合并后的文件无法使用或者存在数据丢失等问题;

  2. 压缩文件:将多个小文件压缩为一个压缩包,减少存储空间。这种方法可以使用Hadoop自带的压缩工具,如gzip、bzip2等;

  3. 删除无用文件:删除不再需要的小文件,释放存储空间;

  4. 设置文件过期时间:对于不再需要的文件,可以设置其过期时间,自动删除过期文件;

  5. 使用SequenceFile:使用Hadoop自带的SequenceFile格式存储小文件,将多个小文件合并到一个SequenceFile中,以减少文件数量,提高处理效率。

通常可以通过应用层,进行合并小文件、删除过期无用文件、转移小文件到其他存储媒介等方式,减少和治理hdfs中的小文件,以提升hdfs集群的稳定性。

针对如上办法进行治理方法如下

  1. 合并小文件:对于日志文件等大量的小文件,可以使用Hadoop自带的合并工具将多个小文件合并为一个大文件。下面是通过hive的重写方式合并小文件,核心参数如下;

set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
set hive.merge.mapfiles = true;
set hive.merge.mapredfiles = true;
set hive.merge.smallfiles.avgsize=256000000;
set hive.merge.size.per.task=12800000;
set mapred.max.split.size=256000000;
set mapred.min.split.size=64000000;
set mapred.min.split.size.per.node=64000000;
set mapred.min.split.size.per.rack=64000000;1.2.3.4.5.6.7.8.9.
  1. 压缩文件:对于大量的小文件,可以使用压缩工具将多个小文件压缩为一个压缩包,以减少存储空间。例如,使用gzip或bzip2压缩工具压缩文件,在HDFS上存储压缩文件,以减少存储空间和文件数量;

  2. 删除无用文件:对于不再需要的小文件,可以使用Hadoop自带的命令hadoop fs -rm命令删除文件,或者使用定时任务脚本定期删除过期文件; 

  3. 设置文件过期时间:使用hadoop fs -touchz命令设置文件的过期时间,当文件过期后,自动删除文件。例如,使用hadoop fs -touchz命令设置文件的过期时间为30天,当文件超过30天未被访问时,自动删除文件;

  4. 使用SequenceFile:对于大量的小文件,可以使用SequenceFile格式存储文件,将多个小文件合并成一个SequenceFile文件。例如,使用Hadoop自带的SequenceFile.Writer类将多个小文件写入SequenceFile文件中,以减少存储空间和文件数量。

6. 疑问和思考

暂无

7. 参考文档

暂无

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/319128.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Rust中的并发性:Sync 和 Send Traits

在并发的世界中,最常见的并发安全问题就是数据竞争,也就是两个线程同时对一个变量进行读写操作。但当你在 Safe Rust 中写出有数据竞争的代码时,编译器会直接拒绝编译。那么它是靠什么魔法做到的呢? 这就不得不谈 Send 和 Sync 这…

jupyter notebook 设置密码报错ModuleNotFoundError: No module named ‘notebook.auth‘

jupyter notebook 设置密码报错ModuleNotFoundError: No module named ‘notebook.auth‘ 原因是notebook新版本没有notebook.auth 直接输入以下命令即可设置密码 jupyter notebook password

ICode国际青少年编程竞赛- Python-1级训练场-基础训练1

ICode国际青少年编程竞赛- Python-1级训练场-基础训练1 1、 Dev.step(4)2、 Dev.step(-4) Dev.step(8)3、 Dev.turnLeft() Dev.step(4)4、 Dev.step(3) Dev.turnLeft() Dev.step(-1) Dev.step(4)5、 Dev.step(-1) Dev.step(3) Dev.step(-2) Dev.turnLeft() Dev.step(…

tomcat打开乱码修改端口

将UTF-8改成GBK 如果端口冲突,需要修改tomcat的端口

PR2019软件下载教程

打开下载网址:rjctx.com 选择Premiere: 选择PR2019,并点击: 拉到最后,选择百度网盘下载: 下载到本地。 二,软件安装 解压缩后,双击set_up 选择位置后,进行安装&…

Java中接口的默认方法

为什么要使用默认方法 当我们把一个程序的接口写完后 用其他的类去实现,此时如果程序需要再添加一个抽象方法的时候我们只有两种选择 将抽象方法写在原本的接口中 但是这样写会导致其他所有改接口的实现类都需要实现这个抽象方法比较麻烦 写另一个接口 让需要的实…

13.1 QQ邮箱

1. 邮箱发送 2. 准备工作 3. 整合SpringBoot 3.1 配置 依赖引入 <!-- 邮件服务--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>application.…

Ubuntu GUI使用Root用户登录指南

Ubuntu GUI使用Root用户登录指南 一、前言 默认情况下&#xff0c;Ubuntu 禁用了 root 账户&#xff0c;我们必须使用 sudo 命令来执行任何需要 root 权限的任务&#xff0c;比如像这样删除一个系统配置文件&#xff08;操作危险&#xff0c;请勿尝试&#xff09;&#xff1a;…

接收区块链的CCF会议--APSEC 2024 截止7.13 附录用率

会议名称&#xff1a;APSEC&#xff08;Asia-Pacific Software Engineering Conference&#xff09; CCF等级&#xff1a;CCF C类学术会议 类别&#xff1a;软件工程/系统软件/程序设计语言 录用率&#xff1a;2023年&#xff0c;90 submissions were recommended for accep…

【前端项目——分页器】手写分页器实现(JS / React)

组件介绍 用了两种方式实现&#xff0c;注释详细~ 可能代码写的不够简洁&#xff0c;见谅&#x1f641; 1. 包含内容显示的分页器 网上看了很多实现&#xff0c;很多只有分页器部分&#xff0c;没和内容显示联动。 因此我增加了模拟content的显示&#xff0c;这里模拟了32条数…

如何免费体验 gpt2-chatbot

如何免费体验 gpt2-chatbot 就在五一假期期间&#xff0c;一个神秘模型在没有任何官方文件的情况下突然发布。发布后不到 12 小时就立即引起人工智能爱好者和专家们的关注。这个名为“gpt2-chatbot”的神秘新模型凭借其令人印象深刻的能力轰动全球。有人猜测它可能是 OpenAI 的…

Docker Compose如何安装

Docker Compose的安装通常依赖于你的操作系统。以下是在不同操作系统中安装Docker Compose的方法&#xff1a; Linux 系统 //下载最新版本的Docker Compose sudo curl -L "https://github.com/docker/compose/releases/download/v2.5.1/docker-compose-$(uname -s)-$(un…

SQL如何利用Bitmap思想优化array_contains()函数

目录 0 问题描述 1 位图思想 2 案例实战 3 小结 0 问题描述 在工作中&#xff0c;我们往往使用array_contains()函数来进行存在性问题分析&#xff0c;如判断某个数是否在某个数组中&#xff0c;但是当表数据量过多&#xff0c;存在大量array_contains()函数时&#xff0c;…

C语言:数据结构(双向链表)

目录 1、双向链表的结构2、顺序表和双向链表的优缺点分析3、双向链表的实现 1、双向链表的结构 注意&#xff1a;这⾥的“带头“跟前面我们说的“头节点”是两个概念&#xff0c;实际前面的在单链表阶段称呼不严谨&#xff0c;但是为了更好的理解就直接称为单链表的头节点。 带…

网络聊天室:通过Servlet和JSP,结合session和application实现(文末附源码)

目录 一.成品效果 二.代码部分 chat.jsp ChatServlet 一.成品效果 在启动成功后&#xff0c;我们就可以在任意俩个浏览器页面中相互发消息&#xff0c;如图所示左边屏幕使用的是Edge浏览器&#xff0c;右图使用的是火狐浏览器。当然笔者这里只是简单实现最基本的一些功能&…

从键入网址到网页显示,期间发生了什么?

从键入网址到网页显示&#xff0c;期间发生了什么&#xff1f; 孤单小弟【HTTP】真实地址查询【DNS】指南帮手【协议栈】可靠传输【TCP】远程定位【IP】两点传输【MAC】出口【网卡】送别者【交换机】出境大门【路由器】互相扒皮【服务器与客户端】相关问答 不少小伙伴在面试过程…

RabbitMq基础概念知识复习

消息拥有消息头和消息体&#xff0c;消息具有rounting key&#xff0c;主题交换机和扇形交换机都是发布与订阅的实现方式&#xff0c;主题交换机用于匹配接收的消息的rount key 动态匹配模式匹配到多个符合的队列&#xff0c;扇形fanout交换机则不会使用消息的路由key&#xff…

SQLite如何处理CSV 虚拟表(三十七)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite的DBSTAT 虚拟表&#xff08;三十六&#xff09; 下一篇:SQLite的扩展函数Carray()表值函数(三十八) ​ RFC4180格式是一种文本文件格式&#xff0c;被用于表格数据间的交互&#xff0c;也可将表格数据转化…

【机器学习】集成方法---Boosting之AdaBoost

一、Boosting的介绍 1.1 集成学习的概念 1.1.1集成学习的定义 集成学习是一种通过组合多个学习器来完成学习任务的机器学习方法。它通过将多个单一模型&#xff08;也称为“基学习器”或“弱学习器”&#xff09;的输出结果进行集成&#xff0c;以获得比单一模型更好的泛化性…

基于t972 Android9 AP6256,如何在设置中添加5G热点选项,并使其正常打开

通过设置的的WiFi热点选项可以知道关键词“2.4GHz”&#xff0c;因此可以其全局搜索&#xff0c;在packages\apps\Settings\res\values\strings.xml文件下找到如下图所示&#xff0c; 从上面注释可以知道&#xff0c;选项按键选择2.4GHz触发的按键关键词是“wifi_ap_choose_2G…