Skip to content

[tiering] Decouple common tiering class from flink module - #3554

Open
Yohahaha wants to merge 5 commits into
apache:mainfrom
Yohahaha:spark-tiering-phase1
Open

[tiering] Decouple common tiering class from flink module#3554
Yohahaha wants to merge 5 commits into
apache:mainfrom
Yohahaha:spark-tiering-phase1

Conversation

@Yohahaha

@Yohahaha Yohahaha commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Purpose

Linked issue: close #xxx

Phase 1 of #2985

Brief change log

Tests

API and Format

Documentation

@Yohahaha
Yohahaha force-pushed the spark-tiering-phase1 branch 2 times, most recently from 4b9f5ff to 693b4c0 Compare July 30, 2026 07:38
@Yohahaha

Yohahaha commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

cc @beryllw @luoyuxia @YannByron

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR moves tiering “common” building blocks (splits, write result container, snapshot committer, and commit logic) out of the Flink connector layer into fluss-client, and adapts the Flink tiering source to use these engine-agnostic types via a Flink-specific wrapper (FlinkTieringSplit). This supports the longer-term goal of enabling additional compute backends (e.g., Spark tiering) without duplicating core tiering protocol code.

Changes:

  • Relocate tiering split types and tiering init/commit helpers into fluss-client and update downstream imports/usages.
  • Introduce TieringCommitter and TieringCommitResult in fluss-client and wire Flink’s TieringCommitOperator to use it.
  • Add FlinkTieringSplit adapter and update Flink tiering source/enumerator/serde/state + tests to use it.

Reviewed changes

Copilot reviewed 33 out of 33 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
fluss-lake/fluss-lake-paimon/src/test/java/org/apache/fluss/lake/paimon/utils/DvTableReadableSnapshotRetrieverTest.java Switch test to use snapshot committer moved to fluss-client.
fluss-flink/fluss-flink-common/src/test/java/org/apache/fluss/flink/tiering/source/TieringSplitReaderTest.java Update tests to use FlinkTieringSplit wrapper and client tiering split types.
fluss-flink/fluss-flink-common/src/test/java/org/apache/fluss/flink/tiering/source/TieringSourceReaderTest.java Update reader tests to wrap client TieringLogSplit in FlinkTieringSplit.
fluss-flink/fluss-flink-common/src/test/java/org/apache/fluss/flink/tiering/source/TableBucketWriteResultSerializerTest.java Update imports to use TableBucketWriteResult from fluss-client.
fluss-flink/fluss-flink-common/src/test/java/org/apache/fluss/flink/tiering/source/state/TieringSplitStateTest.java Update split state tests for FlinkTieringSplit + client split types.
fluss-flink/fluss-flink-common/src/test/java/org/apache/fluss/flink/tiering/source/split/TieringSplitSerializerTest.java Adapt serde tests to serialize/deserialize FlinkTieringSplit and validate wrapper behavior.
fluss-flink/fluss-flink-common/src/test/java/org/apache/fluss/flink/tiering/source/enumerator/TieringSourceEnumeratorTest.java Update enumerator tests to use client split types + Flink wrapper.
fluss-flink/fluss-flink-common/src/test/java/org/apache/fluss/flink/tiering/committer/TieringCommitOperatorTest.java Update imports to client FlussTableLakeSnapshotCommitter + TableBucketWriteResult.
fluss-flink/fluss-flink-common/src/test/java/org/apache/fluss/flink/tiering/committer/FlussTableLakeSnapshotCommitterTest.java Update test to use committer from fluss-client and keep compatibility coverage.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/source/TieringSplitReader.java Switch SplitReader to Flink wrapper split type and unwrap to engine-agnostic split for processing.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/source/TieringSourceReader.java Switch source reader split type to FlinkTieringSplit and update state initialization.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/source/TieringSourceFetcherManager.java Propagate split type change to FlinkTieringSplit.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/source/TieringSource.java Update Flink Source generics to use FlinkTieringSplit.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/source/TableBucketWriteResultTypeInfo.java Update to client TableBucketWriteResult.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/source/TableBucketWriteResultSerializer.java Update to client TableBucketWriteResult.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/source/TableBucketWriteResultEmitter.java Update to client TableBucketWriteResult.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/source/state/TieringSplitState.java Update split state to store/restore FlinkTieringSplit while preserving underlying split metadata.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/source/split/TieringSplitSerializer.java Update split serializer to operate on FlinkTieringSplit while encoding engine-agnostic split data.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/source/split/TieringSplitGenerator.java Update imports to use client TieringSplit types.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/source/split/FlinkTieringSplit.java New adapter implementing Flink SourceSplit around engine-agnostic TieringSplit.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/source/enumerator/TieringSourceEnumerator.java Switch enumerator split type to FlinkTieringSplit while generating engine-agnostic splits.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/committer/TieringCommitOperatorFactory.java Update to client TableBucketWriteResult.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/committer/TieringCommitOperator.java Replace embedded commit protocol with reusable TieringCommitter from fluss-client.
fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/tiering/committer/CommittableMessageTypeInfo.java Update to client TableBucketWriteResult.
fluss-client/src/main/java/org/apache/fluss/client/tiering/TieringWriterInitContext.java Move writer init context into fluss-client tiering package.
fluss-client/src/main/java/org/apache/fluss/client/tiering/TieringSplit.java Move engine-agnostic split base into fluss-client and remove Flink SourceSplit dependency.
fluss-client/src/main/java/org/apache/fluss/client/tiering/TieringSnapshotSplit.java Move snapshot split into fluss-client tiering package.
fluss-client/src/main/java/org/apache/fluss/client/tiering/TieringLogSplit.java Move log split into fluss-client tiering package.
fluss-client/src/main/java/org/apache/fluss/client/tiering/TieringCommitterInitContext.java Move committer init context into fluss-client tiering package.
fluss-client/src/main/java/org/apache/fluss/client/tiering/TieringCommitter.java New engine-agnostic committer extracting the shared lake+Fluss commit protocol.
fluss-client/src/main/java/org/apache/fluss/client/tiering/TieringCommitResult.java New DTO for returning committable + stats from engine-agnostic commit logic.
fluss-client/src/main/java/org/apache/fluss/client/tiering/TableBucketWriteResult.java Move write-result container into fluss-client tiering package.
fluss-client/src/main/java/org/apache/fluss/client/tiering/FlussTableLakeSnapshotCommitter.java Move snapshot committer into fluss-client and adjust visibility for cross-module usage/testing.
Comments suppressed due to low confidence (2)

fluss-client/src/main/java/org/apache/fluss/client/tiering/TieringSplit.java:32

  • TieringSplit is Serializable but doesn’t declare a serialVersionUID, while other Serializable classes in this package/module do (e.g., TableBucketWriteResult). This can cause unintended InvalidClassException if the class evolves and serialized splits are persisted or transferred across versions (relevant for engine-agnostic tiering splits).
    fluss-client/src/main/java/org/apache/fluss/client/tiering/FlussTableLakeSnapshotCommitter.java:202
  • The low-level commit(tableId, snapshotId, …) overload is public but appears intended for internal wiring / tests (similar to prepareLakeSnapshot(), addLogEndOffsets(), getCoordinatorGateway()). Marking it @VisibleForTesting clarifies it’s not meant as a general public API entry point.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 169 to 173
} else {
// deserialize starting offset
long startingOffset = in.readLong();
// deserialize starting offset
long stoppingOffset = in.readLong();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, though note this is pre-existing behaviour rather than something introduced by this refactor. On main the deserialize method already had the same if (splitKind == TIERING_SNAPSHOT_SPLIT_FLAG) { ... } else { ... } shape; this PR only reshaped the two return new ... statements into an assignment plus a single new FlinkTieringSplit(...) wrap at the end, which is why the diff surfaced these lines.

That said, the underlying concern is valid and worth fixing here, so I've addressed it in d92f2a3:

  • deserialize now matches TIERING_LOG_SPLIT_FLAG explicitly and throws IOException("Unknown split kind " + splitKind) for anything else, instead of falling through to the log-split branch.
  • Removed the serializer's private copies of the two flag constants in favour of the public ones on TieringSplit. Previously TIERING_LOG_SPLIT_FLAG was declared but never compared against, which was exactly the symptom of the missing branch; now both flags have a single definition and both are actually used.
  • Added testDeserializeUnknownSplitKindFailsFast, which tampers with the split-kind byte and asserts the IOException. I verified it fails against the previous else fallback and passes with the fix.

One note on the motivation: the "corrupted splitKind" scenario isn't really the risk here, since these bytes only travel from TieringSourceEnumerator to TieringSource within a single job over Flink's own transport (the class javadoc explicitly states it does not need to consider compatibility). The real value is guarding against a future third split kind being added to splitKind()/serialize() while deserialize() is forgotten - that would otherwise silently misread the field layout. Failing fast is strictly better, so the change is worth it either way.

Extract engine-agnostic split generation from fluss-flink so that other
engines (e.g. Spark tiering) can reuse it. Replace FlinkRuntimeException
with FlussRuntimeException to drop the Flink dependency.
TieringSplitSerializer#deserialize treated every non-snapshot splitKind
as a log split, so an unknown kind was silently deserialized with the
wrong field layout instead of failing fast. Match explicitly against
TIERING_LOG_SPLIT_FLAG and throw an IOException otherwise.

Also drop the serializer's private copies of the split kind flags in
favour of the public constants on TieringSplit, so both flags now have
exactly one definition and are both actually used.
@Yohahaha
Yohahaha force-pushed the spark-tiering-phase1 branch from d92f2a3 to 5339daf Compare August 18, 2026 03:10
@Yohahaha

Copy link
Copy Markdown
Contributor Author

@beryllw @luoyuxia @wuchong PTAL!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants