Flink--Souce(自定义)

本文介绍了如何在Apache Flink中自定义SourceFunction,以解决实际场景下数据不足或数据源访问问题。通过实例展示了如何创建一个模拟温度传感器数据的SourceFunction,包括数据生成、偏移模拟和不间断发送过程。

自定义Source

使用自定义的Source具体可以用在以下两个场景:

  1. 系统以及开发好了,但是没有足够数量的数据
  2. 没有具体的实现方法到数据源去读取数据
    此时就需要我们去实现一个自定义Sources

实现自定义Sources

需要:模拟温度传感器产生的数据

当所需sourceFunciton没有具体实现时,需要自定义:

class mySource() extends SourceFunction[SensorReading]{}

这里SourceFunction[T] 中传入的泛型为要发出参数的类型:
首先SourceFunction把这个泛型T传给 SourceContext [T],
然后再 SourceContext 的collet方法中发现 传入泛型T并把结果发送了出去

所以这里泛型设置为 SensorReading

因为SourceFunction是抽象类,所以要重写父类方法

cancel: 用于控制停止发送数据
run:生产或者读取数据 并通过SourceContext.collect发送出去。

Cancel

定义一个flag用于标识是否发送数据,然后当调用cancel就使其false

var running:Boolean = true
override def cancel(): Unit = running = false

Run

这里首先产生十个温度传感器的初始值

 val random = new Random()
    //获取初始数据
    val originData = 1.to(10).map(data => ("Sensor_"+data,random.nextDouble() * 100))

然后再初始值上加上高思函数偏移量用于模拟真实环境

val mapedData = originData.map(data => (data._1,data._2 + random.nextGaussian()))

然后保证成SensorReading类型发送出去

//获取时间戳
      val timeStamp = System.currentTimeMillis()

//发出数据
mapedData.foreach(data =>sourceContext.collect(SensorReading(data._1,timeStamp,data._2)))

因为需要源源不断发送,所以添加循环

override def run(sourceContext: SourceFunction.SourceContext[SensorReading]): Unit = {

    val random = new Random()
    //获取初始数据
    val originData = 1.to(10).map(data => ("Sensor_"+data,random.nextDouble() * 100))

    while(running){

    //添加偏移量
    val mapedData = originData.map(data => (data._1,data._2 + random.nextGaussian()))

    //获取时间戳
    val timeStamp = System.currentTimeMillis()

    //发出数据
    mapedData.foreach(data =>sourceContext.collect(SensorReading(data._1,timeStamp,data._2)))

    //添加睡眠时间
    Thread.sleep(100)
    }

完整代码

package com.erke

import org.apache.flink.streaming.api.functions.source.SourceFunction
import org.apache.flink.streaming.api.scala._

import scala.util.Random


case class SensorReading(id:String,timeStamp:Long,temperature:Double)

class mySource() extends SourceFunction[SensorReading]{
  var running:Boolean = true
  override def cancel(): Unit = running = false

  override def run(sourceContext: SourceFunction.SourceContext[SensorReading]): Unit = {

    val random = new Random()
    //获取初始数据
    val originData = 1.to(10).map(data => ("Sensor_"+data,random.nextDouble() * 100))

    while(running){

      //添加偏移量
      val mapedData = originData.map(data => (data._1,data._2 + random.nextGaussian()))

      //获取时间戳
      val timeStamp = System.currentTimeMillis()

      //发出数据
      mapedData.foreach(data =>sourceContext.collect(SensorReading(data._1,timeStamp,data._2)))

      //添加睡眠时间
      Thread.sleep(100)
    }
  }
}

object soureApiTest {
  def main(args: Array[String]): Unit = {

    val env = StreamExecutionEnvironment.getExecutionEnvironment

    val mySouceDataStream = env.addSource(new mySource())

    mySouceDataStream.print()

    env.execute("SourceTest")
  }
}

Apache Flink 提供了多种连接器,用于与不同的消息队列系统进行集成。对于 MQTT(Message Queuing Telemetry Transport)协议的支持,Flink 社区和第三方开发者提供了相应的连接器组件,允许用户从 MQTT 主题中消费数据或将数据发布到 MQTT 主题。 ### Flink 连接 MQTT 的方式 1. **使用 Apache Bahir 提供的 Flink MQTT 连接器** Apache Bahir 是一个为流处理引擎提供扩展连接器的项目,其中包括对 Flink 的 MQTT 支持。该连接器允许 Flink 作为 MQTT 客户端订阅主题并处理流数据。 - Maven 坐标: ```xml <dependency> <groupId>org.apache.bahir</groupId> <artifactId>flink-connector-mqtt_2.11</artifactId> <version>1.15.0</version> </dependency> ``` - 示例代码:创建 MQTT 源 ```java StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); MqttProperties props = new MqttProperties(); props.setBroker("tcp://mqtt-broker:1883"); props.setTopic("sensor/data"); props.setClientId("flink-consumer"); DataStream<String> mqttStream = env.addSource(new MqttSource(props)); mqttStream.print(); env.execute("Flink MQTT Source Example"); ``` 2. **自定义 MQTT 连接器开发** 如果现有连接器无法满足业务需求,可以基于 Eclipse Paho(MQTT 客户端库)自行实现 Flink 的 `SourceFunction` 或 `SinkFunction` 来与 MQTT 服务交互。 - 引入 Paho 依赖: ```xml <dependency> <groupId>org.eclipse.paho</groupId> <artifactId>org.eclipse.paho.client.mqttv3</artifactId> <version>1.2.5</version> </dependency> ``` - 自定义 MQTT 源示例: ```java public class CustomMqttSource implements SourceFunction<String> { private volatile boolean isRunning = true; private IMqttClient client; @Override public void run(SourceContext<String> ctx) throws Exception { String broker = "tcp://mqtt-broker:1883"; String clientId = "custom-flink-source"; MemoryPersistence persistence = new MemoryPersistence(); client = new MqttClient(broker, clientId, persistence); MqttConnectOptions options = new MqttConnectOptions(); options.setAutomaticReconnect(true); client.connect(options); client.subscribe("sensor/#", (topic, msg) -> { String payload = new String(msg.getPayload()); ctx.collect(payload); }); } @Override public void cancel() { isRunning = false; if (client != null && client.isConnected()) { try { client.disconnect(); } catch (MqttException e) { // handle exception } } } } ``` 3. **Flink SQL 中使用 MQTT 连接器** 若采用 Flink SQL 方式构建流处理应用,可通过自定义 `Factory` 实现 MQTT 表连接器,并通过 `CREATE TABLE ... WITH ('connector' = 'mqtt')` 的方式声明源或目标表[^4]。 --- ### 下载与文档 - **官方推荐下载地址**: - [Apache Bahir](https://bahir.apache.org/) 官网提供各版本 Flink MQTT 连接器的下载链接。 - GitHub 上的镜像仓库也可用于获取源码和编译包,如:[https://github.com/apache/bahir-flink](https://github.com/apache/bahir-flink) - **使用指南参考**: - [Flink MQTT Connector Documentation](https://bahir.apache.org/docs/flink/current/) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值