官宣 | Fluss 0.6 发布公告
Fluss 社区很高兴地宣布 Fluss 0.6.0 版本正式发布。这一版本历时 3 个多月的密集开发,凝聚了全球 45 位贡献者的智慧与努力,累计完成 200+ 次代码提交 。衷心感谢每一位贡献者的支持!
此次版本的发布带来了诸多功能亮点:
-
列压缩:保留列裁剪性能的同时,降低6倍存储空间!
-
MergeEngine:新增灵活的主键数据合并策略,满足不同的实时处理场景需求。
-
Prefix Lookup:Delta Join 功能,Fluss 侧就绪!
这些新特性不仅大幅增强了 Fluss 的功能丰富性,也标志着我们在构建下一代分析型流存储的道路上迈出了坚实的一步。
01
列压缩
Fluss 默认采用 Apache Arrow 列存格式存储实时日志数据,并充分利用 Arrow 的流式列存特性,实现了高效的流式读取与列裁剪能力。Fluss 的列裁剪操作在服务端完成,并通过端到端的零拷贝(zero-copy)优化,无需将数据从磁盘加载到内存即可直接将所需的列数据发送至网络。这一设计不仅显著提升了性能,还大幅降低网络I/O成本,减少了资源开销。在 Fluss 之前的 基准测试 中,当裁剪掉 90% 的列时,Fluss 的读取吞吐量提升了 10 倍 ,充分展现了其在流式数据处理和传输方面的卓越表现。
列裁剪显著降低了网络 I/O 的成本,但磁盘存储成本仍然居高不下。为此,我们在本版本中引入了列压缩功能,支持 ZSTD 和 LZ4 两种高效压缩算法,能显著降低数据存储,从而大幅降低存储开销。由于压缩和解压都在客户端进行,因此减少了数据在网络中的传输量,网络I/O成本进一步得到降低。值得一提的是,压缩是针对每一列独立进行的,因此在启用压缩后,仍能保持原有的列裁剪性能,确保流读效率不受影响。
为了验证这一特性的实际效果,我们用淘宝的核心日志场景进行了基准测试。测试中,我们使用相同规模的数据集,相同资源的 Flink 作业,分别以无压缩和 ZSTD 压缩的方式写入 Fluss,并对比了写入吞吐量;随后从表中读取数据,测试了读取吞吐量。结果表明,列压缩不仅显著降低了6倍的存储量,吞吐也得到了一定提升。
而开启压缩后的 Flink 读写 CPU 与内存并未产生明显变化。
同时测试了在压缩数据上进行列裁剪读取的性能,可以看到随着裁剪列数的增多,仍然能够获得倍数的性能提升,保持了原有的列裁剪性能。
鉴于列压缩在通用场景均有显著的成本收益和性能提升,在 Fluss 0.6 版本中,日志表默认开启了 ZSTD 压缩,用户可以通过在表上设置 'table.log.arrow.compression.type'='NONE'
参数关闭。
02
Merge Engine
Fluss 在此版本中为主键表引入了全新的 Merge Engine 特性,以灵活地支持相同主键数据的合并策略。主键表默认的 Merge Engine 策略为保留每个主键对应的最新记录。用户也可以选择其他 Merge Engine,目前已经支持了 FirstRow Merge Engine 和 Versioned Merge Engine,并计划在之后的版本中支持 Aggregate Merge Engine。
FirstRow Merge Engine
通过在表属性中设置 'table.merge-engine' = 'first_row'
,用户可以为每个主键保留第一条记录。开启该配置的主键表,只会生成 append only 的变更日志,从而使下游的 Flink 作业在订阅该主键表时,能获得一个 append only 流,从而能应用一些不支持回撤(retraction)消息的算子,如 Window Aggregate,Interval Join等。该功能常用于替代在流式计算中的日志去重操作,并能有效降低成本和系统复杂性。
# 创建 first_row 主键表CREATE TABLE T ( k INT, v1 DOUBLE, v2 STRING, PRIMARY KEY (k) NOT ENFORCED) WITH ( 'table.merge-engine' = 'first_row');INSERT INTO T VALUES (1, 2.0, 't1');INSERT INTO T VALUES (1, 3.0, 't2');SELECT * FROM T WHERE k = 1;-- Output-- +---+-----+------+-- | k | v1 | v2 |-- +---+-----+------+-- | 1 | 2.0 | t1 |-- +---+-----+------+
Versioned Merge Engine
Versioned Merge Engine 支持基于版本号(或事件时间戳)进行数据的更新。它确保每个主键仅保留具有最高版本号(或事件时间戳)的记录行。该机制在去重或合并乱序数据时尤为有用,同时能够保证与上游数据源的最终一致性。这一功能在流式计算可用于替代 Rank 或 Deduplication(去重)操作,可以简化工作流程,并有效降低成本。
# 创建 versioned 主键表,指定 ts 为版本列CREATE TABLE VERSIONED ( a INT NOT NULL PRIMARY KEY NOT ENFORCED, b STRING, ts BIGINT ) WITH ( 'table.merge-engine' = 'versioned', 'table.merge-engine.versioned.ver-column' = 'ts');INSERT INTO VERSIONED (a, b, ts) VALUES (1, 'v1', 1000);-- 插入一条数据 ts < 1000, 该数据会被忽略INSERT INTO VERSIONED (a, b, ts) VALUES (1, 'v2', 999);SELECT * FROM VERSIONED WHERE a = 1;-- Output-- +---+-----+------+-- | a | b | ts |-- +---+-----+------+-- | 1 | v1 | 1000 |-- +---+-----+------+-- 插入一条数据 ts > 1000, 更新会被执行INSERT INTO VERSIONED (a, b, ts) VALUES (1, 'v3', 2000);SELECT * FROM VERSIONED WHERE a = 1;-- Output-- +---+-----+------+-- | a | b | ts |-- +---+-----+------+-- | 1 | v3 | 2000 |-- +---+-----+------+
03
Prefix Lookup for Delta Join
在 Flink 宽表构建场景中,通过 Delta Join 来优化双流 Join 是目前 Fluss 的一个主要使用场景,我们也将这部分功能贡献到了 0.6 版本中。Delta Join 可以简单理解成“双边驱动的维表 Join”,就是左边来了数据,就根据 Join Key 去点查右表;右边来了数据,就根据 Join Key 去点查左表。全程就像维表 Join 一样不需要state,但是实现了双流 Join 一样的语义,即任何一边有数据更新,都会触发对关联结果的更新。通过 Delta Join 解决大状态双流Join遇到的成本高、作业不稳定、Checkpoint超时、重启恢复慢等问题。
整体而言,Delta Join 依赖三个核心功能:
-
Source 表具备 CDC 流读功能:Fluss 的最基础能力
-
Source 表具备根据 Join Key 索引点查功能:Fluss 0.6 版本引入 Prefix Lookup 支持
-
Flink SQL 实现 Delta Join 算子: FLIP-486[1],预计规划在 Flink 2.1 版本中。
当 FLIP-486 完成后,用户便可通过如下 SQL 配合 Fluss Prefix Lookup 实现 Delta Join:
CREATE TABLE fluss_left_table ( a1 BIGINT, b1 BIGINT, c1 INT, d1 INT, PRIMARY KEY (c1,d1,a1) NOT ENFORCED -- 需要把 bucket key 定义为前缀) WITH ( 'bucket.key' = 'c1,d1' -- 需要手动指定 bucket key);CREATE TABLE fluss_right_table ( a2 BIGINT, b2 BIGINT, c2 INT, d2 INT, PRIMARY KEY (c2,d2,a2) NOT ENFORCED -- 需要把 bucket key 定义为前缀) WITH ( 'bucket.key' = 'c2,d2' -- 需要手动指定 bucket key);-- 将会优化成 delta join, 其中 join key 为两张表对应的 bucket keySELECT * FROM fluss_left_table INNER JOIN fluss_right_table ON c1 = c2 AND d1 = d2
Flink 通过 Join Key 来点查 Fluss 表,而 Join Key 是 Fluss 表的 Bucket Key,可以命中 Fluss 表的主键前缀索引,实现高效的索引查询,这个特性在 Fluss 中称为 Prefix Lookup。目前也可以使用 Prefix Lookup 来完成一对多的维表查询,具体可以查看 Prefix Lookup 文档[2]。
04
性能与稳定性
在本版本中,我们着重提升了系统的稳定性和性能,解决了 50 多个缺陷和改进,并对核心模块进行了深度优化。例如:
-
服务端优化 :通过引入延迟响应机制,显著降低了低流量场景下的 CPU 消耗,从而提升了资源利用效率。
-
客户端优化 :新增统一的内存管理机制,有效避免了高流量场景下的 OOM(内存溢出)问题,同时减少了垃圾回收(GC)对系统性能的影响。
这些改进显著增强了 Fluss 在高并发、大数据量场景下的可靠性与性能表现,使其能够更高效地应对分析型流存储任务的挑战。
05
湖流一体
在之前的版本中,Fluss 中的表如果需要启用湖流一体能力,则必须在建表时进行配置,否则后续只能通过删表重建的方式来实现。这是由于启用湖流一体功能会改变数据的 key 编码格式以及 bucket 分片策略,导致已存在的表无法直接兼容。
在新版本中,我们通过提前感知集群默认的湖存储格式,并统一采用湖格式的 key 编码和 bucket 分片策略,从而实现了在建表后动态开启湖流一体的能力,避免了删表重建的繁琐操作,提升了用户体验。此外,本版本还升级了对 Paimon 的依赖至最新的 1.0.1 版本。
06
Flink 集成
本版本在 Flink 连接器中新增了以下功能支持:
1. Sink 支持忽略回撤
主键表和日志表的 Sink 均新增了对 'sink.ignore-delete'
参数的支持,从而能够更好地适配包含回撤消息(retraction messages)的场景,满足更复杂的流式数据处理需求。
2. 分区表增强操作支持
分区表现在支持 ALTER TABLE ADD/DROP PARTITION
和 SHOW PARTITIONS
操作,进一步提升了分区管理的灵活性和易用性。
3. Sink 接口升级
将 SinkFunction
升级至 SinkV2
接口,为下一版本全面兼容 Flink 2.0 奠定了基础,确保系统在未来版本中的扩展性和兼容性。
07
升级注意事项
Fluss 社区尽可能保证升级的兼容性。但是,Fluss 0.5 升级到 0.6 是一个不兼容升级。我们将从 0.6 版本开始正式提供向后兼容的能力,以确保未来版本升级更加平滑和可靠。因此 0.6 版本是我们推荐使用和生态对接的版本。
08
后续规划
在下一版本中,我们将围绕以下核心功能展开研发,进一步提升 Fluss 的湖流一体能力、企业级能力、性能和稳定性,也欢迎大家在社区讨论和贡献:
-
全新的湖流一体架构
面向大规模生产环境设计的全新湖流一体架构,通过插件化支持多种主流湖格式(如 Iceberg、Hudi 等),解决 Tiering Service 在性能、扩展性和可运维性上的痛点,为企业级应用场景提供了更加可靠的湖流一体解决方案。
2. 认证与鉴权
引入插件化认证与和细粒度权限控制,满足企业对数据安全的严苛要求。
3. Kafka 兼容
兼容 Kafka 网络协议,支持无缝集成 Kafka 生态系统。
更多关于版本规划的细节,欢迎访问社区讨论页面[3]。欢迎大家的建议和贡献!
09
贡献者列表
Fluss 社区感谢对此版本做出贡献的每一位贡献者(按首字母排序):
Benchao Li, ForwardXu, Gang Yang, Georgios Andrianakis, Giannis Polyzos, Hongshun Wang, Jark Wu, Kerwin, Leonard Xu, LiJingwei, Liu Xiao, MehulBatra, Michael Koepf, Nicholas Jiang, Ron, RunningDB, Sagar Sumit, SeungMin, Shuo Cheng, Stan, SteNicholas, Tyrantlucifer, Vipamp, WangS-C, WenjunMin, Wenston Xin, Xiaojian Sun, Yang Guo, Yubin Li, Yuepeng Pan, Zmm, benjobs, gongzhongqiang, gyang94, jon-qj, luoyuxia, moses, psxjoy, wangwj, wudi, xiaozhou, yunhong, yuxia Luo, 码界探索, 道君
10
关于 Fluss
Fluss是面向实时分析设计的下一代流存储,现已正式开源,欢迎广大开发者关注和Star 🌟。
Tips:关注「Apache Flink」,回复 “Fluss”获取更多信息
官网:https://alibaba.github.io/fluss-docs 查看文档和试用
GitHub:https://github.com/alibaba/fluss 关注项目和参与社区,欢迎 star
[1]FLIP-486:https://cwiki.apache.org/confluence/display/FLINK/FLIP-486%3A+Introduce+A+New+DeltaJoin
[2]Prefix Lookup 文档:
https://alibaba.github.io/fluss-docs/docs/engine-flink/lookups/#prefix-lookup
[3]讨论页面:https://github.com/alibaba/fluss/discussions/556