Flink自定义事件事件和水位线

目录

 

主类

pom.xml

结果输出


主类

package myflink.EventTime;

import org.apache.flink.api.common.eventtime.*;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.TimeCharacteristic;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.ProcessFunction;
import org.apache.flink.util.Collector;

import java.text.SimpleDateFormat;
import java.util.Date;


/**
 * @author pangsl
 * @date 2021/5/25 17:02
 * @Description Flink自定义事件事件和水位线
 */
public class WindowAndWatermarkDemo {
    public static void main(String[] args) throws Exception {


        StreamExecutionEnvironment sEnv = StreamExecutionEnvironment.getExecutionEnvironment();
        //设置使用EventTime,默认使用processtime
        sEnv.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
        //设置并行度为1,默认并行度是当前机器的CPU数量
        sEnv.setParallelism(1);


        DataStream<String> input = sEnv.addSource(new MySource());
        /*消息格式:String,time。例如:消息1,15115556459354*/
        //解析输入的数据
        DataStream<Tuple2<String, Long>> inputMap = input.map(new MapFunction<String, Tuple2<String, Long>>() {

            @Override
            public Tuple2<String, Long> map(String value) throws Exception {
                String[] arr = value.split(",");
                return new Tuple2<>(arr[0], Long.parseLong(arr[1]));
            }
        });
        //抽取timestamp,生成Watermark,这里使用的是Flink1.11最新版的水印生成策略
        DataStream<Tuple2<String, Long>> waterMarkStream = inputMap.assignTimestampsAndWatermarks(new WatermarkStrategy<Tuple2<String, Long>>() {

            @Override
            public WatermarkGenerator<Tuple2<String, Long>> createWatermarkGenerator(WatermarkGeneratorSupplier.Context context) {
                return new WatermarkGenerator<Tuple2<String, Long>>() {
                    private long maxTimestamp;
                    private long delay = 3000;

                    @Override
                    public void onEvent(Tuple2<String, Long> event, long eventTimestamp, WatermarkOutput output) {
                        maxTimestamp = Math.max(maxTimestamp, event.f1);

                    }

                    @Override
                    public void onPeriodicEmit(WatermarkOutput output) {
                        output.emitWatermark(new Watermark(maxTimestamp - delay));
                    }
                };
            }
        });
        /*获取水印信息*/
        waterMarkStream.process(new ProcessFunction<Tuple2<String, Long>, Object>() {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

            @Override
            public void processElement(Tuple2<String, Long> value, Context ctx, Collector<Object> out) throws Exception {
                long w = ctx.timerService().currentWatermark();
                System.out.println(" 水印 : " + w + "水印时间" + sdf.format(w) + "消息的事件时间" +
                        sdf.format(value.f1));
            }
        });
        waterMarkStream.print();
        sEnv.execute();
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>flinkdemo</artifactId>
        <groupId>com.flink.pangsl</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>Flink_shizhanpai</artifactId>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>


    <properties>
        <flink.version>1.11.0</flink.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <!--    flink核心依赖-->
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-core</artifactId>
            <version>${flink.version}</version>
            <scope>provided</scope>
        </dependency>

        <!--    flink流处理和批处理的依赖-->
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-streaming-java_2.11</artifactId>
            <version>${flink.version}</version>
            <scope>provided</scope>
        </dependency>

        <!--    flink客户端依赖-->
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-clients_2.11</artifactId>
            <version>${flink.version}</version>
            <scope>provided</scope>
        </dependency>

        <!--    flink Table API、SQL依赖-->
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-api-scala-bridge_2.11</artifactId>
            <version>${flink.version}</version>
            <scope>provided</scope>
        </dependency>

        <!--    flink 1.9之前的Old Planner依赖-->
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-planner_2.11</artifactId>
            <version>${flink.version}</version>
            <scope>provided</scope>
        </dependency>

        <!--    flink BlinkPlanner依赖-->
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-planner-blink_2.11</artifactId>
            <version>${flink.version}</version>
            <scope>provided</scope>
        </dependency>

        <!--    flink Table的scala依赖-->
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-streaming-scala_2.11</artifactId>
            <version>${flink.version}</version>
            <scope>provided</scope>
        </dependency>


        <!--    flink Table的扩展依赖-->
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-common</artifactId>
            <version>${flink.version}</version>
            <scope>provided</scope>
        </dependency>

        <!--    flink kafka连接器依赖-->
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-connector-kafka-0.11_2.11</artifactId>
            <version>${flink.version}</version>
            <scope>provided</scope>
        </dependency>


    </dependencies>

</project>

 

结果输出

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Flink定义Sink和Source是指用户可以根据自己的需求,编写自己的数据源和数据输出方式。Flink提供了一些内置的Sink和Source,但是有时候用户需要根据自己的业务需求,自定义数据源和数据输出方式。 自定义Sink和Source需要实现Flink提供的接口,例如实现SinkFunction接口来自定义数据输出方式,实现SourceFunction接口来自定义数据源。用户可以根据自己的需求,实现这些接口,然后将自定义的Sink和Source应用到Flink程序中。 自定义Sink和Source可以帮助用户更好地满足自己的业务需求,提高数据处理的效率和准确性。 ### 回答2: Flink定义Sink和Source方便开发人员根据特定业务需求定制化的数据输入和输出。这也是Flink作为DataStream处理引擎的一个强大特性。 自定义Sink的主要作用是将Flink处理的数据流输出到外部存储或处理系统中,如Kafka、Hadoop、Elasticsearch、MySQL等。通过自定义Sink,我们可以满足不同业务场景下,数据输出的不同需求。 自定义Sink的实现需要继承Flink提供的`RichSinkFunction`或者`SinkFunction`抽象类,并实现其抽象方法。`RichSinkFunction`中提供了一些状态管理的方法,如`open`、`close`等,我们可以在这些方法中添加额外的代码逻辑。自定义的SinkFunction可以重写invoke方法,将不需要状态管理的代码集中在此方法中。 自定义Source的主要作用是将外部数据源中的数据读取并发送给Flink的DataStream处理模块。自定义Source可以读取各种类型的数据源,如Kafka、文件、Socket等。 自定义Source的实现需要继承Flink提供的`RichParallelSourceFunction`或者`SourceFunction`抽象类,并实现其抽象方法。`RichParallelSourceFunction`中支持在并行算子中运行,因此对于大规模数据的处理尤为适合。 在自定义Source中,需要实现一个`run`方法和一个`cancel`方法。`run`方法中是数据源处理逻辑的主要实现,`cancel`方法用于停止数据源的读取。我们还可以通过Flink提供的Checkpoint机制来管理数据源。 总之,自定义Sink和Source是Flink处理数据流的重要特性,使得开发人员可以根据业务需求灵活定制化的输入输出逻辑。 ### 回答3: Flink是一个开源流式处理框架,它提供了丰富的内置Sink和Source,同时也支持用户自定义的Sink和Source,以便满足不同的业务需求。 自定义Sink可以用于将流式数据写入外部系统中,比如数据库、消息队列和文件系统等。Flink提供了一个简单的接口SinkFunction,通过实现该接口可以快速开发自己的Sink。 SinkFunction接口定义了一个抽象方法invoke(),该方法是在每个输入元素处理完成时被调用。开发者需要编写自己的业务逻辑,在invoke()中实现将数据写入目标系统的逻辑。 自定义Source可以用于从外部系统读取数据,并将其逐个交付给Flink程序进行处理。同样地,Flink也提供了一个简单的接口SourceFunction,通过实现该接口可以快速开发自己的Source。 SourceFunction接口定义了两个抽象方法:run()和cancel()。run()方法是在源自生命周期内调用的,它是源自执行主逻辑的地方。cancel()方法是用于清理资源的。开发者需要在run()方法中编写从外部系统读取数据的逻辑,并且能够异步地产生数据,最后将数据通过SourceContext将数据一条一条源源不断地输出。 自定义Sink和Source是Flink框架中非常常用的一个扩展方式,它可以满足用户自定义的需求,在具体的业务场景中,能够灵活的使用自定义Sink和Source对数据的处理进行个性化的定制化。同时,自定义Sink和Source的开发也相对简单,可以通过实现简单的接口,快速完成自定义Sink和Source的开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大数据架构师Pony

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

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

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

打赏作者

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

抵扣说明:

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

余额充值