Apache flink 通过阅读卡夫卡的详细信息创建动态flink窗口

Apache flink 通过阅读卡夫卡的详细信息创建动态flink窗口,apache-flink,flink-streaming,Apache Flink,Flink Streaming,假设Kafka消息包含flink窗口大小配置 我想阅读卡夫卡的信息,并在flink中创建一个全局窗口 问题陈述: 我们可以使用BroadcastStream处理上述场景吗 或 支持上述情况的任何其他方法?Flink的窗口API不支持动态更改窗口大小 您需要做的是使用process函数实现自己的窗口。在这种情况下,是KeyedBroadcastProcessFunction,其中窗口配置是广播的 您可以查看如何使用KeyedProcessFunction(复制如下)实现时间窗口的示例: 公共类伪窗

假设Kafka消息包含flink窗口大小配置

我想阅读卡夫卡的信息,并在flink中创建一个全局窗口

问题陈述:

我们可以使用BroadcastStream处理上述场景吗


支持上述情况的任何其他方法?

Flink的窗口API不支持动态更改窗口大小

您需要做的是使用process函数实现自己的窗口。在这种情况下,是KeyedBroadcastProcessFunction,其中窗口配置是广播的

您可以查看如何使用KeyedProcessFunction(复制如下)实现时间窗口的示例:

公共类伪窗口扩展了KeyedProcessFunction{
//键控的托管状态,每个窗口都有一个条目。
//每个传感器都有一个单独的MapState对象。
私有映射状态计数窗口;
布尔事件时间处理;
持续时间毫秒;
/**
*创建KeyedProcessFunction。
*@param eventTime是否使用事件时间处理
*@param durationMsec窗口长度
*/
公共伪窗口(布尔事件时间,int-durationMsec){
this.eventTimeProcessing=eventTime;
this.durationMsec=durationMsec;
}
@凌驾
公共无效打开(配置){
MapStateDescriptor countDesc=
新的MapStateDescriptor(“countInWindow”、Long.class、Integer.class);
countInWindow=getRuntimeContext().getMapState(countDesc);
}
@凌驾
公共无效处理元素(
KeyedDataPoint数据点,
上下文ctx,
收集器输出)抛出异常{
long endOfWindow=setTimer(数据点,ctx.timerService());
整数计数=countInWindow.get(endOfWindow);
如果(计数=null){
计数=0;
}
计数+=1;
countInWindow.put(endofindow,count);
}
公共长设置计时器(KeyedDataPoint数据点、TimerService TimerService){
长时间;
if(事件时间处理){
time=dataPoint.getTimeStamps();
}否则{
时间=System.currentTimeMillis();
}
long endOfWindow=(时间-(时间%durationMsec)+durationMsec-1);
if(事件时间处理){
timerService.RegisterEventTimer(endOfWindow);
}否则{
timerService.RegisterProcessingTimer(endOfWindow);
}
返回窗口;
}
@凌驾
公共void onTimer(长时间戳、OnTimerContext上下文、收集器输出)引发异常{
//获取此计时器的时间戳,并使用它查找该窗口的计数
long ts=context.timestamp();
KeyedDataPoint结果=新的KeyedDataPoint(context.getCurrentKey(),ts,countInWindow.get(ts));
收集(结果);
countInWindow.remove(时间戳);
}
} 

您是想在作业运行时更改窗口大小,还是只是根据配置消息从Kafka提供的数据初始化窗口。如果它包含新信息或与新窗口大小相同,则必须对其进行初始化,然后应在不重新启动的情况下更改窗口大小。
public class PseudoWindow extends KeyedProcessFunction<String, KeyedDataPoint<Double>, KeyedDataPoint<Integer>> {
    // Keyed, managed state, with an entry for each window.
    // There is a separate MapState object for each sensor.
    private MapState<Long, Integer> countInWindow;

    boolean eventTimeProcessing;
    int durationMsec;

    /**
     * Create the KeyedProcessFunction.
     * @param eventTime whether or not to use event time processing
     * @param durationMsec window length
     */
    public PseudoWindow(boolean eventTime, int durationMsec) {
        this.eventTimeProcessing = eventTime;
        this.durationMsec = durationMsec;
    }

    @Override
    public void open(Configuration config) {
        MapStateDescriptor<Long, Integer> countDesc =
                new MapStateDescriptor<>("countInWindow", Long.class, Integer.class);
        countInWindow = getRuntimeContext().getMapState(countDesc);
    }

    @Override
    public void processElement(
            KeyedDataPoint<Double> dataPoint,
            Context ctx,
            Collector<KeyedDataPoint<Integer>> out) throws Exception {

        long endOfWindow = setTimer(dataPoint, ctx.timerService());

        Integer count = countInWindow.get(endOfWindow);
        if (count == null) {
            count = 0;
        }
        count += 1;
        countInWindow.put(endOfWindow, count);
    }

    public long setTimer(KeyedDataPoint<Double> dataPoint, TimerService timerService) {
        long time;

        if (eventTimeProcessing) {
            time = dataPoint.getTimeStampMs();
        } else {
            time = System.currentTimeMillis();
        }
        long endOfWindow = (time - (time % durationMsec) + durationMsec - 1);

        if (eventTimeProcessing) {
            timerService.registerEventTimeTimer(endOfWindow);
        } else {
            timerService.registerProcessingTimeTimer(endOfWindow);
        }
        return endOfWindow;
    }

    @Override
    public void onTimer(long timestamp, OnTimerContext context, Collector<KeyedDataPoint<Integer>> out) throws Exception {
        // Get the timestamp for this timer and use it to look up the count for that window
        long ts = context.timestamp();
        KeyedDataPoint<Integer> result = new KeyedDataPoint<>(context.getCurrentKey(), ts, countInWindow.get(ts));
        out.collect(result);
        countInWindow.remove(timestamp);
    }
}