flink 1.10.1 java版本全量窗口apply计算案例

本文的基础环境可以参考flink 1.10.1 java版本wordcount演示 (nc + socket)

1. 窗口基本概念

窗口是将无界数据量划分为有界数据流的一种方式。

窗口类型按照窗口计算因子划分,包括时间窗口和事件窗口。

窗口类型按窗口计算方式包括滚动窗口,滑动窗口和会话窗口。

窗口计算采用左闭右开的方式。比如统计1秒以内的数据,则时间区间为[0,1000)毫秒,即包括0和999毫秒,不会包括1000毫秒。

2. Window API

window()方法必须在keyBy()之后才能使用。

时间窗口:timeWindow()

DataStream<Integer> resultStream = dataStream.keyBy("id")
        // 滑动窗口的简写方式
        .timeWindow(Time.seconds(15),Time.seconds(10))
        // 滚动窗口的简写方式
        // .timeWindow(Time.seconds(15))

事件窗口:countWindow()

3. 窗口函数

增量聚合函数:RuduceFunciton,AggregateFunction,只做计算,不输出结果;

全量聚合函数:ProcessWindowFunction,窗口关闭,执行计算并输出结果

取最小值

DataStream<Tuple2<String, Integer>> windowCounts = text
                .flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() {
                    @Override
                    public void flatMap(String value, Collector<Tuple2<String, Integer>> out) {
                        for (String word : value.split("\\s")) {
                            out.collect(Tuple2.of(word, 1));
                        }
                    }
                })
                .keyBy(0)
                .timeWindow(Time.seconds(5))
                .minBy(1);

求和

DataStream<Tuple2<String, Integer>> windowCounts = text
                .flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() {
                    @Override
                    public void flatMap(String value, Collector<Tuple2<String, Integer>> out) {
                        for (String word : value.split("\\s")) {
                            out.collect(Tuple2.of(word, 1));
                        }
                    }
                })
                .keyBy(0)
                .timeWindow(Time.seconds(5))
                .sum(1);

.trigger() 触发器,定义window关闭,触发计算并输出结果。

4. 窗口计算案例代码

package com.demo.window;

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.java.tuple.Tuple;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.api.java.tuple.Tuple3;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.windowing.WindowFunction;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
import org.apache.flink.util.Collector;

import java.util.Iterator;

public class FlinkWindowDemo {

    public static void main(String[] args) throws Exception {

        StreamExecutionEnvironment env = StreamExecutionEnvironment.createLocalEnvironmentWithWebUI(new Configuration());
        // 此处数据源是的 Linux 主机,通过 socket 的方式传输数据
        DataStreamSource<String> socketStream = env.socketTextStream("192.168.0.181", 9000, "\n");

        DataStream<String> flatMap = socketStream.flatMap(new FlatMapFunction<String, String>() {
            @Override
            public void flatMap(String value, Collector<String> out) throws Exception {
                String[] strings = value.split(" ");
                for (String s : strings) {
                    out.collect(s);
                }
            }
        });
        DataStream<Tuple2<String, Integer>> map = flatMap.map(new MapFunction<String, Tuple2<String, Integer>>() {
            @Override
            public Tuple2<String, Integer> map(String value) throws Exception {
                return Tuple2.of(value, 1);
            }
        });


//        DataStream<Tuple2<String, Integer>> sum = map
//                .keyBy("f0")
//                .timeWindow(Time.seconds(10))
//                .sum(1);
//
//        sum.print();

        // 全窗口函数,窗口统计数据的同时,输出窗口结束时间
        DataStream<Tuple3<String, Integer, Long>> windowsum= map
                .keyBy("f0")
                .timeWindow(Time.seconds(60))

                .apply(new WindowFunction<Tuple2<String, Integer>, Tuple3<String, Integer, Long>, Tuple, TimeWindow>() {
                    @Override
                    public void apply(Tuple tuple, TimeWindow timeWindow, Iterable<Tuple2<String, Integer>> iterable, Collector<Tuple3<String, Integer,Long>> collector) throws Exception {
                        Iterator<Tuple2<String, Integer>> iterator = iterable.iterator();
                        Integer sum = 0;
                        Long windowEnd = timeWindow.getEnd();

                        while (iterator.hasNext())
                        {
                            Tuple2<String, Integer> next = iterator.next();
                            sum = sum + next.f1;
                        }

                        collector.collect(new Tuple3<>(tuple.getField(0), sum, windowEnd));
                    }
                });

        windowsum.print();

        env.execute();
    }
}

5. 执行测试

在nc输出如下的测试数据:

[root@bogon ~]# nc -l 9000
hello world
hello flink
hello window
timewindow

可以在控制台看到类似如下输出。

3> (hello,3,1644545760000)
7> (flink,1,1644545760000)
1> (timewindow,1,1644545760000)
5> (world,1,1644545760000)
3> (window,1,1644545760000)

在输出数据中,可以看到输出数据的同时,还给出了窗口结束时间,单位是毫秒。

只有在窗口关闭以后,才会进行计算,并输出计算结果。当没有数据时,不会开启窗口,也就不会进行相应的计算了。

为了测试,这里设置了一个60秒的滚动窗口。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flink CDC(Change Data Capture)是 Flink 社区提供的一种用于捕获和处理数据库变更的功能。全量同步是指将源数据库中的所有数据同步到目标数据库中,下面是使用 Flink CDC 实现全量同步的一般步骤: 1. 配置源数据库连接:使用 Flink CDC,您需要配置源数据库的连接信息,包括数据库类型、主机地址、端口号、用户名和密码等。 2. 创建 Flink CDC 源:使用 Flink CDC 的 API,您可以创建一个 CDC 源,指定要捕获变更的数据库和表。 3. 定义目标数据库表结构:在目标数据库中创建与源表相同的表结构,确保目标表与源表具有相同的列和数据类型。 4. 实现数据转换逻辑:根据业务需求,您可能需要对源数据进行一些转换操作,例如数据过滤、字段映射、数据格式转换等。 5. 启动 Flink 作业:将上述配置和逻辑应用到 Flink 作业中,并启动作业来执行全量同步操作。 6. 监控同步进度:通过监控 Flink 作业的状态和日志,可以了解同步进度和可能的错误信息。 需要注意的是,Flink CDC 是一个基于事件时间的流处理框架,它可以实时捕获和处理数据变更。全量同步可能需要较长时间来完成,具体取决于源数据库的数据量和网络传输速度等因素。 此外,Flink CDC 还支持增量同步,可以根据数据库的变更进行实时同步。增量同步可以实现更低的延迟,并且可以处理源数据库中的更新、插入和删除操作。 以上是使用 Flink CDC 实现全量同步的一般步骤,具体实现方式可能因环境和需求而异,请根据您的具体情况进行调整和实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值