Spark——优化篇

Spark2.4.4
官网 https://spark.apache.org/docs/latest/tuning.html

调整Spark

由于大多数Spark计算基于内存的性质,Spark程序可能会因为群集中任何资源而达到瓶颈,如CPU,网络带宽或内存。
大多数情况下,如果数据在内存中大小合适,则瓶颈就是网络带宽,但有时,你还需要进行一些调整,例如以序列化形式存储RDD,以减少内存使用。
本指南将涵盖两个主要主题:数据序列化,这对于良好的网络性能至关重要,并且还可以减少内存使用。另一个主题,内存调整。
我们还概述了几个较小的主题。

数据 序列化

序列化在任何分布式的应用中都起着重要的作用。将对象序列化为较慢的格式,或者需要大量的字节,会极大拖慢计算的速度。通常,这些就是你需要优先调整的方向,以此来优化spark。

Spark试图在便利和性能之间找到一个平衡点。所谓便利,就是允许你可以在你的操作中使用各种Java类型。它提供了两种序列化的库:

  • Java 序列化:默认情况下,Spark使用Java的ObjectOutputStream框架来序列化对象,并可以同你所定义的声明了 java.io.Serializable的任意类一起使用。你还可以通过扩展java.io.Externalizable来更细致地控制序列化的性能。Java的序列化很灵活,但通常很慢,并且许多类序列化后的对象依然很大。
  • Kryo serialization:Spark还可以使用Kryo(version 4)来更快地序列化对象。与Java序列化相比,Kryo显得更快,更紧凑(通常多达10倍)。但不支持所有的Serializable 类型,并且需要你事先register注册将要在程序中使用的这些class类,以达到最好的性能。

你可以通过用 SparkConf 初始化作业 job,切换成 Kryo,并调用conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
该项配置,使得序列化不仅被用于worker节点之间的数据混洗,也会在RDDs序列化到磁盘时起作用。Kryo 不作为默认方式的唯一原因是需要你自定义去注册类,但我们推荐在任何网络密集型的应用中尝试 Kryo。自 Spark 2.0.0版本起,在将数据为简单类型、简单类型的数组或字符串类型的RDD进行混洗时,我们在内部使用Kryo序列化器。
Spark自动为Twitter chill库的AllScalaRegistrar中的许多常用Scala核心类导入Kryo序列化器。
为了向 Kyro 注册你自定义的类,可以使用 registerKryoClasses 方法:

val conf = new SparkConf().setMaster(...).setAppName(...)
conf.registerKryoClasses(Array(classOf[MyClass1], classOf[MyClass2]))
val sc = new SparkContext(conf)

Kryo文档介绍了更高级的注册选项,例如添加自定义序列化代码。

如果对象很大,则可能还需要增加spark.kryoserializer.buffer配置.该值必须足够大以容纳将要序列化的最大的对象。
最后,如果你不注册自定义的类,Kyro 仍然可以使用,但是就要将完整的类名和对象一起存储,这样做很浪费。

内存调优

---未完待续---

你可能感兴趣的:(Spark——优化篇)