一.内存调优
Spark Streaming应用程序所需的集群内存大小在很大程度上取决于所使用的转换类型。例如,如果要对最后10分钟的数据使用窗口操作,则集群应具有足够的内存以将10分钟的数据保存在内存中。或者,如果想使用updateStateByKey操作大量的kv类型数据,则所需的存储空间会很大。相反,如果想执行一个简单的map-filter-store操作,则所需的内存将很少。
通常,由于通过接收器接收的数据存储在StorageLevel.MEMORY_AND_DISK_SER_2中,因此无法容纳在内存中的数据将溢出到磁盘上。这可能会降低流应用程序的性能,因此建议提供流应用程序所需的足够内存。最好尝试以小规模数据查看内存使用情况并据此进行估计。
内存调整的另一个方面是垃圾回收。对于需要低延迟的流应用程序,不希望由于JVM垃圾收集而导致较大的停顿。
有一些参数可以帮助调整内存使用和GC开销:
- DStream的持久性级别:默认情况下,输入数据和RDD被持久化为序列化字节。与反序列化的持久性相比,这减少了内存使用和GC开销。启用Kryo序列化可进一步减少序列化的大小和内存使用量。通过压缩可以进一步减少内存使用量,但会占用CPU时间。
- 清除旧数据:默认情况下,将自动清除DStream转换生成的所有输入数据和持久性RDD。Spark Streaming根据使用的转换来决定何时清除数据。例如,如果使用10分钟的窗口操作,那么Spark Streaming将保留最后10分钟的数据,并主动丢弃较旧的数据。通过设置streamingContext.remember可以将数据保留更长的时间。
- CMS垃圾收集器:强烈建议使用并发标记清除GC,以使与GC相关的暂停时间始终保持较低。尽管已知并发GC会降低系统的整体处理吞吐量