-
Notifications
You must be signed in to change notification settings - Fork 2.5k
docs(streamer): document checkpoint v2 reset for the Hudi incremental source #19573
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: asf-site
Are you sure you want to change the base?
Changes from all commits
c2d9c8e
d92a88e
05e5b64
cc34838
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -312,14 +312,55 @@ Read more in depth about concurrency control in the [concurrency control concept | ||||||||||
| Hudi Streamer uses checkpoints to keep track of what data has been read already so it can resume without needing to reprocess all data. | |||||||||||
| When using a Kafka source, the checkpoint is the [Kafka Offset](https://cwiki.apache.org/confluence/display/KAFKA/Offset+Management) | |||||||||||
| When using a DFS source, the checkpoint is the 'last modified' timestamp of the latest file read. | |||||||||||
| Checkpoints are saved in the .hoodie commit file as `streamer.checkpoint.key`. | |||||||||||
| Checkpoints are saved in the .hoodie commit file. Completion time checkpoints are stored under | |||||||||||
| `streamer.checkpoint.key.v2` and request time checkpoints under `deltastreamer.checkpoint.key`. Which one applies | |||||||||||
| depends on the source, and for the Hudi incremental source also on the table version — see below. | |||||||||||
|
|
|||||||||||
| If you need to change the checkpoints for reprocessing or replaying data you can use the following options: | |||||||||||
|
|
|||||||||||
| - `--checkpoint` will set `streamer.checkpoint.reset_key` in the commit file to overwrite the current checkpoint. Format of checkpoint depends on [KAFKA_CHECKPOINT_TYPE](configurations.md#hoodiestreamersourcekafkacheckpointtype). By default (for type `string`), checkpoint should be provided as: `topicName,0:offset0,1:offset1,2:offset2`. For type `timestamp`, checkpoint should be provided as long value of desired timestamp. For type `single_offset`, we assume that topic consists of a single partition, so checkpoint should be provided as long value of desired offset. | |||||||||||
| - `--checkpoint` will set the matching reset key in the commit file to overwrite the current checkpoint, either `streamer.checkpoint.reset.key.v2` or `deltastreamer.checkpoint.reset_key`. Format of checkpoint depends on [KAFKA_CHECKPOINT_TYPE](configurations.md#hoodiestreamersourcekafkacheckpointtype). By default (for type `string`), checkpoint should be provided as: `topicName,0:offset0,1:offset1,2:offset2`. For type `timestamp`, checkpoint should be provided as long value of desired timestamp. For type `single_offset`, we assume that topic consists of a single partition, so checkpoint should be provided as long value of desired offset. | |||||||||||
| - `--source-limit` will set a maximum amount of data to read from the source. For DFS sources, this is max # of bytes read. | |||||||||||
| For Kafka, this is the max # of events to read. | |||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 Same root cause as the intro line: this bullet now says
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same root cause, same fix — see the reply on the intro line for the detail and the measurements. Corrected in cc34838. Short version: The bullet no longer claims a table-version rule:
Worth keeping in mind that the pre-existing text said |
|||||||||||
|
|
|||||||||||
| #### Resetting the checkpoint for the Hudi incremental source | |||||||||||
|
|
|||||||||||
| When Hudi Streamer writes a target table at table version 8 or higher using `HoodieIncrSource`, it tracks progress by | |||||||||||
| **completion time** instead of requested instant time, and records it in the commit metadata under | |||||||||||
| `streamer.checkpoint.key.v2`. A bare timestamp would be ambiguous between the two, so `--checkpoint` has to state which | |||||||||||
| one it is. This form is required from Hudi 1.0.1 onward; on 1.0.0 the prefixes are not recognised and `--checkpoint` | |||||||||||
| takes a bare completion time. | |||||||||||
|
|
|||||||||||
| ```shell | |||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 This section could clarify the 1.0.0 behavior: it says on 1.0.0
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good challenge — I re-tested rather than argue from the earlier run, and the doc statement holds: 1.0.0 reads a bare The inference in the comment is that because the bare value was accepted on 1.0.0, and that value happened to be a requested instant time, 1.0.0 must interpret bare values as requested times. Acceptance does not imply interpretation, though — 1.0.0 does no validation of the value at all, so it accepts any timestamp-shaped string regardless of which clock it came from. What the value means only shows up in which records get ingested. So I ran the discriminating pair on 1.0.0. Source instant #2: requested
If a bare value were a requested time, passing instant #2's requested time would have resumed after instant #2 and excluded its records. It did not. Passing instant #2's completion time is what lands the checkpoint exactly after it. That is completion time semantics. This also explains the original matrix row that prompted the question. The bare value I fed every version was instant #2's requested time, which is earlier than its completion time, so read as a completion time it sits mid-way and instant #2 is still ahead of the checkpoint — hence six records on 1.0.0 where 1.0.1+ ingests four. The source agrees. In checkpoint = Option.of(CheckpointUtils.targetCheckpointV2(writeTableVersion)
? new StreamerCheckpointV2(streamerConfig.checkpoint) : new StreamerCheckpointV1(streamerConfig.checkpoint));At table version 8 On #12718's note that 1.x was "still using request time based handling": that was written in January 2025 and is now stale, which the PR body covers. The 1.0.0 run with no override stores No change made for this one. @yihua a confirmation of the pre-1.0.1 semantics would still be welcome. |
|||||||||||
| # resume after the instant with this requested instant time | |||||||||||
| --checkpoint resumeFromInstantRequestTime:20250110120000000 | |||||||||||
|
|
|||||||||||
| # resume after the instant with this completion time | |||||||||||
| --checkpoint resumeFromInstantCompletionTime:20250110120005000 | |||||||||||
| ``` | |||||||||||
|
|
|||||||||||
| Both forms resume from the same position. The request time form is translated internally to the completion time of that | |||||||||||
| same instant, and ingestion proceeds in completion time order either way. Whichever value you pass is recorded verbatim | |||||||||||
| under `streamer.checkpoint.reset.key.v2`. | |||||||||||
|
|
|||||||||||
| Passing a bare timestamp is rejected: | |||||||||||
|
|
|||||||||||
| ```plain | |||||||||||
| Illegal checkpoint key override `20250110120000000`. Valid format is either | |||||||||||
| `resumeFromInstantRequestTime:<checkpoint value>` or `resumeFromInstantCompletionTime:<checkpoint value>`. | |||||||||||
| ``` | |||||||||||
|
|
|||||||||||
| :::note | |||||||||||
| `S3EventsHoodieIncrSource` and `GcsEventsHoodieIncrSource` are excluded from completion time checkpoints. They continue | |||||||||||
| to take a plain `--checkpoint` value regardless of the table version. | |||||||||||
| ::: | |||||||||||
|
|
|||||||||||
| :::caution | |||||||||||
| Do not pass `--checkpoint` or `--ignore-checkpoint` on the run that upgrades or downgrades the table version while using | |||||||||||
| a Hudi incremental source. Rather than risk applying the override under the wrong checkpoint semantics, Hudi fails the | |||||||||||
| job with a message asking you to drop those options. Let the upgrade finish first, then reset the checkpoint on a later | |||||||||||
| run. | |||||||||||
| ::: | |||||||||||
|
|
|||||||||||
| ### Transformers | |||||||||||
|
|
|||||||||||
| Hudi Streamer supports custom transformation on records before writing to storage. This is done by supplying | |||||||||||
|
|
|||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 It might help to reconcile the key names here. The existing bullet says
--checkpointsetsstreamer.checkpoint.reset_key, while the new subsection says the value is recorded understreamer.checkpoint.reset.key.v2for table version 8+. A reader inspecting commit metadata may be unsure which key applies to their table. Consider noting thatreset.key.v2is used for table version 8+ and the olderreset_keyfor versions below that, mirroring thestreamer.checkpoint.key.v2vsdeltastreamer.checkpoint.keydistinction you already added just above.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right that these do not reconcile — and the reason is that
streamer.checkpoint.reset_keyis not a real key either. Fixed in 05e5b64.It has the same missing-prefix defect as the checkpoint key line I corrected in d92a88e. The actual reset keys, at
release-1.2.0:deltastreamer.checkpoint.reset_keyStreamerCheckpointV1.java:30, written at:60streamer.checkpoint.reset.key.v2StreamerCheckpointV2.java:33, written at:66Same
CheckpointUtils.shouldTargetCheckpointV2test on the write table version that selects betweendeltastreamer.checkpoint.keyandstreamer.checkpoint.key.v2. So the bullet was not describing an older key superseded by the new one — it was naming a key Hudi never writes, which is exactly why a reader inspecting commit metadata would not find it.The bullet now reads:
which mirrors the phrasing used for the checkpoint key a few lines above, so the two lines now agree with each other and with the new subsection. Empirically confirmed earlier in this PR: the version-9 target commit carries
streamer.checkpoint.reset.key.v2with the prefixed override verbatim, and a target forced tohoodie.write.table.version=6carries thedeltastreamer.*pair.Build is clean with the warning set byte-identical to the baseline.