Build METADATA push metadata from the local segment instead of re-downloading the staged tar - #19490
Draft
KKcorps wants to merge 2 commits into
Draft
Build METADATA push metadata from the local segment instead of re-downloading the staged tar#19490KKcorps wants to merge 2 commits into
KKcorps wants to merge 2 commits into
Conversation
…reshes The METADATA mode of BaseSingleSegmentConversionExecutor registers the staged tar's URI as the segment's download URL. For a task that refreshes a segment under its own name that path collides with a live segment stored as <segment>.tar.gz, drops the TAR path's If-Match and REFRESH_ONLY guards, and moves the download URL away from the deep store location so the second refresh of the same segment fails with "already exists". Add a protected hook, isCopyToDeepStoreForMetadataPush(), default false, so the existing behavior is unchanged for every current task. A task that returns true gets a refresh-safe path: the tar is staged under <segment>.<taskId>.tar.gz, the push carries the same If-Match, REFRESH_ONLY and custom-map headers as TAR plus COPY_SEGMENT_TO_DEEP_STORE=true, the controller copies the bytes into the segment's existing deep store location, and the staged tar is deleted in a finally. The metadata tar is built from the local converted segment instead of downloading the staged tar back, and an unchanged segment (same CRC) only re-registers its metadata against the current download URL. SegmentConversionUtils gains uploadSegmentMetadata sharing the retry loop with uploadSegment. BaseTaskExecutor gains a moveSegmentToOutputPinotFS overload with an explicit target name and overwrite flag, deleteFromOutputPinotFS and createSegmentMetadataTarFile. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y375AgHYsh1YqNSsfvF1a8
…nloading the staged tar Every minion METADATA push uploaded the segment tar to the output filesystem and then downloaded it back into java.io.tmpdir to extract metadata.properties and creation.meta, doubling the minion's transfer per segment and leaving a full segment copy in the temp dir during the push. SegmentPushUtils gains generateSegmentMetadataFile(File, File, String), which builds the two-file metadata tar from a local segment directory, plus sendSegmentUriAndMetadata / sendSegmentsUriAndMetadata overloads that push caller-supplied metadata tars. The existing PinotFS overloads keep their behavior and share one private push loop with the new ones. BaseSingleSegmentConversionExecutor builds the metadata tar for every METADATA push and the default path uses the new overload. BaseMultipleSegmentsConversionExecutor builds one metadata tar per output segment and uses the new overloads in both the per-segment and the batch mode. Wire behavior is unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y375AgHYsh1YqNSsfvF1a8
KKcorps
force-pushed
the
kk/metadata-push-local-metadata-tar
branch
from
September 7, 2026 10:24
7c41407 to
3f20c40
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #19490 +/- ##
=============================================
+ Coverage 39.44% 67.79% +28.35%
- Complexity 1429 1470 +41
=============================================
Files 3488 3488
Lines 224424 224507 +83
Branches 35429 35437 +8
=============================================
+ Hits 88528 152211 +63683
+ Misses 127912 60268 -67644
- Partials 7984 12028 +4044
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #19488 (the first commit here is that PR; review the second commit).
TL;DR
Every minion METADATA push uploads the segment tar to the output filesystem and then downloads the
same tar back to extract
metadata.propertiesandcreation.meta. This PR builds that two-filemetadata tar from the local converted segment before the segment directory is deleted, and adds
SegmentPushUtilsoverloads that push caller-supplied metadata tars. Both minion base executorsuse them. Wire behavior is unchanged: same headers, same URIs, same controller handling. Minion S3
traffic per pushed segment halves and the full-segment copy in
java.io.tmpdirgoes away.The problem
SegmentPushUtils.sendSegmentUriAndMetadata(spec, fileSystem, uriToTarPath, ...)and its batchtwin take a map of staged tar paths and call
generateSegmentMetadataFile(fileSystem, tarUri),which copies the whole tar into
java.io.tmpdir, scans the gzip stream twice withuntarOneFile,tars the two entries and deletes the copy. The
preferMetadataTarGzshortcut only helps when a<segment>.metadata.tar.gzsidecar already exists next to the tar, and the minion executors neverwrite one. So for a task that pushes N segments of size S in METADATA mode, the minion moves
2·N·S bytes: N·S up, N·S back down. For hundreds-of-MB segments that is the dominant cost of the
push step, and the temporary full copy lands on the minion's
java.io.tmpdir.The two files are already on local disk at that point. The executor tars the converted segment
directory and only then deletes it.
The approach
SegmentPushUtils.generateSegmentMetadataFile(File segmentDir, File outputDir, String segmentName)copies
metadata.propertiesandcreation.metaout of a local segment directory (v1/v3 layoutsvia
SegmentDirectoryPaths) and tars them as<segmentName>.metadata.tar.gz.sendSegmentUriAndMetadata(spec, Map<String, File> segmentUriToMetadataFile, headers, params)and the batch
sendSegmentsUriAndMetadata(...)twin push caller-supplied metadata tars. Thesegment name comes from the metadata file name, the caller keeps ownership of the files. The
existing
PinotFSoverloads are unchanged in behavior and now share one private push loop withthe new ones, so the retry, header and batch-tar logic exists once.
BaseSingleSegmentConversionExecutorbuilds the metadata tar right after the conversion forevery METADATA push (the controller-copy path from Add an opt-in controller-copy METADATA push for same-name segment refreshes #19488 already did), and the default path
pushes it with the new overload instead of the
PinotFSone.BaseMultipleSegmentsConversionExecutorbuilds one metadata tar per output segment in the tarloop, keeps them alongside the tars, pushes them with the new overloads in both the per-segment
and the batch mode, and deletes them with the tars.
flowchart LR subgraph Before["Before"] A[tar converted segment] --> B[upload tar to output FS] B --> C[download tar back to java.io.tmpdir] C --> D[extract 2 files, tar them] D --> E[POST metadata] end subgraph After["After"] F[tar converted segment] --> G[copy 2 files from local dir, tar them] G --> H[upload segment tar to output FS] H --> I[POST metadata] endKey components
SegmentPushUtilsgenerateSegmentMetadataFile(File, File, String), the two local-metadata push overloads, shared privatepushSegmentMetadata/pushSegmentsMetadataloops,getSegmentMetadataFile(sidecar-or-download) used by bothPinotFSpaths.BaseSingleSegmentConversionExecutorBaseMultipleSegmentsConversionExecutorupdateSegmentUriToTarPathMapbecomesgetSegmentUris.BaseTaskExecutorcreateSegmentMetadataTarFilefrom #19488 moves intoSegmentPushUtils.Compatibility
DOWNLOAD_URI,UPLOAD_TYPEand copy flag, and the same batch tar layout.PinotFSoverloads keep their signatures and behavior for external callers (theingestion job runners, StarTree's ingestion tasks).
preferMetadataTarGzstill applies to thePinotFSoverloads.Testing
SegmentPushUtilsTest: local metadata tar contents from a v3 layout (data file excluded); singleand batch local-metadata pushes against the TLS test server, checking
UPLOAD_TYPE,DOWNLOAD_URI, the copy flag and that the caller's files survive; rejection of a metadata filenot named
<segment>.metadata.tar.gz.BaseSingleSegmentConversionExecutorTest: the default METADATA path pushes a locally builtmetadata tar describing the converted segment through the new overload and never calls the
PinotFSoverload.BaseMultipleSegmentsConversionExecutorTest: end-to-endexecuteTaskon METADATA push, per-segmentand batch, with two output segments: one metadata tar per segment named after it, containing
exactly the two files and describing that segment; the
PinotFSoverloads are never called; thestaged tars stay in the output dir as the download URLs.
PurgeMinionClusterIntegrationTest(single executor, METADATA table),RealtimeToOfflineSegmentsMinionClusterIntegrationTest#testRealtimeToOfflineSegmentsMetadataPushTaskand
MergeRollupMinionClusterIntegrationTest#testOfflineTableSingleLevelConcatWithMetadataPush(multi executor, per-segment and batch) on a local-FS cluster.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Y375AgHYsh1YqNSsfvF1a8