彻底解决Hive小文件问题
最近发现离线任务对一个增量Hive
表的查询越来越慢,这引起了我的注意,我在cmd
窗口手动执行count
操作查询发现,速度确实很慢,才不到五千万的数据,居然需要300s
,这显然是有问题的,我推测可能是有小文件。
我去hdfs
目录查看了一下该目录:
发现确实有很多小文件,有480个小文件,我觉得我找到了问题所在,那么合并一下小文件吧:
insert into test select * from table distribute by floor (rand()*5);
这里使用distribute by
进行了一个小文件的合并,通过rand() * 5
,保证了从map端输出的数据,最多到5个reducer
,将小文件数量控制了下来,现在只有3个文件了。
合并小文件后,再次做同样的查询,15s
就完成了。确实忽略了,增量数据会导致小文件,应该在当初做的时候就做定时的小文件合并,而不是等到现在才发现。
因为这个表每天是有增量数据进去的,增量数据会单独生成一个文件,因为增量数据本身不大,日积月累就形成了大量小文件。不仅对namenode
的内存造成压力,对map端的小文件合并也有很大压力。
小文件产生的原因
-
动态分区插入数据的时候,会产生大量的小文件;
-
数据源本身就包含有大量的小文件;
-
做增量导入,比如Sqoop数据导入,一些增量insert等;
-
分桶表,分桶表通常也会遇到小文件,本质上还是增量导入的问题;
-
可以修改的表,这种Hive表是可以进行修改的,通过配置
stored as orc TBLPROPERTIES ("transactional"="true")
,这种表最坑,每天都会有一个快照,到后面10G大小的数据,表文件体积可以达到600G,时间越长越大;
小文件的问题有很多,实际中各种原因,由于自己的不小心,前期没有做好预防都会产生大量小文件,让线上的离线任务神不知鬼不觉,越跑越慢。
小文件的危害
- 给namenode内存中fsImage的合并造成压力,如果namenode内存使用完了,这个集群将不能再存储文件了;
- 虽然map阶段都设置了小文件合并,
org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
,太多小文件导致合并时间较长,查询缓慢;
小文件的解决方案
彻底解决小文件,分为了两个方向,一个是小文件的预防,一个是大量小文件问题已经出现了,我们该怎么解决。
1. 小文件的预防
网上有些解决方案,是调节参数,这些参数在我使用的Hive2
是默认都开启了的:
//每个Map最大输入大小(这个值决定了合并后文件的数量)
set mapred.max.split.size=256000000;
//一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
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;
//设置map端输出进行合并,默认为true
set hive.merge.mapfiles = true
//设置reduce端输出进行合并,默认为false
set hive.merge.mapredfiles = true
//设置合并文件的大小
set hive.merge.size.per.task = 256*1000*1000
//当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge。
set hive.merge.smallfiles.avgsize=16000000
有些公司用的版本不同,低版本可能有些配置不一样,最好检查一下上面这些配置是否设置,然后根据自己的实际集群情况进行设置。
小文件的预防,主要还是要根据小文件的产生原因,来进行预防。
- 动态分区插入的时候,保证有静态分区,不要误判导致产生大量分区,大量分区加起来,自然就有大量小文件;
- 如果源表是有大量小文件的,在导入数据到目标表的时候,如果只是
insert into dis select * from origin
的话,目标表通常也有很多小文件。如果有分区,比如dt, hour
,可以使用distribute by dt, hour
,保证每个小时的数据在一个reduce里面; - 类似
sqoop
增量导入,还有hive
一些表的查询增量导入,这些肯定是有小文件的,需要进行一周甚至一天定时任务的小文件合并。
2. 小文件的解决
上面是平时开发数据任务时候,小文件的预防,但如果由于我们的大意,小文件问题已经产生了,就需要解决了。通常就是insert overwrite
了。
insert overwrite table test [partition(hour=...)] select * from test distribute by floor (rand()*5);
注:这个语句把test
表的数据查询出来,overwrite
覆盖test
表,不用担心如果overwrite
失败,数据没了,这里面是有事物性保证的,可以观察一下执行的时候,在test表hdfs
文件目录下面有个临时文件夹。如果是分区表,加上partition
,表示对该分区进行overwrite
。
如果是orc格式存储的表,还可以使用alter table test [partition(...)] concatenate
进行小文件的合并,不过这种方法仅仅适用于orc格式存储的表。
猜你喜欢
Hadoop3数据容错技术(纠删码)
Hadoop 数据迁移用法详解
Flink实时计算topN热榜
数仓建模分层理论
一文搞懂Hive的数据存储与压缩
大数据组件重点学习这几个
原文地址:https://www.cnblogs.com/data-magnifier/p/15314201.html
- Pig、Hive、MapReduce 解决分组 Top K 问题
- Pig、Hive 自定义输入输出分隔符以及Map、Array嵌套分隔符冲突问题
- 新手教程:局域网DNS劫持实战
- 自定义 java 日期、时间 处理函数集
- MapReduce 中的两表 join 几种方案简介
- MapReduce中的自定义多目录/文件名输出HDFS
- 通过hiveserver远程服务构建hive web查询分析工具
- Hive 中内部表与外部表的区别与创建方法
- 常用统计分析 SQL 在 AWK 中的实现
- java 中 16 进制 HEX 转换成字节码形式的 UTF-8
- Hadoop 多表 join:map side join 范例
- 实战 windows7 下 eclipse 远程调试 linux hadoop
- Hive 在多维统计分析中的应用 & 技巧总结
- shell 学习笔记(18)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 编写一个IDEA插件之:开发环境准备那些坑
- 编写一个IDEA插件之:使用PSI分析Java代码
- 编写一个IDEA插件之:自动生成Java代码
- 编写一个IDEA插件之:事件监听
- 重新加载故障节点上的 Ceph 卷
- 一个Spring Bean从诞生到逝去的九次人生转折!
- 原创 | 详解git rebase,让你走上git大神之路
- 启用chrome浏览器内置的二维码生成插件
- ZeroLogon漏洞(CVE-2020-1472)防御性指南
- 原创 | 随机数大家都会用,但是你知道生成随机数的算法吗?
- 原创 | codeforces 1425E,一万种情况的简单题
- 原创 | codeforces 1417C,逆向思考的数据结构题
- 原创 | 操作失误不要慌,这个命令给你的Git一次反悔的机会
- 原创 | 想做推荐算法?先把FM模型搞懂再说
- 活见鬼,明明删除了数据,空间却没减少!