Skip to content

Enable optimized S3 tail reads for Iceberg Parquet footers - #15384

Merged
zpuller merged 15 commits into
NVIDIA:release/26.08from
liurenjie1024:ray/netflix
Jul 31, 2026
Merged

Enable optimized S3 tail reads for Iceberg Parquet footers#15384
zpuller merged 15 commits into
NVIDIA:release/26.08from
liurenjie1024:ray/netflix

Conversation

@liurenjie1024

@liurenjie1024 liurenjie1024 commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Description

Fixes #15363

Parquet footer reads through Iceberg currently open and seek an input stream instead of using RapidsInputFile.readTail. This bypasses the optimized Iceberg S3 suffix-range path and adds an avoidable length/seek round trip.

This change:

  • Reads the Parquet trailer with RapidsInputFile.readTail and the footer body with readVectored.
  • Makes IcebergS3InputFile an IcebergInputFile subclass backed by the original org.apache.iceberg.io.InputFile, overriding only the S3-specific vectored and tail reads.
  • Routes decrypted Iceberg input files through IcebergFileIO, preserving Iceberg decryption while enabling optimized S3 reads.
  • Emits a debug message after a suffix-range tail read completes.

Testing

  • Spark 4.0.2 compilation passed for the Iceberg 1.10 and 1.11 modules: mvn -Dbuildver=402 -DskipTests -pl iceberg/iceberg-1-10-x,iceberg/iceberg-1-11-x -am compile
  • Existing Parquet and Iceberg scan coverage includes ParquetScanSuite, ParquetFormatScanSuite, and integration_tests/src/main/python/iceberg/iceberg_test.py.
  • An EMR GPU table scan completed successfully, and executor logs confirmed that Iceberg readTail used an S3 suffix-range GET.

Checklists

Documentation

  • Updated for new or modified user-facing features or behaviors
  • No user-facing change

Testing

  • Added or modified tests to cover new code paths
  • Covered by existing tests
  • Not required

Performance

  • Tests ran and results are added in the PR description
  • Issue filed with a link in the PR description
  • Not required

@greptile-apps

greptile-apps Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Routes Iceberg Parquet footer reads through optimized RAPIDS tail and vectored I/O while preserving decrypted Iceberg input files.

  • Adds an InputFile-wrapping overload to IcebergFileIO.
  • Makes the S3-specific input file inherit the standard Iceberg wrapper and override only optimized range operations.
  • Wraps decrypted data and delete files through the optimized file-I/O path.
  • Reuses PerfIO for shared Parquet footer reading and adds completion-level debug logging.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
iceberg/common/src/main/java/com/nvidia/spark/rapids/fileio/iceberg/IcebergFileIO.java Adds wrapping for existing Iceberg input files so decrypted delegates can retain Iceberg behavior while selecting optimized S3 access.
iceberg/common/src/main/java/org/apache/iceberg/aws/s3/IcebergS3InputFile.java Refactors the optimized S3 input into an IcebergInputFile subclass and adds suffix-tail completion logging.
iceberg/common/src/main/scala/org/apache/iceberg/spark/source/GpuIcebergPartitionReader.scala Routes decrypted data and delete input files through IcebergFileIO wrapping.
sql-plugin/src/main/scala/com/nvidia/spark/rapids/parquet/GpuParquetScan.scala Reads Parquet trailers through readTail and footer bodies through readVectored.
sql-plugin/src/main/scala/com/nvidia/spark/rapids/parquet/ParquetFooterUtils.scala Replaces the local stream-and-seek footer implementation with the shared PerfIO footer reader.

Sequence Diagram

sequenceDiagram
  participant Reader as GPU Iceberg Reader
  participant FileIO as IcebergFileIO
  participant Input as IcebergS3InputFile
  participant S3 as Amazon S3
  Reader->>FileIO: Wrap decrypted InputFile
  FileIO->>Input: maybeCreate(inputFile, fileIO)
  Reader->>Input: readTail(trailerLength)
  Input->>S3: "GET Range bytes=-N"
  S3-->>Input: Parquet trailer
  Reader->>Input: readVectored(footer range)
  Input->>S3: GET footer byte range
  S3-->>Reader: Framed Parquet footer
Loading

Reviews (10): Last reviewed commit: "Fix build break" | Re-trigger Greptile

@liurenjie1024
liurenjie1024 marked this pull request as draft July 27, 2026 02:19
Comment thread iceberg/common/src/main/java/org/apache/iceberg/aws/s3/IcebergS3InputFile.java Outdated
Comment thread iceberg/common/src/main/java/org/apache/iceberg/aws/s3/IcebergS3InputFile.java Outdated
Signed-off-by: Ray Liu <liurenjie2008@gmail.com>
@nvauto

nvauto commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

NOTE: release/26.08 has been created from main. Please retarget your PR to release/26.08 if it should be included in the release.

@liurenjie1024

Copy link
Copy Markdown
Collaborator Author

blocked by #15360

@sameerz sameerz added the bug Something isn't working label Jul 27, 2026
@liurenjie1024
liurenjie1024 changed the base branch from main to release/26.08 July 28, 2026 05:06
@liurenjie1024 liurenjie1024 changed the title Fix missing tailRead call in iceberg Enable optimized S3 tail reads for Iceberg Parquet footers Jul 28, 2026
@liurenjie1024
liurenjie1024 marked this pull request as ready for review July 28, 2026 05:44
@liurenjie1024 liurenjie1024 changed the title Enable optimized S3 tail reads for Iceberg Parquet footers Enable optimized S3 tail reads for Iceberg Parquet footers Jul 28, 2026

@res-life res-life left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

SHOULD FIX — Remove the redundant delegate field

iceberg/common/src/main/java/org/apache/iceberg/aws/s3/IcebergS3InputFile.java:44

IcebergS3InputFile stores delegate in a private field that is never read. The constructor already passes the same InputFile to IcebergInputFile at line 54, and the superclass stores it for the inherited operations. Remove only the redundant field declaration and constructor assignment; keep the constructor parameter and super(delegate) call.

@@ -41,7 +41,6 @@ public final class IcebergS3InputFile extends IcebergInputFile {
   private static final Logger LOG = LoggerFactory.getLogger(IcebergS3InputFile.class);
 
-  private final InputFile delegate;
   private final String s3Bucket;
   private final String s3Key;
   private final IcebergS3Client icebergS3Client;
@@ -52,7 +51,6 @@ public final class IcebergS3InputFile extends IcebergInputFile {
       String s3Key,
       IcebergS3Client icebergS3Client) {
     super(delegate);
-    this.delegate = delegate;
     this.s3Bucket = s3Bucket;
     this.s3Key = s3Key;
     this.icebergS3Client = icebergS3Client;

@liurenjie1024

Copy link
Copy Markdown
Collaborator Author

build

@sameerz
sameerz requested a review from res-life July 29, 2026 00:10
res-life
res-life previously approved these changes Jul 29, 2026

@res-life res-life left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

@res-life

Copy link
Copy Markdown
Collaborator

build

@sameerz

sameerz commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

build

zpuller
zpuller previously approved these changes Jul 30, 2026
@liurenjie1024

Copy link
Copy Markdown
Collaborator Author

build

@zpuller
zpuller merged commit c69e922 into NVIDIA:release/26.08 Jul 31, 2026
55 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants