Flink——Side Output侧输出流

主要内容:

  • 结合应用场景,介绍Flink侧输出流的使用流程和原理

在处理数据的时候,有时候想对不同情况的数据进行不同的处理,那么就需要把数据流进行分流。可以在主数据流上产生出任意数量额外的侧输出流。

1 场景

某公司使用埋点组件收集到了埋点数据,并实时写入了Kafka。其中,埋点数据共分为三类:Web端埋点数据、移动端埋点数据和CS端埋点数据。现在需要从Kafka读取埋点数据,并分别对三端数据做不同的处理逻辑:

2 Side Output

当然使用 filter 对主数据流进行过滤,也能满足上述场景,但每次筛选过滤都要保留整个流,然后通过遍历整个流来获取相应的数据,显然很浪费性能。假如能够在一个流里面就进行多次输出就好了,恰好 Flink 的 Side Output 提供了这样的功能。Flink的Side Output侧输出流的作用在于将主数据分割成多个不同的侧输出流。侧输出结果流的数据类型不需要与主数据流的类型一致,不同侧输出流的类型也可以不同。

在上述场景中,可以使用Flink此功能:将Kafka的埋点数据进行分类,分为web端、mobile端和CS端三类,然后再对每类埋点数据进行相应的处理。

在这里插入图片描述

3 处理流程

3.1 定义OutputTag

在使用侧输出的时候需要先定义一个OutputTag,来标识 Side Output,代表这个 Tag 是要收集哪种类型的数据。这里定义了三个 OutputTag:

  • webTerminal:web端埋点数据
  • mobileTerminal:移动端埋点数据
  • csTerminal:CS端埋点数据
lazy val webTerminal: OutputTag[MdMsg] = new OutputTag[MdMsg]("Web端埋点数据")
lazy val mobileTerminal: OutputTag[MdMsg] = new OutputTag[MdMsg]("移动端埋点数据")
lazy val csTerminal: OutputTag[MdMsg] = new OutputTag[MdMsg]("CS端埋点数据")

3.2 使用特定的处理函数

要使用侧输出,在处理数据的时候除了要定义相应类型的OutputTag外,还要使用特定的函数,主要是有四个:

  • ProcessFunction
  • CoProcessFunction
  • ProcessWindowFunction
  • ProcessAllWindowFunction

该场景里选择使用ProcessFunction函数。该函数继承于RichFunction,使用时必须要重写processElement方法。自定义ProcessFunction函数:

class MdSplitProcessFunction extends ProcessFunction[MdMsg, MdMsg] {
   

    override def processElement(value: MdMsg, ctx: ProcessFunction[MdMsg, MdMsg]#Context, out: Collector[MdMsg]): Unit = {
   
      // web
      if (value.mdType ==
### Flink侧输出流的概念 在 Apache Flink 的流处理模型中,侧输出流允许从主数据流中分离出一部分数据形成新的输出流。这一特性对于实现复杂事件处理逻辑非常有用,在某些情况下可能需要基于特定条件将部分记录分流到不同的路径上。 当定义了一个 `SideOutput` 后,可以通过调用 `processElement()` 方法中的上下文对象来向指定的侧输出标签发送元素[^1]。 ### 使用 Side Output Stream 的实例 下面是一个简单的 Python 实现例子,展示了如何创建以及利用侧输出: ```python from pyflink.datastream import StreamExecutionEnvironment, SideOutputTag from pyflink.table import StreamTableEnvironment env = StreamExecutionEnvironment.get_execution_environment() t_env = StreamTableEnvironment.create(env) # 定义两个侧输出标记 side_output_low_temp = SideOutputTag('low_temperature') side_output_high_humidity = SideOutputTag('high_humidity') def process_func(element, ctx): temperature, humidity = element # 如果温度低于某个阈值,则将其写入低温侧输出 if temperature < 20: ctx.output(side_output_low_temp, ("Low Temp", temperature)) # 如果湿度高于某个百分比,则将其写入高湿侧输出 elif humidity > 80: ctx.output(side_output_high_humidity, ("High Humidity", humidity)) return (temperature, humidity) ds = env.from_collection([(15,70), (25,90)]) main_stream = ds.process(process_func).print() (main_stream .get_side_output(side_output_low_temp) .print()) (main_stream .get_side_output(side_output_high_humidity) .print()) env.execute("example_job") ``` 在这个脚本里,首先设置了环境变量并导入必要的库文件;接着定义了两个用于区分不同类型的气象状况(低温和高湿度)的侧输出标签;最后通过自定义函数 `process_func` 来判断输入元组是否满足进入相应分支的标准,并据此分配给对应的侧输出或继续沿主线程前进。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值