Flink类型系统的根及基本接口

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
简介: 之前我们谈到了Flink通过自主管理内存的方式来,避免了让JVM管理内存带来的一些问题。自主管理内存之后,JVM中原生的类型也就不适合使用了。因此Flink也对Java的类型进行了扩展,这就是我们本节关注的内容。

之前我们谈到了Flink通过自主管理内存的方式来,避免了让JVM管理内存带来的一些问题。自主管理内存之后,JVM中原生的类型也就不适合使用了。因此Flink也对Java的类型进行了扩展,这就是我们本节关注的内容。

本节探讨的相关类主要位于包:org.apache.flink.types

类型的根Value

Value位于所有类型的继承链的最顶端,可以说是所有类型的根。它代指所有可被序列化为Flink二进制表示的类型。该接口本身并不提供任何接口方法,但它继承自两个接口。下图是它的继承关系图:

Value继承关系图

从上图可以看出任何实现了Value接口的特定类型,都需要满足Value继承的两个接口的契约:

  • Serializable :标记实现该接口的类可被序列化
  • IOReadableWritable :Flink核心IO包种的接口,实现该接口用于将类的实例序列化为二进制的表示形式

IOReadableWritable提供了读写数据的write/read方法,另外IOReadableWritable对接口的实现者的一个要求是其必须有一个默认的(无参)构造器。

容器类型ListValue和MapValue

Value下,Flink直接提供了两个抽象的容器类型:ListValueMapValue。它们都有几个共同点:

  • 容器中存储的元素的类型都是Value类型(通过泛型类型约束)
  • 容器类型自身也实现了Value,也即自身也可被序列化
  • 都实现了JDK Java集合框架中各自的接口(ListMap

关于上面的第三点,Flink其实采用的是装饰器模式。比如,我们拿MapValue来举例:

MapValue类型继承关系图

它内部有一个map字段,该字段的初始化可能来自从构造方法传入的外部被装饰的Map实例,也可能是从无参构造方法中直接实例化的Map实例。而MapValue中实现的Map接口的方法,大都通过调用map的实例方法实现。ListValue的做法类似,不再赘述。

值得一提的是,它们对IOReadableWritableread/write方法的实现。

我们先来看一下read方法的实现:

public void read(final DataInputView in) throws IOException {
    int size = in.readInt();
    this.map.clear();

    try {
        for (; size > 0; size--) {
            final K key = this.keyClass.newInstance();
            final V val = this.valueClass.newInstance();
            key.read(in);
            val.read(in);
            this.map.put(key, val);
        }
    } catch (final InstantiationException | IllegalAccessException e) {
        throw new RuntimeException(e);
    }
}

它首先读取一个整型值size,该整型值表示的是元素对的个数。然后循环读取每个keyvalue同时反序列化之后将其加入内部的map中。

write方法的实现,则是序列化每个元素的过程:

public void write(final DataOutputView out) throws IOException {
        out.writeInt(this.map.size());
        for (final Entry<K, V> entry : this.map.entrySet()) {
            entry.getKey().write(out);
            entry.getValue().write(out);
        }
    }

当然,也是将mapsize先写入二进制结果的头部。结构示意如下图:

MapValue二进制结构
下面会我们来看所有具体的类型需要实现的三个接口。

基本类型实现的接口

ResettableValue接口

该接口提供了一个方法:

void setValue(T value);

用于将一个外部的value赋值给内部的同类型的对象。

CopyableValue接口

该接口提供一些拷贝方法以方便基本类型的拷贝。其类图如下:

CopyValue类继承关系图

接口方法中,值得关注的是三个copy相关的方法。前两个:copyTocopy都必须提供深拷贝的实现。而最后一个copy方法,提供在Flink的二进制表示层面上的拷贝(等价于对IOReadableWritableread以及write的先后调用,但这里copy方法的优势是,中间不需要进行反序列化的过程)。

NormalizableKey接口

该接口指定了实现规范化的键(normalizable key)需要满足的契约。先来解释一下什么叫作“规范化的键”,规范化的键指一种在二进制表示的方式下可以进行逐字节比较的键。而要使两个规范化的键能够比较,首先对于同一种类型,它们的最大字节长度要是相等的。对于这个条件,通过接口方法getMaxNormalizedKeyLen来定义。它针对一种类型通常都会返回一个常数值。比如对于32位的整型,它会返回常数值4。但一个规范化的键所占用的字节数不一定要跟该类型的最大字节数相等。当它比规定的最大的字节数小时,可以认为它只是该规范化键的一种“前缀”。

两个规范化的键进行比较,但满足两个条件的其中之一后会停止:

  • 所有的字节都比较完成
  • 两个相同位置的字节不相等

关于比较的结果,如果在相同的位置,两个字节的值不相等则值小的一个键被认为其整个键会小于另外一个键。

除此之外该接口还提供了将实现类型的值(规范化的键)写入给定的目标字节数组中去的方法。

void copyNormalizedKey(MemorySegment memory, int offset, int len);

对于该接口,值得一提的是,如果真正需要写入的字节数小于给定的len,那么它将会被填充一些特定的字符以进行补齐。

NormalizableKey接口直接继承自Key接口,Key用来使得一个类型可以作为键以建立跟值之间的关系。并且键Key要求是可被比较的,因为它实现了Comparable接口。目前Key接口被标记为“Deprecated”的,在未来的版本中可能会被废弃。



原文发布时间为:2016-07-09


本文作者:vinoYang


本文来自云栖社区合作伙伴CSDN博客,了解相关信息可以关注CSDN博客。

相关实践学习
基于Hologres+Flink搭建GitHub实时数据大屏
通过使用Flink、Hologres构建实时数仓,并通过Hologres对接BI分析工具(以DataV为例),实现海量数据实时分析.
实时计算 Flink 实战课程
如何使用实时计算 Flink 搞定数据处理难题?实时计算 Flink 极客训练营产品、技术专家齐上阵,从开源 Flink功能介绍到实时计算 Flink 优势详解,现场实操,5天即可上手! 欢迎开通实时计算 Flink 版: https://cn.aliyun.com/product/bigdata/sc Flink Forward Asia 介绍: Flink Forward 是由 Apache 官方授权,Apache Flink Community China 支持的会议,通过参会不仅可以了解到 Flink 社区的最新动态和发展计划,还可以了解到国内外一线大厂围绕 Flink 生态的生产实践经验,是 Flink 开发者和使用者不可错过的盛会。 去年经过品牌升级后的 Flink Forward Asia 吸引了超过2000人线下参与,一举成为国内最大的 Apache 顶级项目会议。结合2020年的特殊情况,Flink Forward Asia 2020 将在12月26日以线上峰会的形式与大家见面。
目录
相关文章
|
消息中间件 存储 Kafka
实时计算 Flink版产品使用问题之通过flink同步kafka数据进到doris,decimal数值类型的在kafka是正常显示数值,但是同步到doris表之后数据就变成了整数,该如何处理
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
3月前
|
Java 调度 流计算
基于Java 17 + Spring Boot 3.2 + Flink 1.18的智慧实验室管理系统核心代码
这是一套基于Java 17、Spring Boot 3.2和Flink 1.18开发的智慧实验室管理系统核心代码。系统涵盖多协议设备接入(支持OPC UA、MQTT等12种工业协议)、实时异常检测(Flink流处理引擎实现设备状态监控)、强化学习调度(Q-Learning算法优化资源分配)、三维可视化(JavaFX与WebGL渲染实验室空间)、微服务架构(Spring Cloud构建分布式体系)及数据湖建设(Spark构建实验室数据仓库)。实际应用中,该系统显著提升了设备调度效率(响应时间从46分钟降至9秒)、设备利用率(从41%提升至89%),并大幅减少实验准备时间和维护成本。
218 0
|
11月前
|
SQL 消息中间件 分布式计算
大数据-124 - Flink State 01篇 状态原理和原理剖析:状态类型 执行分析
大数据-124 - Flink State 01篇 状态原理和原理剖析:状态类型 执行分析
202 5
|
消息中间件 监控 数据挖掘
基于RabbitMQ与Apache Flink构建实时分析系统
【8月更文第28天】本文将介绍如何利用RabbitMQ作为数据源,结合Apache Flink进行实时数据分析。我们将构建一个简单的实时分析系统,该系统能够接收来自不同来源的数据,对数据进行实时处理,并将结果输出到另一个队列或存储系统中。
848 2
|
11月前
|
消息中间件 NoSQL Kafka
大数据-116 - Flink DataStream Sink 原理、概念、常见Sink类型 配置与使用 附带案例1:消费Kafka写到Redis
大数据-116 - Flink DataStream Sink 原理、概念、常见Sink类型 配置与使用 附带案例1:消费Kafka写到Redis
617 0
|
调度 流计算
Flink 新一代流计算和容错问题之Flink 中的数据可以分为什么类型
Flink 新一代流计算和容错问题之Flink 中的数据可以分为什么类型
|
消息中间件 存储 算法
联通实时计算平台问题之亿级标签关联实现且不依赖外部系统要如何操作
联通实时计算平台问题之亿级标签关联实现且不依赖外部系统要如何操作
|
消息中间件 Kafka 数据处理
Kafka与Flink:构建高性能实时数据处理系统的实践指南
Apache Kafka 和 Apache Flink 的结合为构建高性能的实时数据处理系统提供了坚实的基础。通过合理的架构设计和参数配置,可以实现低延迟、高吞吐量的数据流处理。无论是在电商、金融、物流还是其他行业,这种组合都能为企业带来巨大的价值。
|
SQL Java 数据库
实时计算 Flink版产品使用问题之Spring Boot集成Flink可以通过什么方式实现通过接口启动和关闭Flink程序
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
分布式计算 Oracle 关系型数据库
实时计算 Flink版产品使用问题之获取Oracle的数据时无法获取clob类型的数据,该怎么办
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。

热门文章

最新文章