SparkStreaming将结果输出到单个文件以及小文件的合并

SparkStreaming将结果输出到单个文件以及小文件的合并

sparkStreaming消费kafka数据…

每个duration批次时间数据量不一定多少,
若数据量太少,
首先每个批次处理数据后会有多个分区的小文件,
解决办法1. 是在结果落地前重分区,每个批次只生成一个文件,

那么要是这一个文件数据量也很小,落地到hive还是会影响查询效率

那么解决办法2. 就用在hive定时执行一个insert overwrite table a select * from a;语句,这个时候会覆盖表的数据达到合并小文件的目的

关于insert overwrite table a select * from a;应该会覆盖原先的文件,不过我还是测试了一下。 在我摘的两篇文章最下面贴截图。

以下摘自CSDN

地址是:https://blog.csdn.net/xianpanjia4616/article/details/82888608

sparksql写入hive后小文件太多,影响查询性能的问题
首先我们要知道hive里面文件的数量=executor-coresnum-executorsjob数,所以如果我们batchDuration的设置的比较小的话,每天在一个分区里面就会生成很多的小文件,我们在hive里面查询的时候就会非常的影响性能,下面介绍两种方法优化小文件:

(1),第一种,可以在创建的DataFrame的时候,cache一下,然后对DataFrame进行重新分区,可以把分区设置为1,可以用reparation,当然也可以用coalesce,这两个的区别,可以看我的另外一篇博客,这个时候就会一个job产生一个文件.但是这么做就降低了写入的性能,所以数据量不是特别大的时候,还是可以用的,但是如果数据量很大,就需谨慎使用,

(2),第二种方法是利用sql定时执行一下,insert overwrite table a select * from a;这个时候会覆盖表的数据达到合并小文件的目的,具体的sql下面会有.

下面看一下具体的代码吧:

 val df = spark.createDataFrame(rowRDD, schema).cache()
          df.coalesce(1).createOrReplaceTempView("tempTable")
          val sq = "insert into combine_data partition(day_time='" + day_time + "') select * from tempTable"
          sql(sq)
          println("插入hive成功了")
          df.unpersist(true)
insert overwrite table combine_data partition (day_time='2018-08-01') select data,enter_time from combine_data where day_time = '2018-08-01'; 

以下是摘自简书

地址:https://www.jianshu.com/p/7e2b20ccc78b

原始的结果
今天终于完成了SparkStreaming的阶段性工作,要将结果数据放入到hdfs上保存,使用的是RDD自己原有的函数saveAsTextFiles(“Path”)
在这里插入图片描述
使用函数
结果如下
在这里插入图片描述
结果
可以看出,有瑕疵。我是想将我的数据保存在一个文件中,所以有瑕疵。文件太多,文件夹太多。这样的结果对于后面对数据的再次使用,坏处我就不必多说了吧。

可以看出,多文件夹的原因是因为我是使用的SparkStreaming,所以是每个时间段(Duration)执行一次写入的操作,所以会出现多文件夹,并且名字以时间命名。再看文件夹下的多个文件,这是由我的RDD的分区决定的,而RDD的分区是由我指定数量的线程来决定的,因为我是在本地跑的val sparkConf =new SparkConf().setMaster(Constant.SPARK_MASTER_LOCAL),我这里指定的是4,所以是4个文件。对RDD感兴趣的可以去看一下RDD的分区,讲的很好理解,这里就不再赘述。对spark中RDD通俗易懂的介绍

解决方法
思路描述:首先解决多文件的问题,因为文件数量是由分区决定的,那我们就将他重分区,分区数量为1,然后再向hdfs中写入临时目录,写入后我们再将这个文件追加到最终的文件中,然后再把这个临时文件删除。闲话少说,上干货。
在这里插入图片描述
解决方法
copyMerge(src.getFileSystem(conf), src, dst)方法如下。
在这里插入图片描述
copyMerge(src.getFileSystem(conf), src, dst)

作者:飞叔Brother
链接:https://www.jianshu.com/p/7e2b20ccc78b
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

测试overwrite覆盖原文件

insert overwrite table a select * from a;

创建表 指定数据目录

create table testover(
a int
)
location '/out/18';

目下有两个文件
在这里插入图片描述
查询数据在这里插入图片描述

覆盖以合并小文件

insert overwrite table testover
select * from testover;

在这里插入图片描述
查看目录下文件

果然由两个变为了一个

在这里插入图片描述
查询一下 没有错
在这里插入图片描述

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值