• Flink


    WindowOperator

    processElement

    final Collection<W> elementWindows = windowAssigner.assignWindows(   //找出该element被assign的所有windows
        element.getValue(), element.getTimestamp(), windowAssignerContext);
    
    //if element is handled by none of assigned elementWindows
    boolean isSkippedElement = true;  //element默认是会skiped
    
    
    for (W window: elementWindows) {
    
        // drop if the window is already late
        if (isWindowLate(window)) { //如果window是late,逻辑是window.maxTimestamp() + allowedLateness <= internalTimerService.currentWatermark(),continue表示skip
            continue;
        }
        isSkippedElement = false; //只要有一个窗口非late,该element就是非late数据
    
        windowState.setCurrentNamespace(window); 
        windowState.add(element.getValue()); //把数据加到windowState中
    
        triggerContext.key = key;
        triggerContext.window = window;
    
        //EventTimeTrigger,(window.maxTimestamp() <= ctx.getCurrentWatermark(),会立即fire
        //否则只是ctx.registerEventTimeTimer(window.maxTimestamp()),注册等待后续watermark来触发
        TriggerResult triggerResult = triggerContext.onElement(element); 
    
        if (triggerResult.isFire()) { //如果Fire
            ACC contents = windowState.get();
            if (contents == null) {
                continue;
            }
            emitWindowContents(window, contents); //emit window内容, 这里会调用自己定义的user function
        }
    
        //对于比较常用的TumblingEventTimeWindows,用EventTimeTrigger,所以是不会触发purge的
        if (triggerResult.isPurge()) { //如果purge
            windowState.clear();  //将window的state清除掉
        }
        registerCleanupTimer(window); //window的数据也需要清除
    }
    
    
    // side output input event if
    // element not handled by any window
    // late arriving tag has been set
    // windowAssigner is event time and current timestamp + allowed lateness no less than element timestamp
    //如果所有的assign window都是late,再判断一下element也是late
    if (isSkippedElement && isElementLate(element)) { //isElementLate, (element.getTimestamp() + allowedLateness <= internalTimerService.currentWatermark())
        if (lateDataOutputTag != null){
            sideOutput(element); //如果定义了sideOutput,就输出late element
        } else {
            this.numLateRecordsDropped.inc(); //否则直接丢弃
        }
    }

    这里currentWatermark的默认值,
    private long currentWatermark = Long.MIN_VALUE;

    如果定期发送watermark,那么在第一次收到watermark前,不会有late数据
    
    
    继续看看,数据清除掉逻辑
    protected void registerCleanupTimer(W window) {
        long cleanupTime = cleanupTime(window); //cleanupTime, window.maxTimestamp() + allowedLateness
    
        if (windowAssigner.isEventTime()) {
            triggerContext.registerEventTimeTimer(cleanupTime); //这里只是简单的注册registerEventTimeTimer
        } else {
            triggerContext.registerProcessingTimeTimer(cleanupTime);
        }
    }

    如果clear只是简单的注册EventTimeTimer,那么在onEventTime的时候一定有clear的逻辑、

    WindowOperator.onEventTime

    if (windowAssigner.isEventTime() && isCleanupTime(triggerContext.window, timer.getTimestamp())) {  //time == cleanupTime(window);
        clearAllState(triggerContext.window, windowState, mergingWindows);
    }

    果然,onEventTime的时候会判断,如果Timer的time等于 window的cleanup time,就把all state清除掉

    所以当超过,window.maxTimestamp() + allowedLateness就会被清理掉

  • 相关阅读:
    RTSP/Onvif协议EasyNVR平台文字过长则显示文字title的组件开发及使用【附代码】
    okadmin框架,第八天角色列表
    okadmin框架,第六天用户删除
    okadmin框架,第十天角色编辑
    linux 查看内存使用率
    okadmin框架,第七天菜单列表
    okadmin框架,第五天用户更新
    okadmin框架,第三天用户列表
    okadmin框架,第四天用户新增
    okadmin框架,第二天系统主页
  • 原文地址:https://www.cnblogs.com/fxjwind/p/7760798.html
Copyright © 2020-2023  润新知