SparkStreaming编程指南学习
文章目录
- SparkStreaming编程指南学习
- 1:SparkStreaming编程指南
- 1:概述
- 2:基本概念
- 2.1:DStream,DataSet以及DataFrame
- 2.2:rdd算子介绍
- 2.3:checkpoint检查点
- 1:checkpoint存储的数据
- 2:checkpoint配置
- 3:使用
- 4:checkpoint和广播变量
- 3:sparkStreaming开发
- 3.1:maven依赖引入
- 3.2初始化StreamingContext
- 3.3:DStream 常见操作
- 1:窗口函数操作
- 2:join操作
- 3:Dstream的算子
- 3.4:持久化
- 4:部署启动
- 4.1:yarn的demo
- 5:日志监控
- 6:调优
- 6.1:并行度
- 1:数据接收并行度
- 2:数据处理并行度
- 6.2:序列化
- 1:RDD缓存级别
- 2:序列化类
- 1:java序列化
- 2:kryo序列化
- 6.3:接收处理限速
- 6.4:内存资源调优
1:SparkStreaming编程指南
1:概述
Spark Streaming 是 Spark Core API 的扩展,它支持弹性的,高吞吐的,容错的实时数据流的处理
2:基本概念
2.1:DStream,DataSet以及DataFrame
DataSet:是一个由特定域的对象组成的强类型集合,可通过功能或关系操作并行转换其中的对象。 每个Dataset还有一个非类型视图,即由多个列组成的DataSet,称为DataFrame。
DataFrame:是一个由多个列组成的结构化的分布式数据集合,等同于关系数据库中的一张表。DataFrame是Spark SQL中的最基本的概念,可以通过多种方式创建,例如结构化的数据集、Hive表、外部数据库或者是RDD。
DStream: 被表示为一系列连续的 RDDs,每个 RDD 包含来自一定的时间间隔的数据。
- 1:DStream 构建
1:文件流:可实现监控目录文件
streamingContext.fileStream[KeyClass, ValueClass, InputFormatClass](dataDirectory)
streamingContext.textFileStream(dataDirectory="hdfs://namenode:8040/logs/")
2:集成kafka,flume等
- 2:DStream的算子操作
map(func) 每个元素传递给函数func来返回新的DStream
flatMap(func) 每个输入项可以映射到0个或多个输出项。
filter(func) 通过符合func返回true 的源DStream的记录来返回新的DStream
repartition(numPartitions) 通过创建更多或更少的分区来更改此DStream中的并行度
reduceByKey(func, [numTasks]) 返回一个新的(K,V)对的DStream,其中使用给定的reduce函数聚合每个键的值。
注意:默认情况下,此操作使用Spark的默认并行任务数(本地模式为2,而在集群模式下,
此数量由config属性确定spark.default.parallelism)进行分组。您可以传递一个可选numTasks参数来设置不同数量的任务。
transform(func) 通过对源DStream的每个RDD应用RDD-to-RDD函数来返回新的DStream。这可用于在DStream上执行任意的RDD操作,transform该功能非常强大,
- 3:Dstream的输出算子操作
print() 在运行流应用程序的驱动程序节点上,打印DStream中每批数据的前十个元素。这对于开发和调试很有用。
saveAsTextFiles(prefix, [suffix]) 将此DStream的内容另存为文本文件。基于产生在每批间隔的文件名的前缀和后缀:“prefix-TIME_IN_MS [.suffix]”。
saveAsObjectFiles(prefix, [suffix]) 将此DStream的内容保存为SequenceFiles序列化Java对象的内容。基于产生在每批间隔的文件名的前缀和 后缀:“前缀TIME_IN_MS [.suffix]”。
saveAsHadoopFiles(prefix, [suffix]) 将此DStream的内容另存为Hadoop文件。基于产生在每批间隔的文件名的前缀和后缀:“prefix-TIME_IN_MS [.suffix]”。
foreachRDD(func) 最通用的输出运算符,将函数func应用于从流生成的每个RDD。此功能应将每个RDD中的数据推送到外部系统,例如将RDD保存到文件或通过网络将其写入数据库。请注意,函数func是在运行流应用程序的驱动程序进程中执行的,并且通常在其中具有RDD操作,这将强制计算流RDD。
2.2:rdd算子介绍
2.3:checkpoint检查点
1:checkpoint存储的数据
checkpoint 有两种类型的数据。
Metadata checkpointing - 将定义 streaming 计算的信息保存到容错存储(如 HDFS)中。这用于从运行 streaming 应用程序的 driver 的节点的故障中恢复(稍后详细讨论)。
元数据包括:
Configuration - 用于创建流应用程序的配置。
DStream operations - 定义 streaming 应用程序的 DStream 操作集。
Incomplete batches - 批量的job 排队但尚未完成。
Data checkpointing - 将生成的 RDD 保存到可靠的存储。这在一些将多个批次之间的数据进行组合的 状态 变换中是必需的。
在这种转换中,生成的 RDD 依赖于先前批次的 RDD,这导致依赖链的长度随时间而增加。
为了避免恢复时间的这种无限增加(与依赖关系链成比例),有状态转换的中间 RDD 会定期 checkpoint 到可靠的存储(例如 HDFS)以切断依赖关系链。
2:checkpoint配置
可以通过在保存 checkpoint 信息的容错,可靠的文件系统(例如,HDFS,S3等)中设置目录来启用 checkpoint。
3:使用
实战demo
RD0.foreachRDD((VoidFunction<JavaRDD<ConsumerRecord<String, byte[]>>>) consumerRecordJavaRDD -> {
String checkPoint = "" + System.currentTimeMillis();
HasOffsetRanges hasOffsetRanges = (HasOffsetRanges) (consumerRecordJavaRDD.rdd());
StringBuilder sb = new StringBuilder();
for (OffsetRange of : hasOffsetRanges.offsetRanges()) {
sb.append(of.topic() + "-" + of.partition() + "=" + of.fromOffset() + "\n");
}
localCheckPoint.saveCheckPoint(checkPoint, sb.toString());
});
1:基本用法:保存
streamingContext.checkpoint(checkpointDirectory)
dstream.checkpoint(checkpointInterval)。通常,DStream的5-10个滑动间隔的检查点间隔是一个不错的尝试。
2:如果要使应用程序从 driver 故障中恢复,您应该重写 streaming 应用程序以具有以下行为。
当程序第一次启动时,它将创建一个新的 StreamingContext,设置所有流,然后调用 start()。
当程序在失败后重新启动时,它将从 checkpoint 目录中的 checkpoint 数据重新创建一个 StreamingContext。
3:getOrCreate
如果checkpointDirectory存在,则将根据检查点数据重新创建上下文。如果该目录不存在(即第一次运行),则将contextFactory调用该函数来创建新上下文并设置DStreams
val context = StreamingContext.getOrCreate(checkpointDirectory, functionToCreateContext _)
4:checkpoint和广播变量
无法从Spark Streaming中的检查点恢复累加器和广播变量。如果启用检查点并同时使用“ 累加器”或“ 广播”变量 ,则必须为“ 累加器”和“ 广播”变量创建延迟实例化的单例实例, 以便在驱动程序发生故障重新启动后可以重新实例化它们
3:sparkStreaming开发
3.1:maven依赖引入
1:sparkStreaming依赖
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_2.11</artifactId>
<version>2.2.0</version>
</dependency>
2:结合其他数据源的依赖
针对从 Spark Streaming Core API 中不存在的数据源中获取数据,如 Kafka,Flume,Kinesis,你必须添加相应的坐标 spark-streaming-xyz_2.11 到依赖中。例如,有一些常见的依赖如下。
Source(数据源) Artifact(maven坐标)
Kafka spark-streaming-kafka-0-8_2.11
Flume spark-streaming-flume_2.11
Kinesis
spark-streaming-kinesis-asl_2.11 [Amazon Software License]
3.2初始化StreamingContext
一个 StreamingContext 对象必须要被创建出来,它是所有的 Spark Streaming 功能的主入口点。
sparkstreaming初始化可以很sparkconf和SparkContext两种进行初始化
方式1:sparkconf
val conf = new SparkConf().setAppName(appName).setMaster(master)
val ssc = new StreamingContext(conf, Seconds(1))
方式2:SparkContext
val sc = SparkContext(master, appName)
val ssc = StreamingContext(sc, 1)
2:参数解释
appName: 参数是展示在集群 UI 界面上的应用程序的名称
master:该streaming程序的部署模式Spark, Mesos or YARN
在实践中,当在集群上运行时,你不会想在应用程序中硬编码 master,而是 使用 spark-submit 来启动应用程序,并且接受该参数。然而,对于本地测试和单元测试,你可以传递 “local[*]” 来运行 Spark Streaming 进程
batch interval:根据您的应用程序和可用的集群资源的等待时间要求进行设置
3.3:DStream 常见操作
1:窗口函数操作
任何窗口操作都需要指定两个参数。
窗口长度 - 窗口的持续时间
滑动间隔 -执行窗口操作的间隔。
这两个参数必须是源DStream的批处理间隔的倍数。
window(windowLength,slideInterval) 返回基于源DStream的窗口批处理计算的新DStream。
countByWindow(windowLength,slideInterval) 返回流中元素的滑动窗口计数。
reduceByWindow(func,windowLength,slideInterval) 返回一个新的单元素流,该流是通过使用func在滑动间隔内聚合流中的元素而创建的。该函数应该是关联的和可交换的,以便可以并行正确地计算它。
reduceByKeyAndWindow(func,windowLength,slideInterval,[ numTasks ]) 在(K,V)对的DStream上调用时,返回新的(K,V)对的DStream,其中使用给定的reduce函数func 在滑动窗口中的批处理上汇总每个键的值。注意:默认情况下,此操作使用Spark的默认并行任务数(本地模式为2,而在集群模式下,此数量由config属性确定spark.default.parallelism)进行分组。您可以传递一个可选 numTasks参数来设置不同数量的任务。
reduceByKeyAndWindow(func,invFunc,windowLength, slideInterval,[ numTasks ])
上面一种更有效的版本,reduceByKeyAndWindow()其中,使用前一个窗口的减少值递增地计算每个窗口的减少值。这是通过减少进入滑动窗口的新数据并“逆向减少”离开窗口的旧数据来完成的。一个示例是在窗口滑动时“增加”和“减少”键的计数。但是,它仅适用于“可逆归约函数”,即具有对应的“逆归约”函数(作为参数invFunc)的归约函数。像in中一样reduceByKeyAndWindow,reduce任务的数量可以通过可选参数配置。请注意,必须启用检查点才能使用此操作。
countByValueAndWindow(windowLength, slideInterval,[ numTasks ]) 在(K,V)对的DStream上调用时,返回新的(K,Long)对的DStream,其中每个键的值是其在滑动窗口内的频率。像in中一样 reduceByKeyAndWindow,reduce任务的数量可以通过可选参数配置。
2:join操作
包括leftOuterJoin,rightOuterJoin,fullOuterJoin
3:Dstream的算子
参见1.2.1Dstream
3.4:持久化
RDD持久化
Dstream持久化
与RDD不同,DStream的默认持久性级别将数据序列化在内存中
4:部署启动
4.1:yarn的demo
bin/spark-submit还将从中读取配置选项conf/spark-defaults.conf,也可以将配置写在该文件
$ ./bin/spark-submit --class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \
--driver-memory 4g \
--executor-memory 2g \
--executor-cores 1 \
--queue thequeue \
examples/jars/spark-examples*.jar \
10
1:添加依赖jar
--jars my-other-jar.jar,my-other-other-jar.jar \
my-main-jar.jar \
app_arg1 app_arg2
2:动态加载sparkconf属性
--conf "spark.executor.extraJavaOptions=-XX:+PrintGCDetails -XX:+PrintGCTimeStamps"
3:指定app名字
--name "My app"
4:加载配置文件
–files filename
5:日志监控
运行日志:http://:4040
日志也会存储在hdfs的datanode的数据目录下:hadoop/data*/nm/application_ID/
程序大量报错可能会使磁盘写满,程序报错,datanode故障,需要及时清理日志重启程序。
6:调优
6.1:并行度
1:数据接收并行度
1:集成替他: task num=批处理间隔/块间隔spark.streaming.blockInterval
2:集成kafka: task num=kafka分区数
2:数据处理并行度
如果在计算的任何阶段使用的并行任务数量不够高,则群集资源可能无法得到充分利用。例如,对于像reduceByKey 和这样的分布式归约操作reduceByKeyAndWindow,并行任务的默认数量由spark.default.parallelism 属性控制。您可以将并行性级别作为参数传递(请参见 PairDStreamFunctions 文档),或将spark.default.parallelism 配置属性设置为更改默认值。
6.2:序列化
1:RDD缓存级别
2:序列化类
包括java序列化和kryo序列化
1:java序列化
2:kryo序列化
kryo介绍 用Kryo序列化都可以减少CPU和内存的开销,比java序列化快10倍以上
1:使用,不注册也可以使用
指定序列化方式: conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
注册自定义类: conf.registerKryoClasses(Array(classOf[MyClass1], classOf[MyClass2]))
spark.kryo.classesToRegister false 如果您使用Kryo序列化,请提供一个逗号分隔的自定义类名称列表,以向Kryo注册。有关更多详细信息,请参见调整指南。
spark.kryo.referenceTracking treu 使用Kryo序列化数据时是否跟踪对同一对象的引用,如果对象图具有循环,则这是必需的;如果它们包含同一对象的多个副本,则对于提高效率很有用。如果您不是这种情况,可以禁用它以提高性能。
spark.kryo.registrationRequired false 是否要求向Kryo注册。如果设置为“ true”,则如果未注册的类被序列化,Kryo将引发异常。如果设置为false(默认值),Kryo将与每个对象一起写入未注册的类名称。编写类名称可能会导致大量的性能开销,因此启用此选项可以严格执行以下操作:用户没有从注册中省略类。
spark.kryo.registrator false 如果您使用Kryo序列化,请提供一个用逗号分隔的类列表,用于向Kryo注册您的自定义类。如果您需要以自定义方式注册类(例如,指定自定义字段序列化程序),则此属性很有用。否则spark.kryo.classesToRegister比较简单。应该将其设置为extends类 。有关更多详细信息,请参见调整指南。 KryoRegistrator
spark.kryo.unsafe false 是否使用不安全的Kryo串行器。使用基于不安全的IO可以大大提高速度。
spark.kryoserializer.buffer.max 64m 除非另有说明,否则Kryo序列化缓冲区的最大允许大小(以MiB为单位)。它必须大于您尝试序列化的任何对象,并且必须小于2048m。如果在Kryo中收到“超出缓冲区限制”异常,请增加此值。
spark.kryoserializer.buffer 64k 除非另有说明,否则Kryo序列化缓冲区的初始大小,以KiB为单位。请注意,每个工作线程上每个内核将有一个缓冲区。spark.kryoserializer.buffer.max如果需要,此缓冲区将增长
6.3:接收处理限速
SparkConf配置spark.streaming.receiver.maxRate
spark.streaming.kafka.maxRatePerPartition:每个分区最大拉取的条数
6.4:内存资源调优
内存消耗:Web UI中的“ Storage”页面
资源调优