Deploying Streaming Lakehouse
This guide covers how to deploy a Fluss cluster with Streaming Lakehouse capabilities. For conceptual overview, see Lakehouse Overview.
Prerequisites
- A running Fluss cluster (see Deploying Distributed Cluster)
- A running Flink cluster (for the Tiering Service)
- Access to a data lake storage system (S3, HDFS, OSS, etc.)
Cluster Configuration
You can enable Lakehouse storage through:
- Static configuration: Configure in
server.yamlbefore starting the cluster - Dynamic configuration: Enable at runtime using the
set_cluster_configsprocedure
Method 1: Static Configuration
Configure lakehouse settings in server.yaml on all Fluss servers (CoordinatorServer and TabletServer).
Fluss follows a simple convention for these keys:
datalake.enabled: trueexplicitly enables lakehouse capability for the cluster. If it is left unset, configuringdatalake.formatalone also enables it; wheneverdatalake.enabledistrue,datalake.formatmust also be set.datalake.formatselects the lake format for the cluster (paimon,iceberg, orlance).- Format-specific options use the
datalake.<format>.*prefix. Fluss strips this prefix and passes the remaining keys straight to the corresponding lake catalog/client — for exampledatalake.paimon.metastorebecomesmetastoreanddatalake.iceberg.typebecomestype. Any option supported by the lake catalog can be set this way. - Only configure options for the format selected by
datalake.format.
The Tiering Service is an independent Flink job and needs the same datalake.* options passed as job arguments (see Starting the Tiering Service).
- Paimon
- Iceberg
- Lance
datalake.enabled: true
datalake.format: paimon
datalake.paimon.metastore: filesystem
datalake.paimon.warehouse: /path/to/paimon/warehouse
For Hive catalog:
datalake.enabled: true
datalake.format: paimon
datalake.paimon.metastore: hive
datalake.paimon.uri: thrift://<hive-metastore-host>:<port>
datalake.paimon.warehouse: hdfs:///path/to/warehouse
datalake.enabled: true
datalake.format: iceberg
datalake.iceberg.catalog-impl: org.apache.iceberg.jdbc.JdbcCatalog
datalake.iceberg.name: fluss_catalog
datalake.iceberg.uri: jdbc:postgresql://postgres-host:5432/iceberg
datalake.iceberg.jdbc.user: iceberg
datalake.iceberg.jdbc.password: iceberg
datalake.iceberg.warehouse: s3://bucket/iceberg
datalake.iceberg.io-impl: org.apache.iceberg.aws.s3.S3FileIO
datalake.enabled: true
datalake.format: lance
datalake.lance.warehouse: s3://bucket/lance
Method 2: Dynamic Configuration
Enable lakehouse settings at runtime using Flink SQL:
USE fluss_catalog;
CALL sys.set_cluster_configs(
config_pairs => 'datalake.format', 'paimon',
'datalake.paimon.metastore', 'filesystem',
'datalake.paimon.warehouse', '/path/to/warehouse'
);
See set_cluster_configs for more details.
Adding Required JARs
Fluss Server JARs
Add JARs to ${FLUSS_HOME}/plugins/<format>/ based on your configuration:
- Paimon
- Iceberg
- Lance
| Scenario | Required JAR |
|---|---|
| Paimon with S3 | paimon-s3-<version>.jar, matching your Paimon version |
| Paimon with OSS | paimon-oss-<version>.jar, matching your Paimon version |
| Paimon Hive catalog | Flink SQL Hive connector JAR |
| Scenario | Required JAR |
|---|---|
| Iceberg with S3 | iceberg-aws-<version>.jar, iceberg-aws-bundle-<version>.jar, matching your Iceberg version |
| Iceberg JDBC catalog | PostgreSQL/MySQL JDBC driver |
Lance support is built into the Fluss distribution. Cloud storage credentials are configured via storage-options.
Starting the Tiering Service
The Tiering Service is a Flink job that continuously tiers data from Fluss to the data lake. For architecture details, see Tiering Service.
Prerequisites
- Download fluss-flink-tiering-1.0-SNAPSHOT.jar
Flink JARs
Add the following to ${FLINK_HOME}/lib:
- Paimon
- Iceberg
- Lance
- fluss-flink-1.20-1.0-SNAPSHOT.jar
- fluss-lake-paimon-1.0-SNAPSHOT.jar
- paimon-bundle-1.3.1.jar
- flink-shaded-hadoop-2-uber-*.jar
- Paimon filesystem JAR (e.g.,
paimon-s3-<version>.jarfor S3)
- fluss-flink-1.20-1.0-SNAPSHOT.jar
- fluss-lake-iceberg-1.0-SNAPSHOT.jar
- iceberg-flink-runtime-1.20-*.jar
- Hadoop client JARs — export
HADOOP_CLASSPATH, download the pre-bundledhadoop-apache-3.3.5-2.jar, or install a full Hadoop package (see Iceberg Hadoop Dependencies) - JDBC driver (if using JDBC catalog)
If using S3, OSS, or HDFS as Fluss's remote storage, also add the corresponding Fluss filesystem JAR.
Start the Service
- Paimon
- Iceberg
- Lance
${FLINK_HOME}/bin/flink run /path/to/fluss-flink-tiering-1.0-SNAPSHOT.jar \
--fluss.bootstrap.servers localhost:9123 \
--datalake.format paimon \
--datalake.paimon.metastore filesystem \
--datalake.paimon.warehouse /tmp/paimon
${FLINK_HOME}/bin/flink run /path/to/fluss-flink-tiering-1.0-SNAPSHOT.jar \
--fluss.bootstrap.servers localhost:9123 \
--datalake.format iceberg \
--datalake.iceberg.catalog-impl org.apache.iceberg.jdbc.JdbcCatalog \
--datalake.iceberg.name fluss_catalog \
--datalake.iceberg.uri "jdbc:postgresql://postgres:5432/iceberg" \
--datalake.iceberg.jdbc.user iceberg \
--datalake.iceberg.jdbc.password iceberg \
--datalake.iceberg.warehouse "s3://bucket/iceberg"
${FLINK_HOME}/bin/flink run /path/to/fluss-flink-tiering-1.0-SNAPSHOT.jar \
--fluss.bootstrap.servers localhost:9123 \
--datalake.format lance \
--datalake.lance.warehouse s3://bucket/lance
- You must pass all
datalake.*options that were set inserver.yamlas command-line arguments - For S3/cloud storage, include additional flags like
--datalake.paimon.s3.endpoint,--datalake.paimon.s3.access-key, etc. - The Tiering Service is stateless—you can run multiple instances for scalability
- Use
-Dto pass Flink configurations (e.g.,-Dparallelism.default=3) - For complete examples with S3 configuration, see the Lakehouse Quickstart
Enabling Lakehouse for Tables
Create tables with lakehouse storage enabled:
CREATE TABLE my_table (
id BIGINT PRIMARY KEY NOT ENFORCED,
name STRING
) WITH (
'table.datalake.enabled' = 'true',
'table.datalake.freshness' = '1min'
);
Verification
- Check the Tiering Service job is running in Flink Web UI
- After the freshness interval, query the lake table:
-- Lake-only query
SELECT * FROM my_table$lake;
-- Union Read (real-time + historical)
SELECT * FROM my_table;
See Union Read for more details.