- 如何打造数据治理闭环?以保[2022-06-16]
- 什么样的公司需要数据治理?[2022-06-15]
- “互联网+政务服务”下的数[2022-06-14]
- 我国数据安全治理研究[2022-06-13]
- 反洗钱视角下的数据治理[2022-06-10]
- 浅谈数据质量管理[2022-06-08]
- 做数据治理前,必须了解并避[2022-06-07]
- 企业数据治理团队的十大职[2022-06-06]
- 浅谈数据质量管理[2022-06-02]
- 数据治理的三种共享范式[2022-06-01]
大数据-Hadoop小文件问题解决方案
HDFS中小文件是指文件size小于HDFS上block( dfs.block.size
)大小的文件。大量的小文件会给hadoop的扩展性和性能带来严重的影响。
小文件是如何产生的?
1.动态分区插入数据,产生大量的小文件,从而导致map数量剧增
2.reduce数量越多,小文件也越多,reduce的个数和输出文件个数一致
3.数据源本身就是大量的小文件
小文件问题的影响
1.从Mapreduce的角度看,一个文件会启动一个map,所以小文件越多,map也越多,一个map启动一个jvm去执行,所以这些任务的初始化,启动,执行会浪费大量的资源,严重的影响性能。
2.从HDFS角度看,HDFS中文件元信息(位置,大小,分块等)保存在NameNode的内存中,每个对象大约占用150字节,如果小文件过多,会占用大量内存,直接影响NameNode的性能;HDFS读写小文件也会更加耗时,因为每次都需要从NameNode获取元信息,并与对应的DataNode建立连接。
如何解决小文件问题
1.输入合并,在Map前合并小文件
2.输出合并,在输出结果的时候合并小文件
3.控制reduce个数来实现减少小文件个数
配置Map输入合并
可以通过在输入mapper的之前将是输入合并,以减少map的个数。
-- 每个Map最大输入大小,决定合并后的文件数
set mapred.max.split.size=256000000;
-- 一个节点上split的至少的大小 ,决定了多个data node上的文件是否需要合并
set mapred.min.split.size.per.node=100000000;
-- 一个交换机下split的至少的大小,决定了多个交换机上的文件是否需要合并
set mapred.min.split.size.per.rack=100000000;
-- 执行Map前进行小文件合并
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
配置Hive输出结果合并
-- 在map-only job后合并文件,默认true
set hive.merge.mapfiles=true;
-- 在map-reduce job后合并文件,默认false
set hive.merge.mapredfiles=true;
-- 设置合并后文件大大小,默认256000000
set hive.merge.size.per.task=256000000;
-- 当输出文件的平均值大小小于该值是,启动一个独立的MR任务进行文件merge,是决定是否执行合并操作的阈值,默认16000000
set hive.merge.smallfiles.avgsize=16000000;
Hadoop Archive(HAR)
Hadoop Archive是一种特殊的归档格式,Hadoop Archive映射到文件系统目录,一个HAR是以扩展名 .har
结尾 ,一个HAR目录包含元数据(以_index和_masterindex的形式)和data(part-*)文件。_index文件包含文件名称,这些文件是归档的一部分,并且包含这些文件在归档中的位置。
Hadoop Archive是一个高效地将小文件放入HDFS块中的文件存档工具,它能将多个小文件打包成一个HAR文件,这样在减少NameNode内存使用的同时,仍然允许对文件进行透明的访问。
使用hadoop命令进行文件归档
hadoop archive -archiveName name -p <parent> <src>* <dest>
hadoop archive -archiveName zoo.har -p /foo/bar /outputdir
可以通过设置 -Dhar.block.size
参数来指定HAR的大小。
在Hive中进行归档处理
Hive支持将已存的分区转换为HAR,从而使得分区下的文件数目大大减少。但是从HAR读数据需要额外的开销,因此查询归档下数据可能会变慢。
set hive.archive.enabled= true;set hive.archive.har.parentdir.settable= true;set har.partfile.size=1099511627776;ALTER TABLE test ARCHIVE PARTITION(year='2017');ALTER TABLE test UNARCHIVE PARTITION(year='2017');
如果不是分区表,可以创建成外部表,使用 har://
协议来指定路径。
SequenceFile
SequenceFile是一个由二进制序列化过的key/value字节流组成的文本存储文件,它可以在map/reduce过程中的input/output的format时被使用。在map/reduce过程中,map处理文件的临时输出就是使用SequenceFile处理过的。
使用SequenceFile作为表存储格式。
create table test2
STORED AS SEQUENCEFILEAS SELECT * FROM test;
控制reducer个数
为了提升MR的运算速度,可以通过增加reducer的个数,Hive也会做类似的优化,Reducer数量等于源数据量除以 hive.exec.reducers.bytes.per.reducer
所配置的量(默认是1G)。Reducer的数量决定了结果文件的数量。所以在合适的情况下控制reducer的数量,可以实现减少小文件数量。
reducer决定因素:
· hive.exec.reducers.bytes.per.reducer
:这个参数控制一个job会有多少个reducer来处理,依据的是输入文件的总大小。默认1GB。
· hive.exec.reducers.max
:这个参数控制最大的reducer的数量, 如果 input / bytes per reduce > max
则会启动这个参数所指定的reduce个数。 这个并不会影响 mapre.reduce.tasks
参数的设置。默认的max是999。
· mapred.reduce.tasks
:这个参数如果指定了,hive就不会用它的estimation函数来自动计算reduce的个数,而是用这个参数来启动reducer。默认是-1.
在hive中可以通过调整上面三个参数实现控制reducer的个数。