Flink 源码剖析|数据流中的元素

本文详细介绍了ApacheFlink数据流中的StreamElement抽象类及其6个子类,包括StreamRecord、Watermark、WatermarkStatus、LatencyMarker、RecordAttributes和EndOfDataMarker。重点阐述了这些类的用途、属性和构造方法,展示了Flink对数据流处理和状态管理的核心组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在 Flink 的数据流中,所有元素均继承自 StreamElement 抽象类。该抽象类有 6 个子类,即 Flink 的数据流中有且仅有这 6 种类型的元素。

继承关系如下图:

Flink - UML - StreamElemenet

  • StreamRecord<T>:数据流中的存储数据的元素,包含一个 T 类型的值和一个可选择的时间戳。
  • Watermark:数据流中的 Watermark
  • WatermarkStatus:数据流状态标记,包含 WatermarkStatus#IDLEWatermarkStatus#ACTIVE 两种,用于标记数据流的空闲状态,告知下游算子是否需要等待这个数据流后续的 Watermark
  • LatencyMarker:延迟标记,用于端到端延迟追踪的指标统计,详见 《Flink 官方文档:Operations - 指标 - End-to-End latency tracking》
  • RecordAttributes:记录属性信息,提供用于优化作业的信息
  • EndOfDataMarker:数据流结束标记

1 StreamElement:数据流对象的抽象类(内部 API)

StreamElement 抽象类中,仅实现了检查实例是否为 5 种子类,以及将实例强转为 5 种子类的对象的方法,没有实现具体的方法。

源码Githuborg.apache.flink.streaming.runtime.streamrecord.StreamElement

@Internal
public abstract class StreamElement {

    public final boolean isWatermark() { return getClass() == Watermark.class; }
    public final boolean isWatermarkStatus() { return getClass() == WatermarkStatus.class; }
    public final boolean isRecord() { return getClass() == StreamRecord.class; }
    public final boolean isLatencyMarker() { return getClass() == LatencyMarker.class; }
    public final boolean isRecordAttributes() { return getClass() == RecordAttributes.class; }

    @SuppressWarnings("unchecked")
    public final <E> StreamRecord<E> asRecord() { return (StreamRecord<E>) this; }
    public final Watermark asWatermark() { return (Watermark) this; }
    public final WatermarkStatus asWatermarkStatus() { return (WatermarkStatus) this; }
    public final LatencyMarker asLatencyMarker() { return (LatencyMarker) this; }
    public final RecordAttributes asRecordAttributes() { return (RecordAttributes) this; }
}

2 StreamRecord<T>:数据流中的记录(内部 API)

StreamRecord 的对象属性中,包含一个 T 类型的值 value 和一个可供选择的 long 类型的 timestamp,以及标记该 timestamp 是否为空的布尔值 hasTimestamp

StreamRecord 有 2 个构造方法,一个是仅提供 T value 的构造方法,一个是提供 T value 和时间戳 timestamp 的构造方法。此外,提供了获取和更新 valuetimestamp 的方法。

源码Githuborg.apache.flink.streaming.runtime.streamrecord.StreamRecord(部分)

@Internal
public final class StreamRecord<T> extends StreamElement {

    private T value;
    private long timestamp;
    private boolean hasTimestamp;

    public StreamRecord(T value) {
        this.value = value;
    }

    public StreamRecord(T value, long timestamp) {
        this.value = value;
        this.timestamp = timestamp;
        this.hasTimestamp = true;
    }

    public T getValue() { return value; }

    public long getTimestamp() {
        if (hasTimestamp) {
            return timestamp;
        } else {
            return Long.MIN_VALUE;
        }
    }

    public boolean hasTimestamp() { return hasTimestamp; }

    @SuppressWarnings("unchecked")
    public <X> StreamRecord<X> replace(X element) {
        this.value = (T) element;
        return (StreamRecord<X>) this;
    }

    @SuppressWarnings("unchecked")
    public <X> StreamRecord<X> replace(X value, long timestamp) {
        this.timestamp = timestamp;
        this.value = (T) value;
        this.hasTimestamp = true;

        return (StreamRecord<X>) this;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
        this.hasTimestamp = true;
    }

    public void eraseTimestamp() {
        this.hasTimestamp = false;
    }
}

3 Watermark

Watermark 的对象属性中,只有一个 Watermark 标记的时间戳,与设置 Watermark 策略时的 org.apache.flink.api.common.eventtime.Watermark 一致,这个时间戳在构造方法中传入后即不可变。

源码Githuborg.apache.flink.api.common.eventtime.Watermark(部分)

@PublicEvolving
public final class Watermark extends StreamElement {

    private final long timestamp;

    public Watermark(long timestamp) {
        this.timestamp = timestamp;
    }

    public long getTimestamp() {
        return timestamp;
    }
}

4 WatermarkStatus:数据流状态(内部 API)

WatermarkStatus 用于标记数据流的空闲状态,避免空闲数据源影响下游算子的 Watermark 更新,具体介绍详见 “2.6 空闲数据源的处理”。而上游算子向下游算子通知数据流的空闲状态,则是通过发出 WatermarkStatus#IDLEWatermarkStatus#ACTIVE 来实现的。

源码Githuborg.apache.flink.streaming.runtime.watermarkstatus.WatermarkStatus

@Internal
public final class WatermarkStatus extends StreamElement {

    public static final int IDLE_STATUS = -1;
    public static final int ACTIVE_STATUS = 0;

    public static final WatermarkStatus IDLE = new WatermarkStatus(IDLE_STATUS);
    public static final WatermarkStatus ACTIVE = new WatermarkStatus(ACTIVE_STATUS);

    public final int status;

    public WatermarkStatus(int status) {
        if (status != IDLE_STATUS && status != ACTIVE_STATUS) {
            throw new IllegalArgumentException(
                    "Invalid status value for WatermarkStatus; "
                            + "allowed values are "
                            + ACTIVE_STATUS
                            + " (for ACTIVE) and "
                            + IDLE_STATUS
                            + " (for IDLE).");
        }

        this.status = status;
    }

    public boolean isIdle() {
        return this.status == IDLE_STATUS;
    }

    public boolean isActive() {
        return !isIdle();
    }

    public int getStatus() {
        return status;
    }
}

在实现上,通过类似枚举类的方式,使用静态常量 IDLEACTIVE 表示空闲状态和活跃状态的 WatermarkStatus 的对象。此外,提供了 isIdle() 方法和 isActive() 方法用于查询当前对象是标记空闲状态还是活跃状态。

参考文献

《Flink 官方文档:Operations - 指标:End-to-End latency tracking》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值