HDFS小文件离线分析
【简介】
HDFS集群通常在使用过程中,文件对象数会越来越多,直到达到NameNode能够支撑的容量,并且小文件过多也会导致对应的上层应用产生各种各样性能问题,常见的如扫描大量小文件耗时加长、处理频次翻倍,同时也会引起NameNode响应变慢,对内存需求增加,DataNode块存储过多,DataNode性能下降等一些列问题,本篇文章主要是讲解通过fsimage离线分析整个hdfs目录小文件分布情况,这种分析能最大程度减少对NameNode的压力。
fsImage介绍
fsimage包含最新的元数据检查点,在HDFS启动时加载fsimage的信息,包含了整个HDFS文件系统的所有目录和文件的信息,NameNode定时合并已经存在的fsimage和新生成的editlog信息,形成元数据快照,这样防止了editlog过多的问题,同时重启时也能根据fsimage文件将集群恢复导致之前的状态。正常情况下可以通过在线的方式查看各个目录大小以及文件目录数来筛选识别小文件所在的目录,但是随着集群规模增大,NameNode文件和目录达到亿级别,在如此量级别下筛选过滤是比较耗时的,而且这些操作对集群性能有一定影响,既然fsimage已经保存了整个集群的文件目录信息,那我们可以利用此fsimage文件对集群目录文件情况做离线分析。
小文件离线分析
1.将fsImage文件转换成csv格式的文件
参考Hadoop官网指导解析fsImage文件:https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsImageViewer.html
在namenode元数据目录下获取最近的元数据fsImage文件,在对应hdfs客户端上执行元数据解析文本文件的命令,如下:
hdfs oiv -i /opt/client/imagecsv/fsimage_0000000000004674911 -o /opt/client/imagecsv/fsimage.txt -p Delimited -delimiter "|"
其中-i是输入文件路径,-o是输出文件路径,-p指定处理器,当前有效的选项是Web(默认)、XML、Delimited、DetectCorruption、FileDistribution和ReverseXML
-delimiter 是指定数据分隔符,由于解析文件较大,执行此命令的客户端进程默认内存较小,建议针对较大的fsimage文件提前调整客户端进程内存,对于16G大小的fsimage文件,建议调整客户端内存到64G(当然首先要保证主机内存足够),对于MRS客户端,可以执行如下命令调整客户端内存 export HADOOP_CLIENT_OPTS="-Xmx64G"
上传hdfs:hdfs dfs -put fsimage.txt /tmp/fsimage/
2.创建hive表
CREATE TABLE `fsimage_view`(
path string,
replication int,
modificationtime string,
accesstime string,
preferredblocksize bigint,
blockscount int,
filesize bigint,
nsquota string,
dsquota string,
permission string,
username string,
groupname string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '|' stored as textfile;
3.将解析的fsimage文本数据导入到hive表
LOAD DATA INPATH '/tmp/fsimage/fsimage.txt' OVERWRITE INTO TABLE fsimage_view;
4.数据加工处理
先查询少量数据熟悉数据结构
select path,replication,blockscount,filesize from fsimage_view where replication != 0 limit 2;
上述数据表示,path 对应路径下文件的副本数是多少,块数是多少,文件大小是多少,如果对应是目录的情况,则这些都是0或者NULL,表全量字段比这个多,其他字段对文件分析暂时帮助不大,可以忽略。
原始表中文件大小以及对应的用户都有显示,也可以根据不同用书的文件大小进行求和,这样可以算出单个用户创建的文件总大小,便于总结输出不同业务占用的空间,select sum(filesize*replication) size,username from fsimage_view group by username order by size desc;
如果需要进行小文件就更复杂些,原则上我们需要将某个目录下的文件数、文件大小和块数进行求和,以得出三级目录或者四级目录下平均文件大小和文件数、block块数,为了便于理解,将path路径经过处理,形成最终分析的数据表,将上述表中path路径经过处理分析后,存入到目标表中
创建目标表,其中path代表原目录,/代表根目录也就是一级目录,p2代表二级目录,p3代表三级目录,p4代表四级目录,p5代表五级目录,p6代表六级目录
create table fsimage_view_group(
path string,
p2 string,
p3 string,
p4 string,
p5 string,
p6 string,
blockscount int,
filesize bigint)ROW FORMAT DELIMITED FIELDS TERMINATED BY '|' stored as textfile;
将原始数据表中path经过分析处理,分析sql如下:
insert into fsimage_view_group
select path,
p2,
p3,
p4,
p5,
concat(p5,'/',split(path, '/')[5]) as p6,
blockscount,
filesize
from
(select path,
p2,
p3,
p4,
concat(p4,'/',split(path, '/')[4]) as p5,
blockscount,
filesize
from
(select path,
p2,
p3,
concat(p3,'/',split(path, '/')[3]) as p4,
blockscount,
filesize
from
(select path,
p2,
concat(p2,'/',split(path, '/')[2] ) as p3,
blockscount,
filesize
from
(select path,
concat('/',split(path, '/')[1] ) as p2,
blockscount,
filesize
from
fsimage_view
)tmp
)tmp1
)tmp2
)tmp3;
简单来讲就是将path目录根据/分隔,生成二级三级目录等,值得注意的是,split函数,若数组不存在对应下标值,返回的是NULL,也就是说,如果split出来不存在二级、三级、四级、五级、六级目录,则对应值为NULL;另外,当对应二级、三级、四级、五级、六级目录其中一个和path相等时且为文件时,为了后续分析方便,可以进行处理,需要再次进行处理,相等的应二级、三级、四级、五级、六级目录值置位NULL,由于hive对数据更新支持较弱,这里可以引入第三张表来存储处理分析后的数据,由于本张表已经足够进行小文件分布的分析,故这里不赘述进一步数据处理过程。
5.小文件分析
根据上述表结构,对filesize小于10M、20M、30M、40M、50M的文件进行分析排序,如下语句是分析小于10M的文件对应所在的二级目录以及小于10M的文件数
select p2,count(*) as count from fsimage_view_group where filesize < 10485760 and filesize !=0 group by p2 order by count DESC;
也可以继续向下分析对应子目录小文件分析情况,当然你也可以根据上述表数据情况,自己进行多个维度的统计分析,比如分析副本数为1的文件所在的目录等。对于现网情况,也可以将上述步骤制作成定时任务,定期分析小文件分布情况。
- 点赞
- 收藏
- 关注作者
评论(0)