草庐IT

hdfs小文件合并

孩子加油孩子 2023-12-14 原文

大数据平台小文件统计及合并

一、小文件统计

1. 统计方法

将namenode 的镜像文件导入hive表,通过sql查询即可统计小文件数量情况。

查看镜像文件: oiv

hdfs oiv -p 文件类型 -i 镜像文件 -o 转换后文件输出路径

1.导出镜像文件:

 hdfs dfsadmin -fetchImage /home/bigdata/fsimage/fsimage_$date

2.解析镜像文件为 "," 逗号分割的csv文件

hdfs oiv -p Delimited -delimiter , -t temporaryDir -i /home/bigdata/fsimage/fsimage_$date -o /home/bigdata/fsimage/fsimage_$date.csv

3.删除csv文件第一行表头信息: Path,Replication,ModificationTime,AccessTime,PreferredBlockSize,BlocksCount,FileSize,NSQUOTA,DSQUOTA,Permission,UserName,GroupName

sed -i '1d' /home/bigdata/fsimage/fsimage_$date.csv

4.导入hive表

4-1. 创建hive分区表(按时间分区):按照导出的表头创建hive表
CREATE TABLE default.fsimage_info_csv(
path string ,
replication int,
modificationtime string,
accesstime string,
preferredblocksize bigint,
blockscount int,
filesize bigint,
nsquota string,
dsquota string,
permission string,
username string,
groupname string)
partitioned by (createdate string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES ( 'field.delim'=',' , 'serialization.format'=',' )
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'; 
4-2. 将镜像文件数据导入hive表:
sql="load data local inpath '/home/bigdata/fsimage/fsimage_$date.csv' into table default.fsimage_info_csv partition(createdate='$date')"
hive -e $sql

hdfs小文件统计参考链接

2. 统计

1.统计hdfs镜像记录中小于60M的文件

通过统计小文件,发现主要是hive表落盘数据小文件较多;有的表达到每日增量4000多小文件;

2.测试目录数据删除( /tmp目录和特殊目录 )

/tmp 目录下 48000个文件,占用空间4211220.19 M(4T)

FSIMG_FILE_STATIC.LEVELFSIMG_FILE_STATIC.PATHFSIMG_FILE_STATIC.SMALL_FILE_NUMFSIMG_FILE_STATIC.FILE_NUMFSIMG_FILE_STATIC.SUM_SMALL_FILE_SIZEFSIMG_FILE_STATIC.SUM_FILE_SIZEFSIMG_FILE_STATIC.CREATEDATE
3/apps/hive/warehouse110769791147938714698785.20102354870.3820220818
3/app-logs/root/logs-ifile304869304984153710.04281023.6620220818
3/data/monitor/source1031053650642111568.5090465815.0420220818
3/data/monitor/checkpoint4915549155598.46598.4620220818

二、小文件合并策略调研

小文件影响:

在HDFS中,任何一个文件,目录或者block在NameNode节点的内存中均以一个对象表示(元数据),而这受到NameNode物理内存容量的限制。每个元数据对象约占150byte,所以如果有1千万个小文件,每个文件占用一个block,则NameNode大约需要15G空间。如果存储1亿个文件,则NameNode需要150G空间,这毫无疑问1亿个小文件是不可取的.

小文件合并方案:

hdfs文件系统中的文件分为下面几类:

  1. 数据中心落盘文件

  2. hive 数据文件

  3. 系统应用文件

经过技术调研发现均可以用har对hdfs上的文件进行归档。 以下是对小文件合并做的一些实验操作。

实验1. 文件追加合并小文件

1.将hdfs /tmp/test/目录下的part-0-7.gz追加到 part-1-8.gz 文件:(appendToFile)

执行命令:

hdfs dfs -cat /tmp/test/part-0-7.gz  | hdfs dfs -appendToFile - /tmp/test/part-1-8.gz

2.追加命令执行成功,part-1-8.gz文件大小为28.1M(16.7M+11.3M两个文件之和 )

3.下载该part-1-8.gz文件并解压到本地,查看内容:

hdfs dfs -cat /tmp/test/part-1-8.gz | zcat > append_m3_xian.txt

追击后的文件行数与两个文件行数之和一致。

适用范围:

  1. 适合hdfs 普通文件或压缩文件;

  2. hive orc格式的不支持(追加后hive查询会报错)

  3. 操作不够简单

实验2. har 归档方式

在HDFS之上构建一个分层文件系统。通过执行hadoop archive 命令可以创建一个HAR文件。hadoop Archive是一个高效地将小文件放入HDFS块中的文件存档文件格式,它通过将多个小文件打包成一个后缀为.har文件来减少HDFS中的文件数量。

上图为HAR文件的文件结构,访问一个指定的小文件需要访问两层索引文件才能获取小文件在HAR文件中的存储位置,因此,访问一个HAR文件的效率可能会比直接访问HDFS文件要低。

对于一个mapreduce任务来说,如果使用HAR文件作为其输入,仍旧是其中每个小文件对应一个map task,效率低下。所以,HAR files最好是用于文件归档。

上图为Hadoop存档目录,其中包含元数据(以index和masterindex的形式)和数据(part- *)文件。 _index文件包含作为归档文件一部分的文件名以及这些文件内的位置。

归档命令会转换成一个mapreduce 任务;

1)归档特点:

1、存档文件的源文件目录以及源文件都不会自动删除需要手动删除
2、存档的过程实际是一个mapreduce过程,所以需要需要hadoop的mapreduce的支持
3、存档文件本身不支持压缩
4、存档文件一旦创建便不可修改,要想从中删除或者增加文件,必须重新建立存档文件
5、创建存档文件会创建原始文件的副本,所以至少需要有与存档文件容量相同的磁盘空间
6、要归档的文件名中不能有空格,否则会抛出异常,可以将空格用其他符号替换(使用-Dhar.space.replacement.enable=true 和-Dhar.space.replacement参数)。
7、对于一个mapreduce任务来说,如果使用HAR文件作为其输入,仍旧是其中每个小文件对应一个map task,效率低下。所以,HAR files最好是用于文件归档。

2)归档操作说明:

1.归档命令:

归档文件:
hadoop archive -archiveName  m3_monitor.har -p /tmp/test/archive_test/m3_monitor/20220809 /tmp/test/archive
删除数据源目录:
hdfs dfs -rm -r /tmp/test/archive_test/m3_monitor/20220809
​
查看归档文件:
hdfs dfs -ls -R  har:///tmp/test/archive/m3_monitor.har
​
解归档:将归档文件内容拷贝到另一个目录:
hdfs dfs -cp har:///tmp/test/archive/m3_monitor.har/part-1-7.gz  /tmp/test/

参考链接:

归档操作说明

归档说明链接

hive表使用归档文件

实验3. hive 表使用 hive har 进行小文件合并

1)使用appendToFile合并hive orc文件(不支持合并操作)--不可用

hdfs dfs -cat /tmp/test/hive/000203_0 | hdfs dfs -appendToFile - /tmp/test/hive/000204_0

加载进入hive后: 执行查询操作报错;

hive> select * from ods.tb_bu_dc_monitor_day_bak1;
OK
Failed with exception java.io.IOException:java.lang.IllegalArgumentException: Buffer size too small. size = 262144 needed = 1206453
Time taken: 0.166 seconds

orc 格式的文件不支持 getmerge合并操作

hive 文件合并参考链接

2)使用hive concatenate (外部表不可用,内部表可用,orc可用)

使用方式:

#1.设置文件最小大小(需要设置,否则合并操作可能会不理想):
SET mapreduce.input.fileinputformat.split.maxsize=256
#对于非分区表
alter table A concatenate;
#2.对于分区表
alter table B partition(day=20201224) concatenate;

使用限制:

  1. 不支持外部表,只支持内部表;

  2. concatenate 命令只支持 RCFILE 和 ORC 文件类型。

  3. 使用concatenate命令合并小文件时不能指定合并后的文件数量,但可以多次执行该命令参考链接

  4. 当多次使用concatenate后文件数量不再变化,这个跟参数 mapreduce.input.fileinputformat.split.minsize=256mb 的设置有关,可设定每个文件的最小size。

3)使用hive har 归档命令

#用来控制归档是否可用
set hive.archive.enabled=true;
#通知Hive在创建归档时是否可以设置父目录
set hive.archive.har.parentdir.settable=true;
#控制需要归档文件的大小
set har.partfile.size=1099511627776;
#使用以下命令进行归档
ALTER TABLE A ARCHIVE PARTITION(dt='2022-02-24', hr='12');
#对已归档的分区恢复为原文件
ALTER TABLE A UNARCHIVE PARTITION(dt='2022-02-24', hr='12');

ALTER TABLE default.tb_bu_dc_monitor_day_bak_manage ARCHIVE partition(dc_code='wgq_monitor',data_date='20220820');

ALTER TABLE default.tb_bu_dc_monitor_day_bak_manage UNARCHIVE PARTITION(dc_code='wgq_monitor',data_date='20220820');

归档后文件: 分区数据目录下只有一个dat.har文件,原来的数据文件都被删除。

解归档后:分区目录下的dat.har文件删除,新增了原来的数据文件。

4.网上的脚本做小文件合并的:

hdfs小文件使用fsimage分析实例_Direction_Wind的博客-CSDN博客_hdfs小文件分析

filecrush/bin at master · asdaraujo/filecrush · GitHub 开源代码;

三、小文件合并方案总结


目前大数据平台hdfs数据存储情况:

数据仓库中的表:
1.stg层是把flink应用程序写入的数据load进入的;
2.ods层表名称中包含ai的表是从mysql导入的; 
/_SCRATCH0 这些目录是sqoop 把mysql数据导入hive时生成的临时目录,可以删除。
3.stg 和 ods 的 tb_bu_dc_monitor_day 是外部表,其他层的表都是内部表;
4.stg层是原始数据,没有经过压缩处理,ods及以后其他各层都是orc格式
flink程序落盘数据路径:
/data/monitor/source 是各个数据中心指标的落盘数据;

1.hive表使用hive归档命令来进行压缩;

2.flink落盘数据 使用har归档;

四、小文件优化:

hive表数据mapreduce操作落盘做参数优化,对落盘文件大小进行限制。

目前hive使用的是默认的16M

hive小文件参数调优

SET hive.exec.dynamic.partition=true; 
#使用动态分区
SET hive.exec.dynamic.partition.mode=nonstrict;
#默认值为srticat,nonstrict模式表示允许所有分区字段都可以使用动态分区
SET hive.exec.max.dynamic.partitions=3000;
#在所有执行MR的节点上,共可以创建多少个动态分区
SET  hive.exec.max.dynamic.partitions.pernode=500;
#在执行MR的单节点上,最大可以创建多少个分区
SET hive.merge.tezfiles=true;
#tez任务结束时合并小文件
SET hive.merge.smallfiles.avgsize=1280000000;
#当输出文件平均大小小于该值时。启用独立的TEZ任务进行文件合并
SET hive.merge.size.per.task=1280000000;
#合并文件大小128M
————————————————
版权声明:本文为CSDN博主「Impl_Sunny」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011487470/article/details/120970962

有关hdfs小文件合并的更多相关文章

  1. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  2. git使用常见问题(提交代码,合并冲突) - 2

    文章目录git常用命令(简介,详细参数往下看)Git提交代码步骤gitpullgitstatusgitaddgitcommitgitpushgit代码冲突合并问题方法一:放弃本地代码方法二:合并代码常用命令以及详细参数gitadd将文件添加到仓库:gitdiff比较文件异同gitlog查看历史记录gitreset代码回滚版本库相关操作远程仓库相关操作分支相关操作创建分支查看分支:gitbranch合并分支:gitmerge删除分支:gitbranch-ddev查看分支合并图:gitlog–graph–pretty=oneline–abbrev-commit撤消某次提交git用户名密码相关配置g

  3. Ruby 哈希直接访问与合并 - 2

    有什么区别:@attr[:field]=new_value和@attr.merge(:field=>new_value) 最佳答案 如果您使用的是merge!而不是merge,则没有区别。唯一的区别是您可以在合并参数中使用多个字段(意思是:另一个散列)。例子:h1={"a"=>100,"b"=>200}h2={"b"=>254,"c"=>300}h3=h1.merge(h2)putsh1#=>{"a"=>100,"b"=>200}putsh3#=>{"a"=>100,"b"=>254,"c"=>300}h1.merge!(h2)pu

  4. ruby - 在两个 ActiveRecord 类之间合并/复制属性的好方法? - 2

    之前有人问过这个问题,我发现了以下clip关于如何一次设置一个类对象的所有属性,但由于批量分配保护,这在Rails中是不可能的。(例如,您不能Object.attributes={})有没有一种很好的方法可以将一个类的属性合并到另一个类中?object1.attributes=object2.attributes.inject({}){|h,(k,v)|h[k]=vifObjectModel.column_names.include?(k);h}谢谢。 最佳答案 利用assign_attributes使用:without_prote

  5. ruby - 合并 nanoc 中的项目 - 2

    我一直在尝试使用nanoc用于生成静态网站。我需要组织一个复杂的排列页面,我想让我的内容保持干燥。包含或合并的概念在nanoc系统中如何运作?我已阅读文档,但似乎找不到我想要的内容。例如:我如何获取两个部分内容项并将它们合并到一个新的内容项中。在staticmatic您可以在您的页面中执行以下操作。=partial('partials/shared/navigation')类似的约定在nanoc中如何运作? 最佳答案 这里是nanoc的作者。在nanoc中,部分是布局。因此,您可以拥有layouts/partials/shared/

  6. ruby-on-rails - Rails 合并两个哈希数组? - 2

    我很难理解我需要合并两个哈希数组的逻辑,看来我已经问过hisquestionawhileback以不同的方式,我还尝试了其他一些方法,例如此处提供的答案:mergingarraysofhashes任何形式的帮助理解这对我来说都是非常有帮助的。假设我有以下数组,这是方法本身的输出,所以你可以想象那些:timestamp是Time对象[{:timestamp=>2011-12-1900:00:00UTC},{:timestamp=>2011-12-1901:00:00UTC},{:timestamp=>2011-12-1902:00:00UTC},{:timestamp=>2011-12-

  7. ruby - 将散列与 ruby​​ 中字符串的键/值合并 - 2

    我正在尝试将散列与ruby​​中字符串的键/值合并。即h={:day=>4,:month=>8,:year=>2010}s="/my/crazy/url/:day/:month/:year"putss.interpolate(h)我所发现的只是迭代键并替换值。但是我不确定是否有更好的方法来做到这一点?:)classString definterpolate(e)  selfife.each{|k,v|self.gsub!(":#{k}","#{v}")} endend谢谢 最佳答案 无需重新发明Ruby内置函数:h={:day=>4

  8. ruby-on-rails - 合并两个 ruby 对象 - 2

    问题:在Ruby(和/或Rails)中是否有一种简洁的方法可以将两个对象合并在一起?具体来说,我试图找出类似于jQuery的$.extend()方法的方法,而您传入​​的第一个对象的属性将被第二个对象覆盖。我正在使用Rails3.2+中的无表模型。当发生表单提交时,来自提交的参数用于动态填充用户对象。该用户对象使用Ruby的PStore类在页面请求之间持久保存,将对象编码为将来可以轻松检索的平面文件。相关代码:moduleItcclassUserincludeActiveModel::ValidationsincludeActiveModel::ConversionincludeAct

  9. ruby - 是否可以使用 Ruby 将一系列 PDF 合并为一个? - 2

    我有一系列按顺序命名的PDF:01_foo.pdf02_bar.pdf03_baz.pdf等等使用Ruby,是否可以将它们组合成一个大PDF,同时保持它们的顺序?我不介意安装任何必要的gem来完成这项工作。如果这在Ruby中是不可能的,那么另一种语言呢?如果可能,不要使用商业组件。更新:JasonNavarrete'ssuggestion导致完美的解决方案:将需要合并的PDF文件与pdftk放在一个目录下(或确保pdftk在您的PATH中),然后运行以下脚本:pdfs=Dir["[0-9][0-9]_*"].sort.join("")`pdftk#{pdfs}outputcombine

  10. 如何使用open3d合并多组mesh并输出结果 - 2

    关注公众号,发现CV技术之美最近在学习open3d的相关应用,然后遇到了一个很有趣的问题。给定多个mesh,我们可能会需要把他们全部合并到一个文件并使用。但是这并不好实现,因为open3d自己不支持这样的操作。相比之下,其他一些集成度非常高的软件,是可以实现这样的操作的,例如meshlab通过交互栏中的“flattenvisiblelayer”指令来实现。唯一的缺点是,你每次都需要手动操作才行,这对于需要高度自动化的使用场景,就不是很合适了。因此,如何可以实现一个自动化的脚本,支持直接合并多个可染色的mesh,并输出带有纹理的最终结果,是一个非常重要的功能。遗憾的是度娘和谷歌目前没有相关的教程

随机推荐