Spark Streaming Receiver restart 重启

一.引言:

 

Spark Streaming 支持通过 Receiver 自定义数据流,实现之后由于接受客户端的不稳定时常造成streaming程序的崩溃,最早的想法是在Receiver实现中加入try catch,通过异常处理使得数据不会中断,但是Receiver整体的中断还是会迫使程序退出,不受Reciver内部的Try Catch控制,所以需要新的策略重启Receiver,好在Spark官方早就给出了解决方案,下面看看怎么使用。

二.源码:

Spark Doc中共有三种restart方案,可以根据自己的需求选择,不过大同小异主要的诉求就是Receiver出问题后重启:

1.Dirver接收消息

def restart(message: String): Unit
 Restart the receiver. This method schedules the restart and returns immediately. 
The stopping and subsequent starting of the receiver (by calling onStop() and 
onStart()) is performed asynchronously in a background thread. The delay between 
the stopping and the starting is defined by the Spark configuration 
spark.streaming.receiverRestartDelay. The message will be reported to the driver.

重新启动接收器。此方法安排重新启动并立即返回。接收器的停止和随后的启动(通过调用onStop()和onStart())是在后台线程中异步执行的。停止和启动之间的延迟由spark配置定义spark.streaming.receiverRestartDelay. 消息将报告给Dirver端。

2.Diver接收消息+异常

def restart(message: String, error: Throwable): Unit
Restart the receiver. This method schedules the restart and returns immediately. 
The stopping and subsequent starting of the receiver (by calling onStop() and 
onStart()) is performed asynchronously in a background thread. The delay between 
the stopping and the starting is defined by the Spark configuration 
spark.streaming.receiverRestartDelay. The message and exception will be reported to 
the driver.

重新启动接收器。此方法安排重新启动并立即返回。接收器的停止和随后的启动(通过调用onStop()和onStart())是在后台线程中异步执行的。停止和启动之间的延迟由spark配置定义spark.streaming.receiverRestartDelay. 消息和异常将报告给Dirver端。

3.直接重启

def restart(message: String, error: Throwable, millisecond: Int): Unit
Restart the receiver. This method schedules the restart and returns immediately. 
The stopping and subsequent starting of the receiver (by calling onStop() and 
onStart()) is performed asynchronously in a background thread.

重新启动接收器。此方法安排重新启动并立即返回。接收器的停止和随后的启动(通过调用onStop()和onStart())是在后台线程中异步执行的。

三.实现

之前实现过Demo版本的Receiver,如果想了解可以参考Spark 自定义Receiver

主要改动在Reveriver内部的 onStart()方法 和 onStop()方法:

1.onStart()

Old Version:

老版本直接起了一个线程去执行接收数据,异常处理在receiver中。

    def onStart(): Unit = {
      new Thread() {
        override def run(): Unit = {
          receive()
        }
      }.start()
    }

New Version:

为了增加鲁棒性,需要在onStart方法中加入异常处理,并调用restart恢复。这里使用了第二种restart方法,将消息与异常传回dirver。

    def onStart(): Unit = {
      new Thread() {
        override def run(): Unit = {
          try {
            receive()
          } catch {
            case e: ConnectException => {
              restart("Connect Failed...", e)
            }
            case t: Throwable => {
              restart("Error receiving data...", t)
            }
          }
        }
      }.start()
    }

2.onStop()

Old Version:

之前实现的onStop出现异常就直接退出了,所以程序经常会终止。

    def onStop: Unit = {
      if (Thread.currentThread.isInterrupted) {
        sys.exit(1)
      }
    }

New Version:

修改后取消了直接退出的逻辑,新增了report逻辑,这里类似restart向dirver汇总数据一样,可以在report内定义自己的汇报逻辑,当然也可以不实现任何方法。

    def onStop: Unit = {
      report()
    }

四.效果

经过 onStrat() 新增重启机制 和 onSrop() 的取消退出机制+回传机制,Streaming稳定性得到保障。可以看到图中接收数据有明显的跃阶,其中的间隔就是上面提到的 spark.streaming.receiverRestartDelay 参数定义的,可以自定义也可以使用默认,换到之前逻辑跃阶处会导致Streaming程序异常退出,数据的完整性将受到影响。其次restart的调用位置可以放在receiver()函数内,也可以放在onStart()函数内,区别不是很大,因为三种restart方法都会异步重新调用onStop()和onStart(),所以将restart逻辑写在receiver函数逻辑内应该也没有问题,有需求的同学可以尝试~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BIT_666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值