目前平台使用Kafka + Flume的方式进行实时数据接入,Kafka中的数据由业务方负责写入,这些数据一部分由Spark Streaming进行流式计算;另一部分数据则经由Flume存储至HDFS,用于数据挖掘或机器学习。HDFS存储数据时目录的最小逻辑单位为“小时”,为了保证数据计算过程中的数据完整性(计算某个小时目录中的数据时,该目录的数据全部写入完毕,且不再变化),我们在Flume中加入了如下策略:
 
每五分钟关闭一次正在写入的文件,即新创建文件进行数据写入。
 
这样的方式可以保证,当前小时的第五分钟之后就可以开始计算上一小时目录中的数据,一定程度上提高了离线数据处理的实时性。
 
随着业务的增加,开始有业务方反馈:“HDFS中实际被分析的数据量很小,但是Spark App的Task数目却相当多,不太正常”,我们跟进之后,发现问题的根源在于以下三个方面:
 
(1)Kafka的实时数据写入量比较小;
(2)Flume部署多个实例,同时消费Kafka中的数据并写入HDFS;
(3)Flume每五分钟会重新创建文件写入数据(如上所述);
 
这样的场景直接导致HDFS中存储着数目众多但单个文件数据量很小的情况,间接影响着Spark App Task的数目。
 
我们以Spark WordCount为例进行说明,Spark版本为1.5.1。
 
假设HDFS目录“/user/yurun/spark/textfile”中存在以下文件:
 
 
这个目录下仅三个文件包含少量数据:part-00005、part-00010、part-00015,数据大小均为6 Byte,其余文件数据大小均为0 Byte,符合小文件的场景。
 
注意:_SUCCESS相当于一个“隐藏”文件,实际处理时通常会被忽略。
 
常规实现
 
 
我们使用SparkContext textFile完成数据输入,应用运行完成之后,通过Spark History Server的页面可以看到:应用执行过程中,会产生一个Job,包含两个Stage,每个Stage包含16个Task,也就是说,Task的总数目为32,如下图所示:
 
 
之所以每个Stage包含16个Task,是因为目录中存有16个文本文件(_SUCCESS不参与计算)。
 
优化实现
 
 
在这个优化的版本中,我们使用SparkContext newAPIHadoopFile完成数据输入,需要着重说明一下“org.apache.hadoop.mapreduce.lib.input.CombineTextInputFormat”,这个类可以将多个小文件合并生成一个Split,而一个Split会被一个Task处理,从而减少Task的数目。这个应用的执行过程中,会产生两个Job,其中Job0包含一个Stage,一个Task;Job1包含两个Stage,每个Stage包含一个Task,也就是说,Task的总数目为3,如下图所示:
 
 
 
可以看出,通过使用“org.apache.hadoop.mapreduce.lib.input.CombineTextInputFormat”可以很大程度上缓解小文件导致Spark App Task数目过多的问题。 

Spark使用CombineTextInputFormat缓解小文件过多导致Task数目过多的问题的更多相关文章

  1. Spark SQL 小文件问题处理

    在生产中,无论是通过SQL语句或者Scala/Java等代码的方式使用Spark SQL处理数据,在Spark SQL写数据时,往往会遇到生成的小文件过多的问题,而管理这些大量的小文件,是一件非常头疼 ...

  2. hadoop 小文件 挂载 小文件对NameNode的内存消耗 HDFS小文件解决方案 客户端 自身机制 HDFS把块默认复制3次至3个不同节点。

    hadoop不支持传统文件系统的挂载,使得流式数据装进hadoop变得复杂. hadoo中,文件只是目录项存在:在文件关闭前,其长度一直显示为0:如果在一段时间内将数据写到文件却没有将其关闭,则若网络 ...

  3. 干货!Apache Hudi如何智能处理小文件问题

    1. 引入 Apache Hudi是一个流行的开源的数据湖框架,Hudi提供的一个非常重要的特性是自动管理文件大小,而不用用户干预.大量的小文件将会导致很差的查询分析性能,因为查询引擎执行查询时需要进 ...

  4. mapreduce 关于小文件导致任务缓慢的问题

    小文件导致任务执行缓慢的原因: 1.很容易想到的是map task 任务启动太多,而每个文件的实际输入量很小,所以导致了任务缓慢 这个可以通过 CombineTextInputFormat,解决,主要 ...

  5. Spark优化之小文件是否需要合并?

    我们知道,大部分Spark计算都是在内存中完成的,所以Spark的瓶颈一般来自于集群(standalone, yarn, mesos, k8s)的资源紧张,CPU,网络带宽,内存.Spark的性能,想 ...

  6. 数仓面试高频考点--解决hive小文件过多问题

    本文首发于公众号:五分钟学大数据 小文件产生原因 hive 中的小文件肯定是向 hive 表中导入数据时产生,所以先看下向 hive 中导入数据的几种方式 直接向表中插入数据 insert into ...

  7. XCode编译文件过多导致内存吃紧解决方法

    XCode编译文件过多导致内存吃紧解决方法 /Users/~~/Library/Developer/Xcode/DerivedData 1) 然后 找到编译文件 删除 就好了哦 快去试试看吧

  8. Spark:spark df插入hive表后小文件数量多,如何合并?

    在做spark开发过程中,时不时的就有可能遇到租户的hive库目录下的文件个数超出了最大限制问题. 一般情况下通过hive的参数设置: val conf = new SparkConf().setAp ...

  9. spark sql/hive小文件问题

    针对hive on mapreduce 1:我们可以通过一些配置项来使Hive在执行结束后对结果文件进行合并: 参数详细内容可参考官网:https://cwiki.apache.org/conflue ...

随机推荐

  1. final----这篇文章是我收获很大

    final 用于声明属性.方法和类,分别表示属性不可变,方法不可重写,类不可继承. [转]Java final 修饰符知识点总结 final从字面上理解含义为“最后的,最终的”.在Java中也同样表示 ...

  2. C#DbHelperOra,Oracle数据库帮助类 (转载)

    主要功能如下数据访问抽象基础类 主要是访问Oracle数据库主要实现如下功能 .数据访问基础类(基于Oracle),主要是用来访问Oracle数据库的. .得到最大值:是否存在:是否存在(基于Orac ...

  3. GitHub中"watch" "star" "fork"三个按钮干什么用的?

    总结下一般使用:1.想拷贝别人项目到自己帐号下就fork一下.2.持续关注别人项目更新就star一下3.watch是设置接收邮件提醒的.具体提醒有Issues and their commentsPu ...

  4. jQuery easyUI框架中经常出现的问题

    相信开发者对于我们jquery来说都不会陌生吧,jquery为我们的开发提供了很多各式各样的库,满足各种开发的需求,其中我们知道的有轻量级的,但是也有一些基于富客服端的一些重量级库,顾名思义,当我们在 ...

  5. 对有状态bean和无状态bean的理解(转)

    现实中,很多朋友对两种session bean存在误解,认为有状态是实例一直存在,保存每次调用后的状态,并对下一次调用起作用,而认为无状态是每次调用实例化一次,不保留用户信息.仔细分析并用实践检验后, ...

  6. PHP Ajax简单实例

    最近学习Jquery Ajax部分,通过简单例子,比较了下post,get方法的不同 HTML部分 <html> <head> <title>jQuery Ajax ...

  7. Apache提示You don't have permission to access / on this server问题解决

    测试时遇到将一本地目录设置为一apache的虚拟主机,在httpd-vhosts.conf文件中进行简单设置,然后在hosts文件中将访问地址指向本地,启动apache,进行访问,却出现了You do ...

  8. 获取数据后导出Excel

    List<PortResourceInfo> list = getList()//获取数据源 //导出excle Response.Clear(); Response.ContentTyp ...

  9. TCP与UDP网络编程总结(一)

    (1):TCP网络编程 我们注意到服务端与客户端通信时是通过客户端的套接字相互通信的,那么服务端的套接字主要是干什么用的呢? TCP服务端设置监听套接字时 int listen(int sock,in ...

  10. 关于反射Assembly.Load("程序集").CreateInstance("命名空间.类")

    关于反射Assembly.Load("程序集").CreateInstance("命名空间.类") 而不管在哪一层写这段代码其中的("程序集" ...