内存调优方面的细节可以参考官方网站上的调优指南部分。这里主要讨论Spark Stream-ing应用相关的一些调优参数。
一个Spark Streaming应用对集群内存大小的需求,在很大程度上依赖于所使用的转换操作类型。比如,如果使用一个窗口长度至少为10分钟的窗口操作,那么集群内存必须足够装载这10分钟的数据。或者,如果对大量Keys进行updateStateByKey操作的话,对内存的要求也会极高。相反的,如果只是简单地做一种map-filter-store操作的话,对内存的需求是比较小的。
通常我们使用StorageLevel.MEMORY_AND_DISK_SER_2存储等级来对接收到的数据进行持久化,因此,当内存不足以装载数据时,会将数据溢出到磁盘中。这会降低流应用的性能,因此在流应用中,应提供足够的内存。
内存调优的另一个方面是垃圾回收GC。一般流应用对延迟的要求很高,如果经常由于GC而导致大量停顿,这是不可接受的。
下面是一些可以对内存使用和GC开销进行调优的参数:
1.DStreams的持久化级别:输入数据和RDD默认情况下是以序列化的字节进行持久化的。这可以同时减少内存使用和GC开销。可以参考前面的数据序列化部分。我们可以使用Kryo序列化来进一步减少序列化后的数据大小和内存使用。除了使用更好的序列化器,还可以加入压缩机制,可以参考配置属性Spark.rdd.compress的设置,以CPU的时间开销来交互内存使用和GC开销。(www.xing528.com)
2.旧数据的清除:默认情况下,输入的数据和DStream转换过程中产生的持久化的RDD,都会自动被清除。Spark Streaming会根据使用的转换操作来决定何时清除这些数据。比如窗口长度为10分钟的窗口操作,SparkStreaminig会保留最后10分钟左右的数据,并积极丢弃旧的数据。可以通过配置参数streamingContext.remember为数据设置更长的保留时间。
3.CMS垃圾收集器:这里强烈建议使用并行的mark-and-sweep GC,以便持续地将GC相关的停顿保持中较低的状态。强烈建议在Driver和Executor侧都设置CMS GC,可以分别在spark-submit中使用--driver-java-options设置Driver,在属性配置中使用spark.executor.extraJavaOptions属性来设置Executors。
4.其他建议:为了进一步减少GC开销,可以尝试以下的方法:
1)持久化RDD时选择off-heap存储级别来使用Tachyon。
2)使用更多个数的,分配的heap sizes更小的executors。这可以在各个JVM heap中减少GC压力。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。