容错(Fault-tolerance)

Spark Streaming的容错包括了三个地方的容错:
1、Executor失败容错:Executor的失败会重新启动一个新的Executor,这个是Spark自身的特性。如果Receiver所在的Executor失败了,那么Spark Streaming会在另外一个Executor上启动这个Receiver(这个Executor上可能存在已经接收到的数据的备份)
2、Driver失败的容错:如果Driver失败的话,那么整个Spark Streaming应用将会全部挂掉。所以Driver端的容错是非常重要的,我们首先可以配置Driver端的checkpoint,用于定期的保存Driver端的状态;然后我们可以配置Driver端失败的自动重启机制(每一种集群管理的配置都不一样);最后我们需要打开Executor端的WAL机制
3、一个Task失败的容错:Spark中的某个Task失败了可以重新运行,这个Task所在的Stage失败的话呢,也可以根据RDD的依赖重新跑这个Stage的父亲Stage,进而重新跑这个失败的Stage,在实时计算的过程,肯定不能容忍某个Task的运行时间过长,Spark Streaming对于某个运行时间过长的Task会将这个Task杀掉重新在另一个资源比较充足的Executor上执行。这个就是利用了Spark的Task调度的推测机制。

Executor失败容错

 

 Driver失败容错

 

checkpoint机制:定期将Driver端的信息写到HDFS中
1、configuration (配置信息)
2、定义的DStream的操作
3、没有完成的batches的信息
 
1、设置自动重启Driver程序
standalone、yarn以及mesos都支持
 
2、设置hdfs的checkpoint目录
streamingContext.setCheckpoint(hdfsDirectory)
3、在driver端使用正确的API来达到Driver的容错,需要写代码
import org.apache.spark.storage.StorageLevel
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.{SparkConf, SparkContext}

/**
  * WordCount程序,Spark Streaming消费TCP Server发过来的实时数据的例子:
  *
  * 1、在master服务器上启动一个Netcat server
  * `$ nc -lk 9998` (如果nc命令无效的话,我们可以用yum install -y nc来安装nc)
  *
  * 2、用下面的命令在在集群中将Spark Streaming应用跑起来
  * spark-submit --class com.twq.wordcount.JavaNetworkWordCount 
  * --master spark://master:7077 
  * --deploy-mode cluster 
  * --driver-memory 512m 
  * --executor-memory 512m 
  * --total-executor-cores 4 
  * --executor-cores 2 
  * /home/hadoop-twq/spark-course/streaming/spark-streaming-basic-1.0-SNAPSHOT.jar
  */
object NetworkWordCount {
  def main(args: Array[String]) {

    val checkpointDirectory = "hdfs://master:9999/user/hadoop-twq/spark-course/streaming/chechpoint"

    def functionToCreateContext(): StreamingContext = {
      val sparkConf = new SparkConf()
      .setAppName("NetworkWordCount")
      val sc = new SparkContext(sparkConf)

      // Create the context with a 1 second batch size
      val ssc = new StreamingContext(sc, Seconds(1))    

      //创建一个接收器(ReceiverInputDStream),这个接收器接收一台机器上的某个端口通过socket发送过来的数据并处理
      val lines = ssc.socketTextStream("master", 9998, StorageLevel.MEMORY_AND_DISK_SER_2)//  提高数据块的高可用性,备份两份,但会占用一定的内存

      //处理的逻辑,就是简单的进行word count
      val words = lines.flatMap(_.split(" "))
      val wordCounts = words.map(x => (x, 1)).reduceByKey(_ + _)

      //将结果输出到控制台
      wordCounts.print()
      ssc.checkpoint(checkpointDirectory)
      ssc
    }
    //  代码
    val ssc = StreamingContext.getOrCreate(checkpointDirectory, functionToCreateContext _)

    //启动Streaming处理流
    ssc.start()

    //等待Streaming程序终止
    ssc.awaitTermination()
  }
}

  

设置自动重启Driver程序
standalone :
在spark-submit中增加以下两个参数:
--deploy-mode cluster
--supervise
 
 
yarn :
在spark-submit中增加以下一个参数:
--deploy-mode cluster
在yarn配置中设置yarn.resourcemanager.am.max-attemps
 
 
mesos :
Marathon 可以重启 Mesos应用

接收到的数据丢失的容错

checkpoint机制:定期将Driver端的DStream DAG信息写到HDFS中(写内存和写磁盘同时进行)

利用WAL恢复数据的配置
1、设置hdfs的checkpoint目录
streamingContext.setCheckpoint(hdfsDirectory)
2、打开WAL的配置
sparkConf.set(“spark.streaming.receiver.writeAheadLog.enable”, “true”)
3、Receiver应该是reliable的
当数据写完了WAL后,才告诉数据源数据已经消费
对于没有告诉数据源的数据,可以从数据源中重新消费数据
4、取消掉in-memory数据备份
使用StorageLevel.MEMORY_AND_DISK_SER来存储数据源,已经写入磁盘,没必要备份到其他executor上内存中,进而节省空间

接收到的数据不管是备份到其他 Executor还是保存到HDFS上,都会给数据源发送回执,假设没有发送回执,重新消费没有发送回执的数据,进而保证数据不会丢失,eg: Kafka
Reliable Receiver :
当数据接收到,并且已经备份存储后,再发送回执给数据源
Unreliable Receiver :
不发送回执给数据源

当一个task很慢的容错

 

 
原文地址:https://www.cnblogs.com/tesla-turing/p/11488299.html