Repository navigation
Conversation
When s3.assumed.role.arn is configured in server.yaml without static credentials, configure AssumedRoleCredentialProvider so that the assumed role is actually used for S3 operations (remote log, KV snapshots, lake offsets). Previously, the code only logged a message and returned without setting the credential provider, causing S3A to use ambient credentials from the default chain instead of the configured role. Closes apache#3761
Implements SupportsRecordBatchWrite for the Iceberg lake writer, enabling direct Arrow batch writing for append-only tables. This avoids the per-record LogRecord deserialization overhead by reading directly from Arrow columnar vectors. Changes: - IcebergLakeWriter now implements SupportsRecordBatchWrite - New IcebergArrowBatchHelper reads Arrow FieldVectors and produces GenericRecord objects enriched with system columns (__bucket, __offset, __timestamp), then writes through the existing TaskWriter pipeline - Added arrow-vector and arrow-memory-netty as provided dependencies - Only enabled for append-only tables (same restriction as Paimon) Closes apache#4047
|
This PR has been marked as stale because it has had no activity for 60 days. It will be closed in 10 days unless it receives a new comment, commit or other update. |
|
bump |
|
@qzyu999 Heads-up: with this PR alone, Iceberg tables would still be tiered row by row. I've opened #5223 (issue #5222) to let the tiering factory declare it instead, through |
|
Hi @mikepapadim, thanks for taking a look, unfortunately this looks heavily bottlenecked by apache/parquet-java#3734, not sure if you're willing to take a look to help push it forward. |
|
Thanks for the pointer. I benchmarked apache/parquet-java#3734 on the data from the tiering profile: TPC-H lineitem-like, 19 columns with Fluss's system columns, 16384-row Arrow batches, ZSTD. I built it against parquet 1.18.2. As is, it writes 512 MB in 2.57 s, versus 7.3 s for Fluss's Iceberg row path and 3.2 s for the Paimon writer. I also found a page-sizing issue in it. With that fixed, it takes 1.73 s and the files are 19% smaller. I've left the details on apache/parquet-java#3734 and opened the fix against your branch (qzyu999/parquet-java#1). The Fluss-side numbers are in #5227. On the Fluss side, #5223 makes the batch path reachable for Iceberg, and #5226 proposes a way to plug in an Arrow file writer. apache/parquet-java#3734 would be the obvious CPU implementation for it, so #4048 wouldn't have to wait on a parquet-java release to get the columnar path wired up. |
|
Thanks for benchmarking this, @mikepapadim! I merged your page-sizing fix into the branch for apache/parquet-java#3734. For this PR, I’ll wait for #5223 to land, then rebase and wire up the Iceberg factory so append-only Arrow tables can use the batch path. |
Summary
Implements
SupportsRecordBatchWritefor the Iceberg lake writer, enabling direct Arrow batch writing for append-only log tables during tiering. This closes the performance gap with Paimon's batch write path (landed in #3417/#3418).Closes #4047
Changes
SupportsRecordBatchWriteFieldVectorcolumns directly and produces IcebergGenericRecordobjects enriched with system columns (__bucket,__offset,__timestamp), then writes through the existingTaskWriter<Record>pipelinearrow-vectorandarrow-memory-nettyas provided dependencies (same pattern asfluss-lake-paimon)Motivation
The Paimon lake writer implements
SupportsRecordBatchWritewhich takes raw Arrow batches from Fluss internal format and writes them to Parquet viapaimon-arrow. The Iceberg path previously wrote row-by-row throughGenericRecordobjects wrappingLogRecord, requiring per-record binary deserialization.With this change, the Iceberg tiering path can read directly from Arrow columnar memory, avoiding the
LogRecord->InternalRow->FlussRecordAsIcebergRecordconversion chain for each record.Design
The helper creates typed
ArrowFieldExtractorlambdas per column based on the FlussDataType, then iterates rows reading from the pre-fetchedFieldVectorarray. This preserves the existingTaskWriterpipeline (file rolling, partition key generation, Iceberg metrics tracking) while eliminating the input-side deserialization cost.Supported types: boolean, tinyint, smallint, int, bigint, float, double, string, char, binary, bytes, decimal, date, time, timestamp, timestamp_ltz. Complex types (array, map, row) have placeholder extractors and are left as follow-up work.
Test Plan
mvn compile -pl fluss-lake/fluss-lake-iceberg -am -DskipTestsmvn spotless:checkpassesmvn checkstyle:checkpassesIcebergLakeCatalogTest,IcebergWriteResultSerializerTest,FlussToIcebergPredicateConverterTest,IcebergConfigurationTestall passArrowRecordBatchthrough the new path (follow-up)