开发者社区> 问答> 正文

flink怎么计算当前月初至当前时间的数据?使用窗口貌似不能实现

现在有个需求是需要计算当前月初到当前时间之间的数据,现有窗口貌似都无法满足这个需求

展开
收起
游客b2gy4byxxtxs4 2020-10-26 15:17:54 1060 0
1 条回答
写回答
取消 提交回答
  • 下一站是幸福

    当我们在使用Flink的时候,避免不了要和时间(time)、水位线(watermarks)打交道,理解这些概念是开发分布式流处理应用的基础。那么Flink支持哪些时间语义?Flink是如何处理乱序事件的?什么是水位线?水位线是如何生成的?水位线的传播方式是什么?让我们带着这些问题来开始本文的内容。

    时间语义

    基本概念

    时间是Flink等流处理中最重要的概念之一,在 Flink 中 Time 可以分为三种:Event-Time,Processing-Time 以及 Ingestion-Time,如下图所示:

    Event Time

    事件时间,事件(Event)本身的时间,即数据流中事件实际发生的时间,通常使用事件发生时的时间戳来描述,这些事件的时间戳通常在进入流处理应用之前就已经存在了,事件时间反映了事件真实的发生时间。所以,基于事件时间的计算操作,其结果是具有确定性的,无论数据流的处理速度如何、事件到达算子的顺序是否会乱,最终生成的结果都是一样的。

    Ingestion Time

    摄入时间,事件进入Flink的时间,即将每一个事件在数据源算子的处理时间作为事件时间的时间戳,并自动生成水位线(watermarks,关于watermarks下文会详细分析)。

    Ingestion Time从概念上讲介于Event Time和Processing Time之间。与Processing Time相比 ,它的性能消耗更多一些,但结果却更可预测。由于 Ingestion Time使用稳定的时间戳(在数据源处分配了一次),因此对记录的不同窗口操作将引用相同的时间戳,而在Processing Time中每个窗口算子都可以将记录分配给不同的窗口。

    与Event Time相比,Ingestion Time无法处理任何乱序事件或迟到的数据,即无法提供确定的结果,但是程序不必指定如何生成水位线。在内部,Ingestion Time与Event Time非常相似,但是可以实现自动分配时间戳和自动生成水位线的功能。

    Processing Time

    处理时间,根据处理机器的系统时钟决定数据流当前的时间,即事件被处理时当前系统的时间。还以窗口算子为例(关于window,下文会详细分析),基于处理时间的窗口操作是以机器时间来进行触发的,由于数据到达窗口的速率不同,所以窗口算子中使用处理时间会导致不确定的结果。在使用处理时间时,无需等待水位线的到来后进行触发窗口,所以可以提供较低的延迟。

    对比

    经过上面的分析,应该对Flink的时间语义有了大致的了解。不知道你会不会有这样一个疑问:既然事件时间已经能够解决所有的问题了,那为何还要用处理时间呢?其实处理时间有其特定的使用场景,处理时间由于不用考虑事件的延迟与乱序,所以其处理数据的延迟较低。因此如果一些应用比较重视处理速度而非准确性,那么就可以使用处理时间,比如要实时监控仪表盘。总之,虽然处理时间的延迟较低,但是其结果具有不确定性,事件时间虽然有延迟,但是能够保证处理的结果具有准确性,并且可以处理延迟甚至无序的数据。

    使用

    上一小结讲述了三种时间语义的基本概念,接下来将从代码层面讲解在程序中该如何配置这三种时间语义。首先来看一段代码:

    /** The time characteristic that is used if none other is set. */

    private static final TimeCharacteristic DEFAULT_TIME_CHARACTERISTIC = TimeCharacteristic.ProcessingTime;

    //省略的代码

    /** The time characteristic used by the data streams. */

    private TimeCharacteristic timeCharacteristic = DEFAULT_TIME_CHARACTERISTIC;

    上述两行代码摘自StreamExecutionEnvironment类,可以看出,Flink在流处理程序中默认的时间语义是Processing Time,那么该如何修改默认的时间语义呢?很简单,再来看一段代码,下面的代码片段同样来自于StreamExecutionEnvironment类:

    /**

    • 如果使用Processing Time或者Event Time,默认的水位线间隔时间是200毫秒

    • 可以通过ExecutionConfig#setAutoWatermarkInterval(long)设置

    • @param characteristic The time characteristic.

    */

    @PublicEvolving

    public void setStreamTimeCharacteristic(TimeCharacteristic characteristic) {

    this.timeCharacteristic = Preconditions.checkNotNull(characteristic);

    if (characteristic == TimeCharacteristic.ProcessingTime) {

    getConfig().setAutoWatermarkInterval(0);

    } else {

    getConfig().setAutoWatermarkInterval(200);

    }

    }

    上述的方法可以配置不同的时间语义,参数TimeCharacteristic是一个枚举类,包括ProcessingTime,IngestionTime,EventTime三个元素。具体使用方式如下:

    //env.setStreamTimeCharacteristic(TimeCharacteristic.IngestionTime);

    //env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime); ———————————————— 协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_39533361/article/details/111743920

    2021-04-02 22:01:51
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Flink CDC Meetup PPT - 覃立辉 立即下载
Flink CDC Meetup PPT - 孙家宝 立即下载
Flink CDC Meetup PPT - 徐榜江 立即下载