Spark Streaming自定义Receiver

spark streaming可以从任何数据源来接收数据,哪怕是除了它内置支持的数据源以外的其他数据源(比如flume、kafka、socket等)。
如果我们想要从spark streaming没有内置支持的数据源中接收实时数据,那么我们需要自己实现一个receiver。

实现一个自定义的receiver

一个自定义的receiver必须实现以下两个方法:onStart()、onStop()。onStart()和onStop()方法必须不能阻塞数据,一般来说,
onStart()方法会启动负责接收数据的线程,onStop()方法会确保之前启动的线程都已经停止了。负责接收数据的线程可以调用
isStopped()方法来检查它们是否应该停止接收数据。

一旦数据被接收了,就可以调用store(data)方法,数据就可以被存储在Spark内部。有一系列的store()重载方法供我们调用,来将数据
每次一条进行存储,或是每次存储一个集合或序列化的数据。

接收线程中的任何异常都应该被捕获以及正确处理,从而避免receiver的静默失败。restart()方法会通过异步地调用onStop()和
onStart()方法来重启receiver。stop()方法会调用onStop()方法来停止receiver。reportError()方法会汇报一个错误消息给driver
,但是不停止或重启receiver。
复制代码
package com.ljpbd.bigdata.spark.stream_1

import org.apache.spark.storage.StorageLevel
import org.apache.spark.streaming.receiver.Receiver

import java.io.{BufferedReader, InputStreamReader}
import java.net.Socket
import java.nio.charset.StandardCharsets

class CustomerReceiver(host: String, port: Int) extends Receiver[String](StorageLevel.MEMORY_ONLY) {
  override def onStart(): Unit = {
    new Thread(new Runnable {
      override def run(): Unit = {
        receive()
      }
    }).start()
  }

  def receive(): Unit = {
    try {
      val socket = new Socket(host, port)
      var input: String = null
      val reader = new BufferedReader(new InputStreamReader(socket.getInputStream, StandardCharsets.UTF_8))
      input = reader.readLine()
      while (!isStopped() && input != null) {
        store(input)
        input = reader.readLine()

      }
      reader.close()
      socket.close()
      restart("restart")
    }catch {
      case exception: Exception=>{
        restart("Error receiving data", exception)
      }
    }
  }

  override def onStop(): Unit = {}
}
复制代码

通过调用

sc.receiverStream(new CustomerReceiver("localhost", 9999))

 

posted @   会飞的猪仔  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示