一、引言
传统实时数据平台往往由多套系统拼接而成:Kafka 负责事件传输,Flink 负责流计算,Redis 或 Mysql 承接在线查询,Iceberg/Paimon/Hudi 负责离线湖仓,额外的同步链路维持各系统之间的数据一致性,这类架构可称为"multiple-systems tax",每个系统边界都会成为数据漂移和工程维护成本的来源。
这种问题在大数据工程里很常见。一个订单事件从 Kafka 进入 Flink 后,可能要写入明细宽表、写入 Redis 做实时查询、写入 Iceberg 做离线分析、再写入特征平台供模型使用。链路越长,越容易出现延迟不一致、Schema 演进困难、重放成本高、历史与实时口径不一致等问题。
Apache Fluss的定位正是填补这条缝隙:它是一个开源的、湖仓原生的流式存储系统,可将消息队列、在线 KV、流处理状态后端与湖仓冷存储收敛到一个统一基础设施中,用于实时分析与 AI 场景。Fluss上层对接 Flink、Spark 等计算引擎,下层对接 Apache Paimon、Apache Iceberg、Lance 等湖仓存储,在中间提供低延迟写入、流式读取、主键查询、变更日志和分层存储能力。
可以把它理解为实时数据进入湖仓之前的"热数据层"。热层负责承接高频写入、更新、查询和增量消费,冷层负责长期留存、批分析和开放生态查询。

二、Fluss核心架构
Fluss 集群主要由两个核心进程组成:CoordinatorServer 和 TabletServer。CoordinatorServer 负责元数据维护、Tablet 分配、节点列表、权限、扩缩容重平衡、故障时的数据迁移和服务节点切换;TabletServer 负责数据存储、持久化和面向用户的 I/O 服务。
在 TabletServer 内部,最关键的是两类存储组件:LogStore 与 KvStore。PrimaryKey Table 同时启用 LogStore 和 KvStore,其中 KvStore 用于高效更新与点查,LogStore 用于保存表的 changelog;Log Table 只启用 LogStore,适合仅追加的高吞吐写入场景。
Fluss 还依赖 ZooKeeper 做集群协调、元数据存储和集群配置管理,未来版本计划用 KvStore 存储元数据,并通过 Raft 做集群协调与一致性保障。

三、表模型
Fluss 的表模型可以先抓住两类:Log Table 和 PrimaryKey Table。Log Table 不声明主键,只支持 append,不支持 update/delete,适合日志、事件流、点击流等高吞吐追加写入。
PrimaryKey Table 通过 PRIMARY KEY 声明主键,保证主键唯一,支持 INSERT、UPDATE、DELETE。如果向同一主键写入多条数据,Fluss PrimaryKey Table 会保留最后一条记录;它还支持部分列更新、Lookup、Prefix Lookup 和 Changelog 生成。
| 表类型 | 是否有主键 | 写入语义 | 典型能力 | 适用场景 |
|---|---|---|---|---|
| Log Table | 否 | Append-only | 顺序追加、流式消费、列裁剪、压缩、Log Tiering | 行为日志、点击流、IoT 事件、CDC 原始流 |
| PrimaryKey Table | 是 | Insert/Update/Delete | 主键点查、部分更新、Changelog、Merge Engine | 维表、实时宽表、用户画像、订单状态、特征表 |
这个表模型的意义在于:一套系统同时覆盖了"流"和"表"。Log Table 更像事件流,PrimaryKey Table 更像可更新的实时状态表。
less
Log Table:
+I -> +I -> +I -> +I
只追加,适合事件流
PrimaryKey Table:
k=1, v=A
k=1, v=B
k=1 被更新为 B
适合状态表、维表、特征表
四、读写与查询机制
Fluss 的 LogStore 类似数据库 binlog,消息只能追加,不能修改,主要用于低延迟 streaming read,同时也作为恢复 KvStore 的 WAL。KvStore 则类似数据库表,支持更新和删除,并生成 changelog 来追踪数据变化。
sql
CREATE CATALOG fluss_catalog WITH (
'type' = 'fluss',
'bootstrap.servers' = 'coordinator-server:9123'
);
USE CATALOG fluss_catalog;
CREATE TABLE fluss_customer (
`cust_key` INT NOT NULL,
`name` STRING,
`phone` STRING,
`nation_key` INT NOT NULL,
PRIMARY KEY (`cust_key`) NOT ENFORCED
);
对于实时维表 Join,Fluss 的价值比较直观。Flink 流作业可以把 Fluss PrimaryKey Table 当成维表,通过主键 Lookup 获取最新维度值,这类场景过去往往依赖外部 KV 存储(如HBase/Redis)。Fluss PrimaryKey Table 支持高 QPS 主键点查,并可用于 Flink Lookup Join。
lua
订单流 Fluss 维表
+-----------+ +----------------+
| order_id | | cust_key -> 用户 |
| cust_key | ----lookup--> | nation_key -> 国家|
| amount | +----------------+
+-----------+
|
v
实时宽表 enriched_orders
五、湖仓分层
Fluss 的湖仓能力来自热层与冷层的组合,它可以使用 Apache Paimon、Apache Iceberg、Apache Hudi、Delta Lake、Lance 等湖仓存储作为分层存储层。
Fluss 的 datalake tiering service 会持续把 Fluss 数据分层到 Lakehouse Storage。进入湖仓后的数据既可以被 Fluss client 以 streaming 方式读取,也可以被 Flink、Spark、StarRocks 等外部系统直接访问,从而降低存储成本并改善分析性能。
lua
热层:Apache Fluss
+--------------------------------+
| 最近数据 / 高频更新 / 点查 |
| Stream Read / Lookup / CDC |
+---------------+----------------+
|
| Tiering Service
v
冷层:Lakehouse Storage
+--------------------------------+
| Paimon / Iceberg / Lance |
| 历史数据 / 长周期分析 / 开放查询 |
+--------------------------------+
启用湖仓存储并不是默认行为(默认关闭),需要在server.yaml中配置datalake.format等参数,并启动基于 Flink 的 tiering service;每张表还需要通过'table.datalake.enabled' = 'true'开启湖仓分层。
六、功能特性
Fluss 作为实时分析、AI 和重状态流式负载的 streaming storage system 的重要里程碑,重点增强了数据模型、零停机 Schema 演进、存储层优化、运维保障、Spark 集成和 Azure 支持。
| 能力 | 说明 | 工程价值 |
|---|---|---|
| 亚秒级流式读写 | Fluss 支持 sub-second streaming reads/writes | 适合实时看板、告警、实时特征 |
| Log Table | 只追加,不支持 Update/Delete | 替代或补充事件流存储 |
| PrimaryKey Table | 支持 Insert/Update/Delete、点查、Changelog | 承接维表、状态表、画像表 |
| 列式存储与列裁剪 | Log Table 默认使用 Apache Arrow 列式格式,并支持 streaming read 下的 column pruning | 降低 I/O 和网络开销 |
| Changelog | PrimaryKey Table 可生成 changelog | 支持审计、CDC、回放 |
| 湖仓分层 | Tiering service 持续写入 Paimon/Iceberg/Lance 等冷层 | 降低热层存储压力,统一实时与历史分析 |
| Aggregation Merge Engine | 0.9 引入存储层聚合 | 减少 Flink 状态压力 |
| Auto-Increment | 可用于字典表与高基数去重 | 优化 count distinct 等场景 |
Log Table 的列裁剪值得特别关注。Fluss Log Table 默认使用 Apache Arrow 列式格式,查询只访问部分列时可以跳过无关列;Fluss 支持 streaming reads 中的 column pruning,从而减少读取数据量和网络成本。
压缩方面,Log Table 支持 Arrow log format 的端到端压缩,默认使用 ZSTD codec 且 level 为 3,ZSTD level 3 可达到约 5x 压缩比。
七、适用场景
- 实时数仓热层:如果你的实时数仓已经由 Kafka + Flink + Iceberg/Paimon 组成,Fluss 可以作为 Kafka 与湖仓之间的热存储层。它保留流式写入与消费,又通过分层服务把数据持续下沉到湖仓格式,适合希望把实时与离线口径统一起来的团队。
- 实时维表与 Lookup Join:PrimaryKey Table 支持主键点查,因此适合存储用户维表、商品维表、账户状态、设备状态等实时维度。Flink 作业可通过 Lookup Join 读取这些表,减少单独维护 Redis 维表或外部 KV 的复杂度。
- 实时画像与特征表:用户画像和实时特征往往既有更新,又有点查,还需要被下游模型或分析任务消费,Fluss为这类场景提供了较完整的基础能力。
- CDC 审计与回放:Fluss 引入
$changelog和$binlog虚拟表,用于 Change Data Feed。用户可通过给表名追加$changelog访问数据修改记录,记录中包含_change_type、_log_offset、_commit_timestamp等元信息;PrimaryKey Table 还提供$binlog形式,包含 before/after 行结构。
sql
业务表 orders
|
| SELECT * FROM orders$changelog
v
+--------------+-------------+-------------------+-------------+
| _change_type | _log_offset | _commit_timestamp | 原始业务字段 |
+--------------+-------------+-------------------+-------------+
| insert | 10001 | 2026-xx-xx | ... |
| update_after | 10002 | 2026-xx-xx | ... |
| delete | 10003 | 2026-xx-xx | ... |
+--------------+-------------+-------------------+-------------+
另一方面,Fluss 还处在快速演进期,官方最新0.9 版本仍以 "Incubating" 发布。 如果你的团队需要一个已长期验证、生态插件极其丰富、主要用于跨语言事件总线的消息系统,Kafka 仍然是更稳妥的默认选择。
如果业务只需要离线湖仓批分析,而不需要亚秒级写入、实时查询、Changelog 或热层点查,直接使用 Paimon/Iceberg/Hudi 可能更简单。Fluss 的价值主要在"实时热层 + 湖仓冷层 + 表语义"的组合处体现。
八、部署使用
一个最小测试集群通常包含 ZooKeeper、CoordinatorServer 和至少一个 TabletServer,通过官方示例提供的docker compose up -d拉起集群。
lua
测试环境最小组件:
+-------------+
| ZooKeeper |
+------+------+
|
v
+-------------+ +----------------+
| Coordinator | -----> | TabletServer |
| Server | | LogStore/KV |
+-------------+ +----------------+
与 Flink 交互时,需要在 Flink SQL Client 中创建 Fluss Catalog,如果要启用湖仓分层,需要额外准备 Flink 集群、fluss-flink-tiering-0.9.1-incubating.jar、对应 Fluss Connector、湖仓格式相关 jar,以及远端文件系统 jar。目前 tiering service 以 Flink 作为后端,且该服务是 stateless 的,可同时运行多个实例,并由 Fluss 集群协调以保证写入 lake storage 的 exactly-once 语义。
九、常见问题
1.Fluss 和 Kafka 是什么关系
Kafka 更偏事件传输和消息日志,Fluss 更偏流式存储和实时湖仓热层。一句话区分二者:Kafka is the streaming transport,Fluss is the streaming storage。 如果你的需求是稳定的事件总线,Kafka 依然合适;如果还需要主键点查、表更新、Changelog、湖仓分层和实时分析热层,Fluss 更值得评估。
2.Fluss 是否可以替代 Redis
不能简单等同。Fluss PrimaryKey Table 支持高 QPS 主键点查,并可用于 Flink Lookup Join。 但 Redis 仍然在超低延迟缓存、复杂数据结构、广泛客户端生态上有优势;Fluss 的优势在于同一份实时数据同时服务流读、表读、变更日志和湖仓分层。
3.Fluss 是否需要 ZooKeeper
Fluss 使用 ZooKeeper 做集群协调、元数据存储和配置管理,不过未来版本计划用 KvStore 替代 ZooKeeper 的元数据存储,并使用 Raft 做集群协调和一致性保障。
4.KvTablet 是否支持副本
LogTablet 支持按表配置 replication factor 进行多副本,但 目前 KvTablet 不支持 replication。 KvTablet本身不进行多副本复制,其数据的一致性和恢复能力,是通过多副本的LogTablet(WAL)和定期上传到远程存储的快照来共同保证的。
5.湖仓分层是否默认开启
不是, Lakehouse Storage 默认关闭,需要手动启用;表级别也要设置 'table.datalake.enabled' = 'true'。
6.Fluss 当前支持哪些湖仓格式
当前仅支持 Apache Paimon、Apache Iceberg、Lance,更多类型仍在路上。