Spark的kryo性能测试以及RDD持久化级别

本文详细测试了Spark中不同RDD持久化级别及kryo序列化的效果。通过实验发现,使用Kryo序列化能显著降低内存占用和提高效率。特别是在注册kryo并开启RDD压缩后,内存占用降至45M,达到最优效果。然而,是否启用RDD压缩应视具体场景,如磁盘IO和GC压力而定,有时其他优化策略可能更有效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MEMORY_ONLY

代码如下

package com.yxw.Test

import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.{FileSystem, Path}
import org.apache.spark.{SparkConf, SparkContext}

object KryoTest000 {
  def main(args: Array[String]): Unit = {

    //定义输入输出路径
    val inputpath = new Path(args(0)) //file:///E:/BaiduNetdiskDownload/cleaned.log
    val outputpath = new Path(args(1)) //file:///E:/BaiduNetdiskDownload/outputpath

    //连接hdfs
    val fsConf = new Configuration()
    val fs = FileSystem.get(fsConf)

    //路径存在就删除
    if (fs.exists(outputpath)){
      fs.delete(outputpath,true)
      val path = args(1).toString
      println(s"已经删除存在的路径 $path")
    }

    //创建sparkcontext
    val conf = new SparkConf().setAppName("KryoTest000APP").setMaster("local[4]")
    val sc = new SparkContext(conf)
    //得到文件 创建RDD
    val files = sc.textFile(args(0))

   // files.foreach(println)
    //调用utils 持久化
    val res = KryoUtils.logCache(files)
    //res.collect()


//    //序列化方式存到内存
    KryoUtils.saveLog(res,args(1))
//
    Thread.sleep(50000) //睡50s 以便观察webUI


  }
}

KryoUtils.scala

package com.yxw.Test

import org.apache.spark.rdd.RDD

case class INFO(cdn: String, region: String, level: String, date: String, ip: String, domain: String, url: String, traffic: String)

object KryoUtils {
  //baidu	CN	E	2018050103	222.73.34.128	rw.uestc.edu.cn	http://rw.uestc.edu.cn/user_upload/15316339776271051.html	72071
  def logCache(logs: RDD[String]): RDD[INFO] = {
    logs.filter(_.split("\t").length == 8).map(log => {
      val info = log.split("\t")
      INFO(info(0), info(1), info(2), info(3), info(4), info(5), info(6), info(7))

    }).cache()


  }

  def saveLog(logsCache: RDD[INFO], outputpath: String) = {
    logsCache.map(logCache => {
      logCache.cdn + "\t" + logCache.region + "\t" + logCache.level + "\t" +
        logCache.date + "\t" + logCache.ip + "\t" + logCache.domain + "\t" + logCache.url + "\t" + logCache.traffic


    }).repartition(1).saveAsTextFile(outputpath)
  }
}

运行的结果如图:
在这里插入图片描述
由于有个shuffle操作 共耗时10s
cache的大小为:
在这里插入图片描述
900多M,这简直恐怖

MEMORY_ONLY_SER 未使用kryo序列化

修改代码:
在这里插入图片描述
结果如下:
在这里插入图片描述
在这里插入图片描述
序列化后占用内存已经显著减小,耗时也减小为7s

MEMORY_ONLY_SER 使用kryo序列化未注册

代码修改如下:
在这里插入图片描述
结果如下:
在这里插入图片描述
在这里插入图片描述
耗时差不多,都是7s,但是内存占用稍微减小

MEMORY_ONLY_SER 使用kryo序列化并注册

修改代码如下:
在这里插入图片描述
结果如图所示:
在这里插入图片描述
在这里插入图片描述
可以看到速度,内存占用都是以上几组测试用最优的

注册kryo序列化并开启RDD压缩

这个测试是网上看来的
注意:RDD压缩只能存在于序列化的情况下
修改代码如图:
在这里插入图片描述
运行结果如图:
在这里插入图片描述
在这里插入图片描述
持久化的内存占用大小仅为45M左右!!!

spark.rdd.compress

这个参数决定了RDD Cache的过程中,RDD数据在序列化之后是否进一步进行压缩再储存到内存或磁盘上。当然是为了进一步减小Cache数据的尺寸,对于Cache在磁盘上而言,绝对大小大概没有太大关系,主要是考虑Disk的IO带宽。而对于Cache在内存中,那主要就是考虑尺寸的影响,是否能够Cache更多的数据,是否能减小Cache数据对GC造成的压力等。

这两者,前者通常不会是主要问题,尤其是在RDD Cache本身的目的就是追求速度,减少重算步骤,用IO换CPU的情况下。而后者,GC问题当然是需要考量的,数据量小,占用空间少,GC的问题大概会减轻,但是是否真的需要走到RDD Cache压缩这一步,或许用其它方式来解决可能更加有效。

所以这个值默认是关闭的,但是如果在磁盘IO的确成为问题或者GC问题真的没有其它更好的解决办法的时候,可以考虑启用RDD压缩。

以上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值