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 @ 2024-01-22 17:54  会飞的猪仔  阅读(56)  评论(0)    收藏  举报