SparkStreaming如何解决小文件问题

使用sparkstreaming时,如果实时计算结果要写入到HDFS,那么不可避免的会遇到一个问题,那就是在默认情况下会产生非常多的小文件,这是由sparkstreaming的微批处理模式和DStream(RDD)的分布式(partition)特性导致的,sparkstreaming为每个partition启动一个独立的线程来处理数据,一旦文件输出到HDFS,那么这个文件流就关闭了,再来一个batch的parttition任务,就再使用一个新的文件流,那么假设,一个batch为10s,每个输出的DStream有32个partition,那么一个小时产生的文件数将会达到(3600/10)*32=11520个之多。众多小文件带来的结果是有大量的文件元信息,比如文件的location、文件大小、block number等需要NameNode来维护,NameNode会因此鸭梨山大。不管是什么格式的文件,parquet、text,、JSON或者 Avro,都会遇到这种小文件问题,这里讨论几种处理Sparkstreaming小文件的典型方法。

增加batch大小

这种方法很容易理解,batch越大,从外部接收的event就越多,内存积累的数据也就越多,那么输出的文件数也就回变少,比如上边的时间从10s增加为100s,那么一个小时的文件数量就会减少到1152个。但别高兴太早,实时业务能等那么久吗,本来人家10s看到结果更新一次,现在要等快两分钟,是人都会骂娘。所以这种方法适用的场景是消息实时到达,但不想挤压在一起处理,因为挤压在一起处理的话,批处理任务在干等,这时就可以采用这种方法(是不是很像spark内部的pipeline模式,但是要注意区别哦)。

Coalesce大法好?

文章开头讲了,小文件的基数是:batch_number*partition_number,而第一种方法是减少batch_number,那么这种方法就是减少partition_number了,这个api不细说,就是减少初始的分区个数。看过spark源码的童鞋都知道,对于窄依赖,一个子RDD的partition规则继承父RDD,对于宽依赖(就是那些个叉叉叉ByKey操作),如果没有特殊指定分区个数,也继承自父rdd。那么初始的SourceDstream是几个partiion,最终的输出就是几个partition。所以Coalesce大法的好处就是,可以在最终要输出的时候,来减少一把partition个数。但是这个方法的缺点也很明显,本来是32个线程在写256M数据,现在可能变成了4个线程在写256M数据,而没有写完成这256M数据,这个batch是不算做结束的。那么一个batch的处理时延必定增长,batch挤压会逐渐增大。这种方法也要慎用,切鸡切鸡啊!

SparkStreaming外部来处理

我们既然把数据输出到hdfs,那么说明肯定是要用hive或者sparksql这样的“sql on hadoop”系统类进一步进行数据分析,而这些表一般都是按照半小时或者一小时、一天,这样来分区的(注意不要和sparkStreaming的分区混淆,这里的分区,是用来做分区裁剪优化的),那么我们可以考虑在SparkStreaming外再启动定时的批处理任务来合并SparkStreaming产生的小文件。这种方法不是很直接,但是却比较有用,“性价比”较高,唯一要注意的是,批处理的合并任务在时间切割上要把握好,搞不好就可能回去合并一个还在写入的SparkStreaming小文件。

自己调用foreach去append

SparkStreaming提供的foreach这个outout类api,可以让我们自定义输出计算结果的方法。那么我们其实也可以利用这个特性,那就是每个batch在要写文件时,并不是去生成一个新的文件流,而是把之前的文件打开。考虑这种方法的可行性,首先,HDFS上的文件不支持修改,但是很多都支持追加,那么每个batch的每个partition就对应一个输出文件,每次都去追加这个partition对应的输出文件,这样也可以实现减少文件数量的目的。这种方法要注意的就是不能无限制的追加,当判断一个文件已经达到某一个阈值时,就要产生一个新的文件进行追加了。

上边这些方法我都有尝试过,各有利弊,大家在使用时多加注意就可以了。

更多spark相关交流、分享、讨论,请加入知识星球,BAT一线工程师为你答疑解惑,免费修改简历,并进行面试指导。

原文发布于微信公众号 - Spark学习技巧(bigdatatip)

原文发表时间:2018-06-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Hadoop实操

如何在CDH中安装和使用StreamSets

StreamSets由Informatica前首席产品官Girish Pancha和Cloudera前开发团队负责人Arvind Prabhakar于2014年...

5.3K10
来自专栏大数据挖掘DT机器学习

基于Hadoop 的分布式网络爬虫技术

一、网络爬虫原理 Web网络爬虫系统的功能是下载网页数据,为搜索引擎系统提供数据来源。很多大型的网络搜索引擎系统都被称为基于 Web数据采集的搜索引擎系统,比如...

4768
来自专栏Spark学习技巧

Flink与Spark Streaming在与kafka结合的区别!

本文主要是想聊聊flink与kafka结合。当然,单纯的介绍flink与kafka的结合呢,比较单调,也没有可对比性,所以的准备顺便帮大家简单回顾一下Spark...

2052
来自专栏机器人网

终于全了!ABB机器人学习资料

? 1、安全 自动模式中,任何人不得进入机器人工作区域 长时间待机时,夹具上不宜放置任何工件。 机器人动作中发生紧急情况或工作不正常时,均可使用E-stop键...

3583
来自专栏程序员宝库

后端说:只是你不懂怎么用 headers!

事情是这样的,上一个项目我们的后端提供的接口,一次性返回了所有数据给我,分页功能是前端自己完成的。

1247
来自专栏Coding+

如何多端同步 Hexo 框架博客

这个必要性其实不用多说,用着用着你就自己能体会到,比如头天晚上在家里发布了一篇技术文章,第二天在公司 Coding 的过程中突然想到之前发的文某个地方有 Bug...

911
来自专栏章鱼的慢慢技术路

Direct3D驱动类型(DRIVER_TYPE)介绍

之前部门老大叫我查找有关Direct3D使用软件渲染的方法,于是我找到了D3D驱动的类型,并整理如下

1312
来自专栏androidBlog

adb 截屏和录屏命令

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/details/...

4051
来自专栏知识分享

关于IAR开发STM32配置

因为自己要学Msp430还有ZigBee发现IAR真的挺好用,,,所以以后想着就用IAR写单片机程序,, 这次配置我不会把程序的配置弄得有条理,分开文件夹存放,...

3254
来自专栏信安之路

用powershell下载文件的姿势你研究过吗?

PowerShell 的最大优势在于以 .NET 框架为基础。 .NET 框架在脚本领域几乎是无所不能,这是一个优点,也有可能成为一个方便黑客攻击的一个强大的便...

2570

扫码关注云+社区