Hadoop/Hive/Spark小文件处理

news2024/11/24 3:49:10

什么是小文件?

小文件指的是文件size比HDFS的block size小很多的文件。Hadoop适合处理少量的大文件,而不是大量的小文件。

hadoop小文件常规的处理方式

1、小文件导致的问题

首先,在HDFS中,任何block,文件或者目录在内存中均以对象的形式存储,每个对象约占150byte,如果有1000 0000个小文件,每个文件占用一个block,则namenode大约需要2G空间。如果存储1亿个文件,则namenode需要20G空间。这样namenode内存容量严重制约了集群的扩展。
其次,访问大量小文件速度远远小于访问几个大文件。HDFS最初是为流式访问大文件开发的,如果访问大量小文件,需要不断的从一个datanode跳到另一个datanode,严重影响性能。
最后,处理大量小文件速度远远小于处理同等大小的大文件的速度。每一个小文件要占用一个slot,而task启动将耗费大量时间甚至大部分时间都耗费在启动task和释放task上。

2、Hadoop自带的解决方案

对于小文件问题,Hadoop本身也提供了几个解决方案,分别为: Hadoop Archive , Sequence
file 和 CombineFileInputFormat 。

  • Hadoop Archive
    Hadoop Archive或者HAR,是一个高效地将小文件放入HDFS块中的文件存档工具,它能够将多
    个小文件打包成一个HAR文件,这样在减少namenode内存使用的同时,仍然允许对文件进行
    透明的访问。
  • Sequence file
    sequence file由一系列的二进制key/value组成,如果为key小文件名,value为文件内容,则可
    以将大批小文件合并成一个大文件。
  • CombineFileInputFormat
    它是一种新的inputformat,用于将多个文件合并成一个单独的split,另外,它会考虑数据的
    存储位置。

Hadoop Archive

Hadoop Archive或者HAR,是一个高效地将小文件放入HDFS块中的文件存档工具,它能够将多个小文件打包成一个HAR文件,这样在减少namenode内存使用的同时,仍然允许对文件进行透明的访问。对某个目录/foo/bar下的所有小文件存档成/outputdir/ zoo.har:

hadoop archive -archiveName zoo.har -p /foo/bar /outputdir

当然,也可以指定HAR的大小(使用-Dhar.block.size)。
HAR是在Hadoop file system之上的一个文件系统,因此所有fs shell命令对HAR文件均可用,只不过是文件路径格式不一样,HAR的访问路径可以是以下两种格式:

har://scheme-hostname:port/archivepath/fileinarchive
har:///archivepath/fileinarchive(本节点)

可以这样查看HAR文件存档中的文件:

hadoop dfs -ls har:///user/zoo/foo.har

输出:

har:///user/zoo/foo.har/hadoop/dir1
har:///user/zoo/foo.har/hadoop/dir2

使用HAR时需要两点
第一,对小文件进行存档后,原文件并不会自动被删除,需要用户自己删除;
第二,创建HAR文件的过程实际上是在运行一个mapreduce作业,因而需要有一个hadoop集群运行此命令。

此外,HAR还有一些缺陷:
第一,一旦创建,Archives便不可改变。要增加或移除里面的文件,必须重新创建归档文件。
第二,要归档的文件名中不能有空格,否则会抛出异常,可以将空格用其他符号替换
(使用-Dhar.space.replacement.enable=true 和-Dhar.space.replacement参数)。
第三,存档文件不支持压缩。

一个归档后的文件,其存储结构如下图:
在这里插入图片描述

Sequence file

Sequence file由一系列的二进制key/value组成,如果为key小文件名,value为文件内容,则可以将大批小文件合并成一个大文件。
Hadoop-0.21.0中提供了SequenceFile,包括Writer,Reader和SequenceFileSorter类进行写,读和排序操作。
在这里插入图片描述
创建sequence file的过程可以使用mapreduce工作方式完成,对于index,需要改进查找算法
优缺点:对小文件的存取都比较自由,也不限制用户和文件的多少,但是该方法不能使用append方
法,所以适合一次性写入大量小文件的场景

CombineFileInputFormat

CombineFileInputFormat是一种新的inputformat,用于将多个文件合并成一个单独的split,另外,它会考虑数据的存储位置。

Hive小文件问题怎么解决?

首先,我们要弄明白两个问题:
1)哪里会产生小文件
源数据本身有很多小文件
动态分区会产生大量小文件
reduce个数越多, 小文件越多
按分区插入数据的时候会产生大量的小文件, 文件个数 = maptask个数 * 分区数

2)小文件太多造成的影响
从Hive的角度看,小文件会开很多map,一个map开一个JVM去执行,所以这些任务的初始化,启
动,执行会浪费大量的资源,严重影响性能。
HDFS存储太多小文件, 会导致namenode元数据特别大, 占用太多内存, 制约了集群的扩展

小文件解决方案:

方法一:通过调整参数进行合并

1)在Map输入的时候, 把小文件合并

-- 每个Map最大输入大小,决定合并后的文件数
setmapred.max.split.size=256000000;
-- 一个节点上split的至少的大小,决定了多个datanode上的文件是否需要合并
setmapred.min.split.size.per.node=100000000;
-- 一个交换机下split的至少的大小,决定了多个交换机上的文件是否需要合并
setmapred.min.split.size.per.rack=100000000;
-- 执行Map前进行小文件合并
sethive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

2)在Reduce输出的时候, 把小文件合并

-- 在map-onlyjob后合并文件,默认true
sethive.merge.mapfiles=true;
-- 在map-reducejob后合并文件,默认false
sethive.merge.mapredfiles=true;
-- 合并后每个文件的大小,默认256000000
sethive.merge.size.per.task=256000000;
-- 平均文件大小,是决定是否执行合并操作的阈值,默认16000000 sethive.merge.smallfiles.avgsize=100000000;

方法二:针对按分区插入数据的时候产生大量的小文件的问题,可以使用DISTRIBUTE BY rand() 将数据

随机分配给Reduce,这样可以使得每个Reduce处理的数据大体一致。

-- 设置每个reducer处理的大小为5个G
sethive.exec.reducers.bytes.per.reducer=5120000000;
-- 使用distributebyrand()将数据随机分配给reduce,避免出现有的文件特别大,有的文件特别小insertoverwritetabletestpartition(dt)
select * from iteblog_tmp
DISTRIBUTEBYrand();

方法三:使用Sequencefile作为表存储格式,不要用textfile,在一定程度上可以减少小文件

方法四:使用hadoop的archive归档

-- 用来控制归档是否可用
set hive.archive.enabled=true;
-- 通知Hive在创建归档时是否可以设置父目录
set hive.archive.har.parentdir.settable=true;-- 控制需要归档文件的大小
set har.partfile.size=1099511627776;
-- 使用以下命令进行归档
ALTER TABLE srcpart ARCHIVE PARTITION(ds='2008-04-08',hr='12');
- 对已归档的分区恢复为原文件
ALTER TABLE srcpart UNARCHIVE PARTITION(ds='2008-04-08',hr='12');
-- 注意,归档的分区不能够INSERTOVERWRITE,必须先unarchive

Spark输出文件的个数,如何合并小文件?

当使用spark sql执行etl时候出现了,最终结果大小只有几百k,但是小文件一个分区可能就有上千的情况。
小文件过多的一些危害如下:

  • hdfs有最大文件数限制
  • 浪费磁盘资源(可能存在空文件)
  • hive中进行统计,计算的时候,会产生很多个map,影响计算的速度。

解决方案如下:

方法一:通过spark的coalesce()方法和repartition()方法

val rdd2 = rdd1.coalesce(8, true) //(true表示是否shuffle)
val rdd3 = rdd1.repartition(8)

coalesce:coalesce()方法的作用是返回指定一个新的指定分区的Rdd,如果是生成一个窄依赖的结果,那么可以不发生shuffle,分区的数量发生激烈的变化,计算节点不足,不设置true可能会出错。
repartition:coalesce()方法shuffle为true的情况。

方法二:降低spark并行度,即调节spark.sql.shuffle.partitions

比如之前设置的为100,按理说应该生成的文件数为100;
但是由于业务比较特殊,采用的大量的union all,且union all在spark中属于窄依赖,不会进行shuffle,所以导致最终会生成(union all数量+1)*100的文件数。
如有10个union all,会生成1100个小文件。这样导致降低并行度为10之后,执行时长大大增加,且文件数依旧有110个,效果不理想。

方法三:新增一个并行度=1任务,专门合并小文件

先将原来的任务数据写到一个临时分区(如tmp);再起一个并行度为1的任务,类似:

insert overwrite 目标表 select * from 临时分区

结果小文件数还是没有减少,经过多次测后发现原因:‘select * from 临时分区’ 这个任务在spark中属于窄依赖;
并且spark DAG中分为宽依赖和窄依赖,只有宽依赖会进行shuffle;
故并行度shuffle,spark.sql.shuffle.partitions=1也就没有起到作用;

由于数据量本身不是特别大,所以直接采用了group by(在spark中属于宽依赖)的方式,类似:

insert overwrite 目标表 select * from 临时分区 group by * 

先运行原任务,写到tmp分区,‘dfs -count’查看文件数,1100个,运行加上group by的临时任务
(spark.sql.shuw le.partitions=1),查看结果目录,文件数=1,成功。

总结:

1)方便的话,可以采用coalesce()方法和repartition()方法
2)如果任务逻辑简单,数据量少,可以直接降低并行度
3)任务逻辑复杂,数据量很大,原任务大并行度计算写到临时分区,再加两个任务:
一个用来将临时分区的文件用小并行度(加宽依赖)合并成少量文件到实际分区
另一个删除临时分区
4)hive任务减少小文件相对比较简单,可以直接设置参数,如:
Map-only的任务结束时合并小文件:

set hive.merge.mapfiles = true

在Map-Reduce的任务结束时合并小文件:

set hive.merge.mapredfiles= true

当输出文件的平均大小小于1GB时,启动一个独立的map-reduce任务进行文件merge:

set hive.merge.smallfiles.avgsize=1024000000

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

吴恩达471机器学习入门课程1第1周——梯度下降

文章目录 1加载数据集2计算COST(均值平方差,1/2m(y_pre - y))3计算梯度4画出成本曲线5梯度下降 import math, copy import numpy as np import matplotlib.pyplot as plt plt.style.use(./deeplearning.mplstyle) from lab_utils_uni import plt_house_x, plt_conto…

华为OD机试真题 JavaScript 实现【找出通过车辆最多颜色】【2023Q1 100分】

一、题目描述 在一个狭小的路口,每秒只能通过一辆车,假如车辆的颜色只有3种,找出n秒内经过的最多颜色的车辆数量。 三种颜色编号为0、1、2。 二、输入描述 第一行输入的是通过的车辆颜色信息 [0 1 1 2] 代表4秒钟通过的车辆颜色分别是0 1…

手把手教你使用CONN(预处理)

CONN软件介绍 (1)CONN是一个基于Matlab的跨平台软件,用于计算、显示和分析功能磁共振成像(fcMRI)中的功能连通性。也可用于静息状态数据(rsfMRI)以及任务相关设计。 (2&#xff09…

Vue的组合式

1. 概念 选项式API:将相同类型的代码放在一起(比如所有数据、所有用到的方法等等)当代码业务板块过多时,不方便写代码和后期维护 组合式API:将同一业务的相关代码放在一起(比如说数据,方法&am…

什么是同源策略

文章目录 同源策略同源策略的目的同源策略分类 同源策略 同源策略是指浏览器的一种安全机制,用于限制来自不同源(即域、协议或端口)的文档或脚本之间的交互操作。 根据同源策略,浏览器只允许当前网页与同一源下的其他资源进行交…

Linux之CentOS 7.9部署Oracle 11g r2 静默安装实测验证(无桌面模式)

前言:因前段时间一直部署的windows环境的oracle,这次记录下linux下的部署方式,当然还有更多的其他部署,大家可根据自身环境及学习来了解。一般静默安装主要还是要提前准备源包,还有很多依赖包,另外就是配置…

如何显示文件后缀名,这4个方法很简单!

Anna最近想对电脑里的文件进行分类,但有些未知类型的文件,她想查看文件的类型并进行分类,可是她不知道如何显示文件后缀名,因此向大家求助。 在计算机操作中,文件的后缀名是文件名的一部分,用于标识文件的类…

FlinkSQL写入iceberg—Windows环境下

前置条件 Flink运行版本13.1&#xff0c;iceberg依赖版本&#xff1a;1.0.0 依赖 FlinkSQL运行环境略。 注意版本匹配&#xff0c;采用不合适版本可能导致无法读写。 <!-- Flink 操作Iceberg 需要的Iceberg依赖 --><dependency><groupId>org.apache.iceb…

shell脚本变量-特殊变量

目录 特殊变量&#xff1a;$n案例需求 特殊变量&#xff1a;$#案例需求 特殊变量&#xff1a;$*、$案例需求 特殊变量&#xff1a;$&#xff1f;特殊变量&#xff1a;$$ 特殊变量&#xff1a;$n 语法 $n含义&#xff1a; 用于接收脚本文件执行时传入的参数 $0 用于获取当前脚…

机器人系统中的六大漏洞

原创 | 文 BFT机器人 在过去的几十年里&#xff0c;创新和技术导致机器人技术不断发展。 机器人系统正在迅速变得更加多产、复杂、有能力、智能化和网络化&#xff0c;并被用于越来越多的任务。 最初&#xff0c;机器人技术领域仅限于制造领域&#xff0c;但现在机器人可以与人…

KMP算法 - 确定有限状态自动机

KMP神在哪里&#xff1f; 子串匹配问题&#xff0c;拍脑袋一下子想出来的暴力解法大抵都是两重for循环&#xff0c;不断重复扫描主串&#xff0c;与子窜进行匹配&#xff0c;重复换句话讲就是冗余&#xff0c;会有很高的时间复杂度 我先前博客大作业发的模糊查找算法就是如此&…

三分钟告诉你如何和智能ai聊天

有一个名叫艾丽的年轻女孩&#xff0c;她生活在一个科技发达的未来世界。在这个世界里&#xff0c;人们与人工智能伙伴共同生活。艾丽对ai技术充满好奇&#xff0c;尤其是对ai对话聊天工具的运作方式。为了知道ai对话聊天工具怎么用&#xff0c;艾丽决定展开探索。 方案一&…

智能无线监测器的工作原理及应用优势

在现代工业生产中&#xff0c;设备状态监测对于确保生产的安全性、效率和可靠性至关重要。随着科技的不断发展&#xff0c;智能无线监测器成为工业设备状态监测的利器。本文将介绍智能无线监测器在工业领域中的应用&#xff0c;以及其带来的优势和价值。 图.设备状态监测&#…

智驾风向标|卷、乱、难,如何穿越多极分化新周期?

竞争越来越卷&#xff0c;企业越来越难&#xff0c;市场处于混乱期。对于大多数供应商来讲&#xff0c;穿越新周期的战略一定是先有规模&#xff08;市场份额&#xff09;&#xff0c;然后才是利润。 在6月8日召开的2023&#xff08;第十四届&#xff09;高工智能汽车开发者大…

8个你必须知道的Java8新特性,让你的代码变得优雅!

Java 8 是一次重大的发行版更新&#xff0c;引入了大量新特性和改进&#xff0c;以下是 Java 8 的主要特性&#xff1a; 文章目录 Java 8 是一次重大的发行版更新&#xff0c;引入了大量新特性和改进&#xff0c;以下是 Java 8 的主要特性&#xff1a;1.Lambda 表达式2.Stream …

云平台 stm32连接阿里云2023最新版本保姆级别教学只看这一篇就够了~

注册账号 阿里云平台点击直达 点击控制台 鼠标悬浮会出现下拉栏 点击物联网 再点击物联网平台 点击公共实例 新用户需要开通 开通需要五分钟的时间 点击创建产品 蓝色显眼字体 参数设置 仔细比对下图 点击查看产品详情 蓝色显眼字体 点击功能定义 点击编辑草图 实际上就是定义…

如何通过Android平台的API实现5G网络的支持 安卓系统版本和5g网络相关【一】

前面分享了两篇5G基带相关的移植修改博文。 安卓高通机型的基带移植 修改 编译的相关 增加信号 支持5G等【一】 安卓高通机型的基带移植 修改 编译的相关 增加信号 支持5G等【二】 今天的帖子聊聊安卓版本与5G网络与机型和修改之间相关的话题。众所周知&#xff0c;目前的机型…

如何获取签章定位信息

在合同系统中&#xff0c;经常需要在合同文档的特定位置放置签名/印章图片。在合同拟稿过程中&#xff0c;放置签名/印章图片只是为了获取一个精确的定位信息&#xff0c;在合同定稿阶段才根据拟稿阶段得到的位置信息&#xff0c;去插入真正的签名/印章。那么如何在合同系统中高…

基于OpenMV的疲劳驾驶检测系统的设计

一、前言 借助平台将毕业设计记录下来&#xff0c;方便以后查看以及与各位大佬朋友们交流学习。如有问题可以私信哦。 本文主要从两个方面介绍毕业设计&#xff1a;硬件&#xff0c;软件&#xff08;算法&#xff09;。以及对最后的实验结果进行分析。感兴趣的朋友们可以评论区…

创新案例|专注在线 协作平台 设计产品中国首家PLG独角兽企业蓝湖如何实现98%的头部企业渗透率

蓝湖起步于2015年&#xff0c;是一款服务于产品经理、设计师、工程师的产品设计研发在线协作工具&#xff0c; 2021年10月&#xff0c;蓝湖宣布完成C轮融资&#xff0c;融资额高达10亿人民币&#xff0c;称为中国2B市场中首家采用PLG发展的独角兽企业&#xff0c;并实现了从100…