c语言计算磁盘大小,通过累积器获取RDD磁盘大小并计算分区数量

在工作过程中,很多spark在saveAsTextFile的过程中都会repartition,用于减少磁盘文件,节约内存空间;但是repartition的分区数,只能根据实际结果测试后重新进行调整或者根据自己的经验进行预估。但是当数据骤增或骤减的时候之前的经验值就不是那么可靠,而且当数据骤增时采用snapyy、gz等让当个文件过大导致task oom。

但是在实际测试、API说明中发现,SizeEstimator 只是计算了Java Heap中大小而不是磁盘落地大小。

于是使用:RDD总数/takeSample取样数*takeSample取样大小=RDD总大小;(sample 返回的数据占比不一定与参数相同)

这样有两个缺点:

有两个shuffle

结果浮动较大

所以,我们使用了累加器Accumulator,使用map获取每行的大小并进行累加,代码如下:

import org.apache.spark.SparkContext

import org.apache.spark.rdd.RDD

/**

* 通过累积器计算分区数量

*/

object ComputePartitionNum {

def compute(sc: SparkContext, rdd: RDD[String], blockSize:Double = 128, compressClass: String = "snappy"): Int = {

val accum = sc.longAccumulator("rddSizeToPartitionNum")

rdd.mapPartitions(iter => iter.map(x=>accum.add(x.getBytes.length))).collect()

val rddSize = accum.value

compressClass match {

case "snappy" => Math.ceil(rddSize / 1024 / 1024 / blockSize * 0.27).toInt

case "gz" => Math.ceil(rddSize / 1024 / 1024 / blockSize * 0.17).toInt

}

}

}

累加器必须通过Action产生Shuffle之后才会进行累加,试过take(1)、count、sample,都比collect效率地下

rdd.map(x => accum.add(x.getBytes.length)).collect()

压缩格式compress snappy、gz 的压缩比;本来要采用2012年google官方提供的的压缩比,但是与实际差距较大;于是自己测试了snappy、gz的压缩比,计算得出snappy:0.27(浮动在0.22-0.28) gz:0.17

有一点不明:

能否不使用collect或者比collect效率更高的action

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值