sparkstreaming sparkstreaming容错机制

sparkstreaming运行流程

  1. 提交一个sparkstreaming程序到服务器运行,默认提交的服务器为client,并向ClusterManager报备申请资源。
  2. 在一个executor中单独启动一个receiver线程(默认一个,可以更改成多个)用来接收数据。
  3. receiver根据指定时间间隔(默认200ms)将数据分隔成一个个block并写入内存中
  4. receiver服务器端将block数据备份并将划分的block的一些信息发送给driver端
  5. driver端根据一定的时间间隔将这些block块组成一个RDD
  6. driver使用DStreamGraph记录的RDD依赖关系划分job,然后提交给obScheduler进行任务分配,默认一个block对应一个task

在这里插入图片描述

Executor失败

  • executor失败会在其他executor端启动receiver和tasks从而实现receiver端的高可用,不需要做特殊配置
    在这里插入图片描述

Driver失败

  • 可以使用checkpoint机制,定期的将driver信息写入到HDFS,从而在driver失败时恢复driver,从而实现driver端的高可用

在这里插入图片描述

driver的自动重启设置

步骤一

  • standlone
在spark-submit中增加以下两个参数:
--deploy-mode cluster
--supervise #失败后是否重启Driver
#使用示例:
spark-submit \
--master spark://node01:7077 \
--deploy-mode cluster \
--supervise \                        
--class com.streaming.Demo \
--executor-memory 1g \
--total-executor-cores 2 \
original-sparkStreamingStudy-1.0-SNAPSHOT.jar 

--deploy-mode cluster 集群模式
--supervise 失败之后自动重启 ,需要在集群模式下使用
  • spark on yarn
    • spark on yarn模式下,driver端和master共用一个JVM,被绑定在一起
在spark-submit中增加以下参数:
--deploy-mode cluster
在yarn配置中设置yarn.resourcemanager.am.max-attemps参数 ,默认为2,例如:
 <value>4</value> 自动重启次数

<property>
  <name>yarn.resourcemanager.am.max-attempts</name>
  <value>4</value>
  <description>
    The maximum number of application master execution attempts.
  </description>
</property>
使用示例:
spark-submit \
--master yarn \
--deploy-mode cluster \
--class com.streaming.Demo \
--executor-memory 1g \
--total-executor-cores 2 \
original-sparkStreamingStudy-1.0-SNAPSHOT.jar 

步骤二

streamingContext.setCheckpoint(hdfsDirectory)

步骤三

// Function to create and setup a new StreamingContext
def functionToCreateContext(): StreamingContext = {
  val ssc = new StreamingContext(...)   // new context
  val lines = ssc.socketTextStream(...) // create DStreams
  ...
  ssc.checkpoint(checkpointDirectory)   // set checkpoint directory
  ssc
}

// Get StreamingContext from checkpoint data or create a new one
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()

数据丢失

executor备份

receiver所在的executor接受后,除了将数据写入自己的内存,还会将数据向blockManager备份。当该executor挂掉后,可以读取备份的数据,但是可能丢失部分没来的即备份的数据。
在这里插入图片描述

WAL预写日志

WAL概念

  • WAL使用在文件系统和数据库中用于数据操作的持久性,先把数据写到一个持久化的日志中,然后对数据做操作,如果操作过程中系统挂了,恢复的时候可以重新读取日志文件再次进行操作。

  • 对于像kafka和flume这些使用接收器来接收数据的数据源。接收器作为一个长时间的任务运行在executor中,负责从数据源接收数据,如果数据源支持的话,向数据源确认接收到数据,然后把数据存储在executor的内存中,然后在exector上运行任务处理这些数据。

  • 如果wal启用了,所有接收到的数据会保存到一个日志文件中去(HDFS), 这样保存接收数据的持久性,此外,如果只有在数据写入到log中之后接收器才向数据源确认,这样driver重启后那些保存在内存中但是没有写入到log中的数据将会重新发送,这两点保证的数据的无丢失


可靠数据源和不可靠数据源

Reliable Receiver : 当数据接收到,并且已经备份存储后,再发送回执给数据源
Unreliable Receiver : 不发送回执给数据源

  • 每次receiver端的executor接受到数据后,通过WAL机制,将数据写入到HDFS,HDFS本身又有备份。这样比较安全丢失概率小。
  • 但是:当写数据到HDFS磁盘的过程中executor中挂掉,数据没有写入HDFS成功,此时数据丢失。
    可以使用一个可靠的数据源,如:kafka。来保证数据在写入磁盘前不丢失
    • kafka可以设置当数据处理成功时,会接受回执,否则会重新发送,从而保证了数据写入HDFS成功
    • 而socket这种只管发送,不根据回执决定是否重新发送的数据源为不可靠数据源

在这里插入图片描述

实现步骤

步骤一:设置checkpoint目录

streamingContext.setCheckpoint(hdfsDirectory)

步骤二:开启WAL日志

sparkConf.set("spark.streaming.receiver.writeAheadLog.enable", "true")

步骤三:需要reliable receiver

当数据写完了WAL后,才告诉数据源数据已经消费,对于没有告诉数据源的数据,可以从数据源中重新消费数据

步骤四:取消备份

//使用StorageLevel.MEMORY_AND_DISK_SER来存储数据源,不需要后缀为2的策略了(默认是2),因为HDFS已经是多副本了
val initDS: ReceiverInputDStream[String] = sc.socketTextStream("node01",9999,StorageLevel.MEMORY_AND_DISK_SER)

某个task特别慢

在这里插入图片描述

在这里插入图片描述

推测机制

spark.speculation=true,每隔一段时间来检查有哪些正在运行的task需要重新调度(spark.speculation.interval=100ms),假设总的task有10个,成功的task的数量 > 0.75 * 10(spark.speculation.quantile=0.75),正在运行的task的运行时间 > 1.5 * 成功运行task的平均时间(spark.speculation.multiplier=1.5),则这个正在运行的task需要重新等待调度。

推测机制的风险

在分布式环境中导致某个Task执行缓慢的情况有很多,负载不均、程序bug、资源不均、数据倾斜等,而且这些情况在分布式任务计算环境中是常态。Speculative Task这种以空间换时间的思路对计算资源是种压榨,同时如果Speculative Task本身也变成了Slow Task会导致情况进一步恶化。负载不均、数据倾斜等原因导致的问题,使用Speculative Task并不会解决问题,慢的task会重复反复提交,反复的占用资源。
  Speculative Task要谨慎使用

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值