Apache flink 弗林克计数法

Apache flink 弗林克计数法,apache-flink,flink-cep,flink-sql,Apache Flink,Flink Cep,Flink Sql,现在我们使用翻滚窗口来计算不同。我们面临的问题是,如果我们把翻滚窗口从一天延长到一个月,我们就无法得到目前为止的数字。这意味着,如果我们将翻滚窗口设置为1个月,那么我们得到的数字是每个月的第1个。如何获取当前的不同计数(现在是3月9日) 包flink.trigger; 导入org.apache.flink.api.common.state.ReducingState; 导入org.apache.flink.api.common.state.ReduceingStateDescriptor; 导入

现在我们使用翻滚窗口来计算不同。我们面临的问题是,如果我们把翻滚窗口从一天延长到一个月,我们就无法得到目前为止的数字。这意味着,如果我们将翻滚窗口设置为1个月,那么我们得到的数字是每个月的第1个。如何获取当前的不同计数(现在是3月9日)

包flink.trigger;
导入org.apache.flink.api.common.state.ReducingState;
导入org.apache.flink.api.common.state.ReduceingStateDescriptor;
导入org.apache.flink.api.common.typeutils.base.LongSerializer;
导入org.apache.flink.streaming.api.windowing.triggers.Trigger;
导入org.apache.flink.streaming.api.windowing.triggers.TriggerResult;
导入org.apache.flink.streaming.api.windowing.windows.TimeWindow;
导入java.text.simpleDataFormat;
导入java.util.Date;
公共类CustomCountDistingTTigger扩展触发器{
私有最终还原状态描述符时间状态=
新的ReduceingStateDescriptor(“点火间隔”,新的DistinctCountAggregateFunction(),LongSerializer.INSTANCE);
私人长间隔;
公共CustomCountDistingTTigger(长间隔){
这个。间隔=间隔;
}
@凌驾
公共TriggerResult OneElement(对象元素、长时间戳、时间窗口、TriggerContext ctx)引发异常{
ReduceingState fireTimestamp=ctx.getPartitionedState(timeState);
timestamp=ctx.getCurrentProcessingTime();
if(fireTimestamp.get()==null){
长启动=时间戳-(时间戳%间隔);
long nextFireTimestamp=开始+间隔;
ctx.RegisterProcessingTimer(nextFireTimestamp);
firetimstamp.add(nextfiretimstamp);
返回TriggerResult.CONTINUE;
}
返回TriggerResult.CONTINUE;
}
@凌驾
public TriggerResult on ProcessingTime(长时间、时间窗口、TriggerContext ctx)引发异常{
//System.out.println(“在“+System.currentTimeMillis()处调用的onProcessingTime”);
//返回TriggerResult.FIRE\u和\u PURGE;
SimpleDataFormat df=新的SimpleDataFormat(“yyyy-MM-dd HH:MM:ss”);
System.out.println(df.format(new Date());
//间歇
ReduceingState fireTimestamp=ctx.getPartitionedState(timeState);
if(window.maxTimestamp()=时间){
返回TriggerResult.FIRE\u和\u PURGE;
}
else if(firetimstamp.get().equals(time)){
firetimstamp.clear();
firetimstamp.add(时间+间隔);
ctx.RegisterProcessingTimer(时间+间隔);
返回TriggerResult.FIRE;
}
返回TriggerResult.CONTINUE;
}
@凌驾
public TriggerResult onEventTime(长时间、时间窗口、TriggerContext ctx)引发异常{
返回TriggerResult.CONTINUE;
}
@凌驾
公共无效清除(时间窗口、TriggerContext ctx)引发异常{
}
}
不同计数:
DataStreamSink finalResultStream=keyedStream
.flatMap(新的KPIDistinctDataFlatmap函数(inputSchema))
.map(新SwapMap())
.keyBy(新的WordKeySelector())
.window(TumblingProcessingTimeWindows.of(org.apache.flink.streaming.api.windowing.time.time.minutes(5)))
.触发器(新的CustomCountDistingTTigger(1*60*6000))
.aggregate(新的DistinctCountAggregateFunction())
.打印(“最终打印”);

您可以定义一个自定义触发器,该触发器每天返回一次FIRE以触发中间结果,然后在月末执行FIRE\u和\u清除以关闭窗口

每次触发器返回激发时,通过调用
ProcessWindowFunction
process()
方法来评估窗口,此时它可以使用提供的
收集器生成结果。FIRE_和_PURGE最后一次计算窗口,然后将其销毁


另请参阅此问题的答案————其中涉及相关主题。

您的解决方案仍然存在问题。请你核对一下我上面的问题好吗?我们使用表窗口来处理计数。解决方案触发器来自StreamExecutionEnvironment,它可以有一个触发器。但是StreamTableEnvironment没有触发器。对吗?我没有看到使用表API或SQL的解决方案。嗨,David,我在实现自定义触发器时遇到了一个问题。虽然卡夫卡没有任何事件。它不会触发distinctcount?上面的代码示例是针对窗口5分钟和每分钟触发一次distinct count。Flink中没有空窗口。当第一个事件被分配给窗口时,窗口被实例化。所以,没有事件,没有窗口。没有窗口,没有触发器。没有触发器,没有表明窗口为空的结果。确定。所以我可以为中间结果创建状态。如果没有触发,如何在计时器(例如每日)上获得中间结果?
package flink.trigger;

import org.apache.flink.api.common.state.ReducingState;
import org.apache.flink.api.common.state.ReducingStateDescriptor;
import org.apache.flink.api.common.typeutils.base.LongSerializer;
import org.apache.flink.streaming.api.windowing.triggers.Trigger;
import org.apache.flink.streaming.api.windowing.triggers.TriggerResult;
import org.apache.flink.streaming.api.windowing.windows.TimeWindow;

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

public class CustomCountDistinctTigger extends Trigger<Object, TimeWindow> {

    private final ReducingStateDescriptor<Long> timeState =
            new ReducingStateDescriptor<>("fire-interval", new DistinctCountAggregateFunction(), LongSerializer.INSTANCE);
    private long interval;


    public CustomCountDistinctTigger(long interval) {
        this.interval = interval;
    }

    @Override
    public TriggerResult onElement(Object element, long timestamp, TimeWindow window, TriggerContext ctx) throws Exception {
        ReducingState<Long> fireTimestamp = ctx.getPartitionedState(timeState);

        timestamp = ctx.getCurrentProcessingTime();

        if (fireTimestamp.get() == null) {
            long start = timestamp - (timestamp % interval);
            long nextFireTimestamp = start + interval;
            ctx.registerProcessingTimeTimer(nextFireTimestamp);
            fireTimestamp.add(nextFireTimestamp);
            return TriggerResult.CONTINUE;
        }
        return TriggerResult.CONTINUE;
    }

    @Override
    public TriggerResult onProcessingTime(long time, TimeWindow window, TriggerContext ctx) throws Exception {
//        System.out.println("onProcessingTime called at "+System.currentTimeMillis() );
//        return TriggerResult.FIRE_AND_PURGE;
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(df.format(new Date()));
        //interval
        ReducingState<Long> fireTimestamp = ctx.getPartitionedState(timeState);

        if(window.maxTimestamp() == time) {
            return TriggerResult.FIRE_AND_PURGE;
        }
        else if (fireTimestamp.get().equals(time)) {
            fireTimestamp.clear();
            fireTimestamp.add(time + interval);
            ctx.registerProcessingTimeTimer(time + interval);
            return TriggerResult.FIRE;
        }
        return TriggerResult.CONTINUE;
    }

    @Override
    public TriggerResult onEventTime(long time, TimeWindow window, TriggerContext ctx) throws Exception {
        return TriggerResult.CONTINUE;
    }

    @Override
    public void clear(TimeWindow window, TriggerContext ctx) throws Exception {

    }

}


distinct count:
DataStreamSink<Tuple2<String, Integer>> finalResultStream = keyedStream
                            .flatMap(new KPIDistinctDataFlatMapFunction(inputSchema))
                            .map(new SwapMap())
                            .keyBy(new WordKeySelector())
                            .window(TumblingProcessingTimeWindows.of(org.apache.flink.streaming.api.windowing.time.Time.minutes(5)))
                            .trigger(new CustomCountDistinctTigger(1 * 60 * 6000))
                            .aggregate(new DistinctCountAggregateFunction())
                            .print("final print");