《Spark Streaming 编程指南核心概念之 缓存/持久化、检查点》

目录

1. 缓存/持久化

2. 检查点

2.1 什么时候启动检查点

2.2 如何配置检查点


1. 缓存/持久化

和RDD相同,DStreams 也允许开发者将 stream数据持久化到内存。也就是说,在DStream上使用persist()方法将会自动将每个DStream RDD保存到内存。这在DStream数据被多次使用的情况下会比较有用(同一个数据上有多个操作)。对于基于窗口的操作-例如:reduceByWindow和reduceByKeyAndWindow,以及基于状态的操作-例如:updateStateByKey,缓存会隐式的自动进行。因此,由基于窗口操作产生的DStream会自动持久化到内存,而不需要开发者手动调用persist()。

对于从网络(例如:kafka、Flume、Socket等)接收的stream,为容错,默认的持久化级别是在复制副本在另外的两个节点上。

请注意,与RDD不同(持久化到内存,未序列化),DStream的默认持久化级别是保存序列化的数据到内存。这将会在性能调优章节做进一步讨论。更多关于持久化级别的信息请参阅Spark编程指南

2. 检查点

一个Streaming 程序必须 24/7 不间断运行,因此程序必须能够从失败(例如,系统崩溃、JVM奔溃)中弹性恢复(与应用逻辑无关)。为实现这种可能,,Spark Streaming 需要 checkpoint 足够的信息到可容错的存储系统,这样它才能从失败中恢复。有两种信息需要checkpoint:

  • Metadata checkpoint - 保存定义streaming计算的信息到可容错的存储,例如HDFS。用来恢复运行streaming程序driver节点的失败。元数据包括:
    • 配置信息 - 配置信息用来创建streaming 程序
    • Dstream 操作 - 定义streaming 程序的DStream操作集合
    • 未完成的批次 - 队列中未完成的批次
  • Data checkpoint - 保存产生的RDD到可靠存储。这在一些在多个批次之间组合数据的有状态转换中时必要的。在这些转换操作中,产生的RDD依赖于之前批次的RDD,这就会导致依赖链的长度随时间持续增长。为避免恢复时间无限增加(与依赖链长度成正比),有状态转换的中间RDD会定期持久化到可靠存储,来切断依赖链。

总的来说,元数据 checkpointing主要是用来恢复driver失败,如果用到了有状态转换,数据或者RDD checkpointing 对于基本函数也是必要的。

2.1 什么时候启动检查点

下列情况需要启动检查点:

  • 使用了有状态转换 - 如果程序中使用了updateStateBykey或者 reduceByKeyAndWindow算子,那么必须提供checkpoint路径来定期的checkpoint RDD
  • 恢复运行程序的driver失败 - Metadata checkpoint

请注意,没有使用上面提到的转换操作的简单streaming 程序可以不启动checkpoint运行。但这种用例下的driver恢复仍然是需要的(一些接收但未处理的数据可能会)。这通常是可以接受的,

2.2 如何配置检查点

检查点可以通过配置一个可容错外部存储系统的路径来启用,这个路径将用来存储检查点信息。这通过使用 StreamingContext.checkpoint(checkpointDirectory)来完成。此外,如果你想让程序能从driver失败中恢复,你需要重写streaming 程序,使其有下述行为:

  • 当程序第一次启动时,会创建一个新的StreamingContext ,设置所有的stream 并调用 start()
  • 当程序从失败中恢复时,会根据检查点存储的信息重新创建StreamingContext
// 创建一个新的 StreamingContext
def functionToCreateContext(): StreamingContext = {
  val ssc = new StreamingContext(...)   // new context
  val lines = ssc.socketTextStream(...) // create DStreams
  ...
  ssc.checkpoint(checkpointDirectory)   // set checkpoint directory
  ssc
}

// 从检查点获取 StreamingContext 或者创建一个新的
val context = StreamingContext.getOrCreate(checkpointDirectory, functionToCreateContext _)

// Do additional setup on context that needs to be done,
// irrespective of whether it is being started or restarted
context. ...

// Start the context
context.start()
context.awaitTermination()

如果checkpointDirectory存在,那么这个context会从检查点重建。如果不存在,则会调用functionToCreateContext来创建一个新的context,并配置DStream。可参考RecoverableNetworkWordCount。

此外,使用getOrCreate还需要保证driver可在失败时自动重启,这将会在部署章节介绍。

需要注意的是,RDD checkpoint会产生保存数据到可靠系统的消耗。这可能会导致处理时间增长。因此,检查点的间隔需要谨慎设置,对于小批次(比如 1秒),每个批次都检查点,会显著减少吞吐量。相反的,太频繁的检查点会引起血统和task大小增长,可能产生巨大影响。对于需要RDD检查点的有状态转换,默认的间隔是多个批次间隔,且至少10s.可以通过使用 dstream.checkpoint(checkpointInterval)来设置。一般情况下,可以尝试5-10个DStream滑动间隔。

注:转载请注明出处

参考:

http://spark.apache.org/docs/latest/streaming-programming-guide.html#caching--persistence

http://spark.apache.org/docs/latest/streaming-programming-guide.html#checkpointing

 

猜你喜欢

转载自blog.csdn.net/Mathieu66/article/details/85088976
今日推荐