总的来说,需要考虑以下两点:

1. 有效地运用集群资源去减少每个批次处理的时间

2. 正确的设置batch size,以使得处理速度能跟上接收速度

一.  为了减少处理时间,主要有以下几个优化点:

1. 接收数据的并行度。

每个InputDStream只创建一个Receiver用于接收数据,如果接收数据是系统的瓶颈,可以创建多个InputDStream。配置不同的InputDStream读取数据源的不同分区。比如原先用一个InputDStream读取Kafka的两个topic的数据,可以拆分成两个InputDStream读取不同的Topic。处理时,把两个InputDStream收到的数据合并成一个。

int numStreams = 5;
List<JavaPairDStream<String, String>> kafkaStreams = new ArrayList<>(numStreams);
for (int i = 0; i < numStreams; i++) {
kafkaStreams.add(KafkaUtils.createStream(...));
}
JavaPairDStream<String, String> unifiedStream = streamingContext.union(kafkaStreams.get(0), kafkaStreams.subList(1, kafkaStreams.size()));
unifiedStream.print();

2.  阻塞间隔

有一个配置参数:spark.streaming.blockInterval,它的意思是每间隔多少秒后,Spark才把接收到的数据组成数据块存到Spark中。官网推荐的最小值是50ms,默认值200ms。假设实例化InputDStream时设置的Duration(batch interval)为1秒(1000ms),那么任务执行时,总共有 1000 / 200 = 5 个block,每个block将对应一个task。如果task的数量少于每台机器配置的core的数量,则说明资源没有被很好的利用。应减少 spark.streaming.blockInterval 或增加batch interval。

注意:官网并没有说要使得task的数量和core的数量一致。能想到两个的原因:(1)receiver也会占用core (2)driver也会占用core

3. 相对于1中所说的增加receiver,一个可供选择的方案是通过调用 inputStream.repartition(<number of partitions>) 对inputDStream的数据进行repartition。这将使接收到的数据分布到指定数量的其它机器上,以供进一步处理。

4. 处理数据的并行度

对于reduceByKey, reduceByKeyAndWindow,Join 等shuffle操作,默认的并行度由 spark.default.parallelism 控制。可以在shuffle操作中设置partition的数量来覆盖默认值。

5. 数据序列化

在Spark Streaming中,有两类数据会被序列化:

5.1 输入数据。默认情况下,输入数据会以StorageLevel.MEMORY_AND_DISK_SER_2 的方式存储在 executor 的内存中。Receiver会反序列化接收到数据,然后再把它序列化成Spark的序列化格式。这显然会有花销。

5.2 持久化Streaming操作产生的RDD。某些windows操作会持久化需要进行多次处理的数据到内存中,默认的存储方式是StorageLevel.MEMORY_ONLY_SER

以上两种情况,使用Kyro序列化机制来减少CPU和内存的花销。

6. 启动Task的开销

如果每秒启动的task较多(比如:50个或更高),那么发送task去workers的开销会较大。通过以下方式减少这个开销:以Standalone模式或 coarse-grained Mesos 模式运行Spark程序。详见: Running on Mesos guide

7. 设置正确的Batch Interval

每个时间间隔提交的job应该能处理完这个时间间隔内收到的数据。可以通过Web UI 去查看批处理的时间是否小于interval

二. 内存调优

Spark Streaming应用程序需要的内存依赖于程序中用到的transformation。比如,你使用了window操作,想要处理最后10分钟的数据,这就要求内存能保存这10分钟的所有数据。虽然默认情况下是,内存存不下后会存到磁盘,但是这样的会比较慢。建议尽量加大内存。

垃圾回收也是需要考虑的一方面。可以考虑以下几点来减少GC的开销:

1. 接收的数据和RDD会默认序列化并持久化。开启Kyro序列化机制可减少内存的使用。 设置spark.rdd.compress为TRUE,可减少CPU时间

2. 清除旧的数据。Spark Streaming默认会做这件事。

3. 使用CMS 垃圾收集器。driver端使用 --driver-java-options ( spark-submit的时候)。executor端, 使用spark.executor.extraJavaOptions 这个配置

4. 尝试以下2点:1. 使用OFF_HEAP 存储级别  2. 增加executor,减少heap size

总的来说,需要记住以下几点:

1. 一个InputDSteam对应一个receiver, receiver运行在executor上,因此会占用一个core。Receivers以轮询的方式分配到executors中。

2. 每隔block interval的时间就会生成一个block,所以每个batch interval的时间会生成 batch interval / block interval 个block,每个block对应一个task。block会被BlockManager分发到不同的executor上

3. 在batchInterval内,在driver端生成一个RDD,在此期间内生成的blocks是这个RDD的partitions。每个partition是一个task。

4. 较大的blockInterval 意味着较大的data block。较大的 spark.locality.wait 将增加 block 在本地处理的机会。寻找这两个值的平衡点,以使较大的block在本地处理。

5. 可以使用 inputDstream.repartition(n) 来替代设置 batchInterval 和 blockInterval 来获取较好的并行度。但这会产生shuffle的花销。

6. 一次只能处理一个Job。所以当有多个 InputDStream 时,需要先Union两个 InputDStream。

7. Receiver暂时没有暂停的方法。因此当job的处理时间大于 batchInterval 时,receiver 的内存使用将会持续增加,最终导致 BlockNotFoundException 。使用spark.streaming.receiver.maxRate 可以限制 receiver的接收速度

Spark Streaming 官网上提到的几点调优的更多相关文章

  1. Spark 官网提到的几点调优

    1. 数据序列化 默认使用的是Java自带的序列化机制.优点是可以处理所有实现了java.io.Serializable 的类.但是Java 序列化比较慢. 可以使用Kryo序列化机制,通常比Java ...

  2. Spark Streaming官方文档学习--上

    官方文档地址:http://spark.apache.org/docs/latest/streaming-programming-guide.html Spark Streaming是spark ap ...

  3. Spark Streaming官方文档学习--下

    Accumulators and Broadcast Variables 这些不能从checkpoint重新恢复 如果想启动检查点的时候使用这两个变量,就需要创建这写变量的懒惰的singleton实例 ...

  4. spark新能优化之shuffle新能调优

    shuffle调优参数 new SparkConf().set("spark.shuffle.consolidateFiles", "true") spark. ...

  5. Spark面试题(五)——数据倾斜调优

    1.数据倾斜 数据倾斜指的是,并行处理的数据集中,某一部分(如Spark或Kafka的一个Partition)的数据显著多于其它部分,从而使得该部分的处理速度成为整个数据集处理的瓶颈. 数据倾斜俩大直 ...

  6. Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十二)Spark Streaming接收流数据及使用窗口函数

    官网文档:<http://spark.apache.org/docs/latest/streaming-programming-guide.html#a-quick-example> Sp ...

  7. Spark Streaming的简单介绍

    本文讲解Spark流数据处理之Spark Streaming.本文的写作时值Spark 1.6.2发布之际,Spark 2.0预览版也已发布,Spark发展如此迅速,请随时关注Spark Stream ...

  8. Spark调优 | Spark Streaming 调优

    Spark调优 | Spark Streaming 调优 1.数据序列化 2.广播大变量 3.数据处理和接收时的并行度 4.设置合理的批处理间隔 5.内存优化 5.1 内存管理 5.2优化策略 5.3 ...

  9. Spark学习之路 (八)SparkCore的调优之开发调优

    摘抄自:https://tech.meituan.com/spark-tuning-basic.html 前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark ...

随机推荐

  1. 图数据库Neo4j简介

    图数据库Neo4j简介 转自: 图形数据库Neo4J简介 - loveis715 - 博客园https://www.cnblogs.com/loveis715/p/5277051.html 最近我在用 ...

  2. NFL原则告诉我们做决策的时候,试图找到一个能解决所有问题,“大而全”的方案是不存在的。我们应当找到最关心的问题,因地制宜做出选择。——聚焦目标,取舍有道!

    资源匮乏原则:有限的资源无法满足无穷的需要及欲望:因此想要多一点的某件东西,意味着必须放弃一些其他的东西:因为资源匮乏,所以我们必须做出选择. NFL原则:没有免费午餐定理(No Free Lunch ...

  3. Java之泛型浅解

    我觉得学习一个东西,首先得从概念上明白它大概是什么? “泛型”就是“参数化类型”,也就是是把类型当成了一种参数.之前我们看到得函数方法比如: public long add(int num1,int ...

  4. GeoServer基础教程(二):GeoServer的Web管理界面快速入门

    转载:http://blog.163.com/daimiao_study/blog/static/248923117201542522742373/ GeoServer的控制和管理是基于网页形式,所有 ...

  5. SQLite优化方法

    1.建表优化 SQLite的数据库本质文件读写操作,频繁操作打开和关闭是很耗时和浪费资源的: 优化方法事务机制: 这里要注意一点:事务的开启是要锁定DB的,其他对DB的写入操作都是无法成功的. db. ...

  6. luogu1776宝物筛选

    多重背包问题 一开始我们的转移方程是 ;i<=n;i++) for(int j=m;j>=w[i];j--) ;k<=c[i];k++) )dp[j]=max(dp[j],dp[j- ...

  7. 1057 Stack (30)(30 分)

    Stack is one of the most fundamental data structures, which is based on the principle of Last In Fir ...

  8. Aravis 库编译方法

    Aravis 库编译方法 March 21, 2015 9:40 PM 首先下载 aravis 库的源代码:aravis 库下载地址 这里我们使用的是 aravis_0_2_0,比较老的一个版本. 首 ...

  9. Sublime 实践

    1.下载开发版:http://www.sublimetext.com/dev 2.安装Package control: (1)按键ctrl+~ (2)在命令行中输入:  import urllib2, ...

  10. 功能强大的Northwoods GoDiagram控件库

    Northwoods GoDiagram控件库用于开发图形应用 Northwoods GoDiagram控件库是付费软件,其官方网址为http://www.nwoods.com/ Northwoods ...