comphead commented on code in PR #205:
URL: https://github.com/apache/datafusion-site/pull/205#discussion_r4137711211
##########
content/blog/2026-10-01-datafusion-comet-1.1.0.md:
##########
@@ -0,0 +1,607 @@
+---
+layout: post
+title: Apache DataFusion Comet 1.1.0 Release
+date: 2026-10-01
+author: pmc
+categories: [subprojects]
+---
+
+<!--
+{% comment %}
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+{% endcomment %}
+-->
+
+[TOC]
+
+The Apache DataFusion PMC is pleased to announce version 1.1.0 of the
[Comet](https://datafusion.apache.org/comet/) subproject.
+
+Comet is an accelerator for Apache Spark that translates Spark physical plans
to DataFusion physical plans for
+improved performance and efficiency without requiring any code changes.
+
+This release covers roughly seven weeks of development since 1.0.0: 398
commits from 40 contributors. See the
+[change log] for the full list of changes.
+
+[change log]:
https://github.com/apache/datafusion-comet/blob/branch-1.1/docs/source/changelog/1.1.0.md
+
+The highlights:
+
+- **Native Iceberg writes** (experimental): Comet can write Iceberg data files
with iceberg-rust instead of
+ iceberg-java.
+- **Memory management**: Comet now measures the native memory its pools don't
track, logs it on every executor,
+ and fixes several long-standing pool accounting bugs.
+- **Native shuffle over Apache Celeborn**: Comet's side is in place, but it
needs a Celeborn client API that no
+ released Celeborn version provides yet.
+- **Native Parquet writes on Spark 4.0+** (experimental), now built on Spark's
own write path.
+
+## Native Iceberg Writes (Experimental)
+
+Until now, Comet accelerated Iceberg reads but left writes to the JVM. In
1.1.0, Comet can write Iceberg data
+files natively using [iceberg-rust](https://github.com/apache/iceberg-rust).
The feature is **experimental and
+disabled by default**, and it only engages under fairly strict conditions.
+
+### Splitting the write operator
+
+Spark writes an Iceberg table with a single operator that writes the data
files, writes the metadata, commits,
+and validates against the catalog. Adaptive Query Execution (AQE) re-plans the
query feeding that operator, but
+the operator itself sits outside AQE, so the file writing can't adapt to how
its input actually ran. And because
+file writing is bundled with the metadata and commit steps, there is no
separate piece for Comet to take over.
+
+Setting `spark.comet.write.iceberg.splitOperator.enabled=true` splits eligible
writes into two operators:
+
+1. **`IcebergWrite`** writes data files on the executors and returns each
task's commit message. It runs inside
+ AQE, along with the query feeding it.
+2. **`IcebergCommit`** collects the commit messages on the driver and performs
the normal Iceberg commit, once,
+ outside AQE.
+
+On its own, the split doesn't change who writes the files; that's still
iceberg-java. It moves file writing inside
+AQE and separates it from the commit, which gives the native writer a place to
plug in. It covers `INSERT INTO`
+and DataFrame `append`, static and dynamic `INSERT OVERWRITE`, and
copy-on-write `DELETE`, `UPDATE`, and `MERGE`,
+on every supported Spark version. Merge-on-read writes are left alone. When
Comet can't split a write (an
+unrecognized write class, CTAS on Spark 3.4, or a write that needs Spark's
commit coordinator), it plans the write
+exactly as if Comet weren't there.
+
+### Writing Parquet natively
+
+Also setting `spark.comet.iceberg.write.enabled=true` hands each task's
Parquet writing to iceberg-rust. The
+driver passes the native writer everything it needs: schema, partition spec,
data location, Parquet settings,
+writer mode, and object-store configuration. Each task writes its files and
returns their metadata as an
+in-memory Iceberg manifest.
+
+From there, iceberg-java takes over again. The JVM reads the manifest,
recomputes each file's metrics from its
+Parquet footer, and builds the same commit message the JVM writer would have
produced. Snapshots, manifest
+lists, commit validation, and retries all work as before.
+
+The native writer consumes Arrow batches from a Comet operator, so the query
feeding the write must run in Comet
+too. Writes from a local relation, such as `INSERT ... VALUES`, also need
+`spark.comet.exec.localTableScan.enabled=true`.
+
+To see which path a write took, check the physical plan: a native write shows
`CometIcebergWrite` under
+`IcebergCommit`, and a write that fell back shows `IcebergWrite`.
+
+### Matching iceberg-java
+
+The goal is the table iceberg-java would have written, not just a valid one.
Manifest metrics drive pruning for
+every future reader, so rather than trust the native writer's numbers, Comet
recomputes them with iceberg-java's
+own code. Parity tests write the same rows through both writers and compare
the committed counts and bounds. The
+cost is one small footer read per file.
+
+Eligibility is an allowlist. A write goes native only if its whole
configuration matches the documented set of
+supported settings. Anything else, including properties added by future
Iceberg versions, falls back to
+iceberg-java and reports why in Comet's extended `EXPLAIN` output. Encryption,
object-storage layout, custom
+location providers, bloom filters, and unrecognized `parquet.*` properties all
fall back. For a partitioned
+table, Iceberg asks Spark to cluster and sort rows by partition value, such as
`bucket(16, id)` or `days(ts)`,
+before writing. That step must also run natively, which it now can because
Iceberg's system functions have
+native implementations.
+
+Comet decides all of this at planning time, including checking that every
iceberg-java class it relies on is
+where it expects. An Iceberg release that moves one falls back instead of
failing tasks mid-write. CI also runs
+Apache Iceberg's own Spark test suites, for Iceberg 1.8.1 through 1.11.0, with
the native writer enabled.
+
+### Failure handling
+
+Only successful tasks' commit messages are committed. A failed task deletes
the files it wrote, as iceberg-java
+does, and a failed job commits nothing and deletes the completed tasks' files.
Retries can't collide, because
+each attempt's ID is part of its file names. Anything cleanup misses is
invisible to readers and is removed by
+Iceberg's normal `remove_orphan_files` maintenance.
+
+### Known differences
+
+Files written by parquet-rs, the Rust Parquet library iceberg-rust uses,
differ from those written by
+parquet-java (formerly parquet-mr), which iceberg-java uses. Enabling the
feature accepts these differences.
+Most are cosmetic, such as footer metadata, `created_by`, and page encoding
labels. Two are worth knowing about:
+
+- **Files won't split at the same points.** Both writers check file size every
1000 rows, but they estimate it
+ differently, so they can roll over to a new file at different rows.
+- **High-cardinality columns keep a dictionary page.** parquet-java drops
dictionary encoding early when it isn't
+ saving space, while parquet-rs keeps it up to
`write.parquet.dict-size-bytes`. Results are the same, but
+ selective reads of native-written files fetch more bytes
+ ([#6114](https://github.com/apache/datafusion-comet/issues/6114)).
+
+The [Iceberg Writes guide] lists every supported setting and every difference.
Please try it on a non-production
+table and tell us how it goes. Feedback from real workloads is what this
feature needs before it loses the
+experimental label.
+
+Thanks to [@jordepic] for designing and implementing the split-operator plan,
write detection, and the native
+writer, and to [@andygrove] for the fidelity and failure-handling work, with
contributions from
+[@zhangfengcdt], [@snmvaughan], [@liupoyi-1031], and [@0lai0], and reviews
from [@sunchao], [@comphead],
+[@unikdahal], and [@mbutrovich]. Related PRs: [#4658], [#5298], [#5361],
[#5663], [#5780].
+
+[Iceberg Writes guide]:
https://datafusion.apache.org/comet/user-guide/latest/iceberg-writes.html
+
+## Memory Management
+
+A recurring problem for Comet users has been executors killed by the cluster
manager (on Kubernetes,
+`ExecutorLostFailure` with exit code 137) even though Comet stayed within its
memory pool. 1.1.0 explains why
+this happens, lets you measure it, and fixes pool bugs that made it worse.
+
+### Where the memory goes
+
+Comet's native operators allocate from the Rust heap but charge their
reservations against Spark's off-heap
+pool, sized by `spark.memory.offHeap.size`. Operators only reserve memory for
data they deliberately hold onto:
+sort buffers, hash join build sides, aggregation state, and buffered shuffle
partitions.
+
+Plenty of memory is never reserved: working memory in expression kernels,
decompression buffers, Parquet reader
+state, object store buffers, JVM-side Arrow buffers, and allocator overhead.
All of it has to fit in
+`spark.executor.memoryOverhead`, and until now there was no way to see how
much of it there was.
+
+<img
+src="/blog/images/comet-1.1.0/comet-executor-memory.svg"
+width="100%"
+class="img-fluid"
+alt="The executor container holds the JVM heap, the off-heap memory pool, and
the memory overhead. Spark and Comet share the off-heap pool, where Comet's
sorts, joins, aggregations, and shuffles reserve memory. The memory overhead
holds the JVM's own overhead plus Comet's native memory that the pool does not
track."
+/>
+
+### Measuring it
+
+Comet now wraps its native allocator in a counter that tracks every byte
allocated and not yet freed. It only
+observes and never rejects an allocation. Arrow buffers the JVM imports from
native code are now tracked
+separately, so they aren't counted twice.
+
+Each executor uses the counter to log its native memory usage every 10 seconds
while Comet runs:
+
+```
+Comet native memory usage: allocated 5412.3 MiB, reserved 3890.0 MiB (16
native plans, 8 memory pools)
+```
+
+`reserved` is what the pools track, and the container already has room for it.
`allocated` is everything
+Comet's native code holds. The difference is what has to fit in
`spark.executor.memoryOverhead`, next to the
+JVM's own non-heap memory. To size the overhead, run a representative
workload, take the largest difference from
+the log, add it to the overhead you had before Comet, and leave a margin.
Setting
+`spark.comet.memory.logInterval=1s` for that run makes it less likely to miss
a short peak.
+
+The executor also warns when its native memory looks larger than the container
allows, and the
+[tuning guide] walks through sizing with examples. One gotcha: setting
`spark.executor.memoryOverhead`
+_replaces_ the value Spark derives from `spark.executor.memoryOverheadFactor`
instead of adding to it, so on a
+large executor it can shrink the container. For large executors, raise the
factor instead.
+
+[tuning guide]:
https://datafusion.apache.org/comet/user-guide/latest/tuning/memory.html
+
+In 1.0.0, the driver plugin tried to raise `spark.executor.memoryOverhead` for
you, but on most Spark versions
+the change never reached the container, so it has been removed. The driver now
warns when neither the overhead
+nor the factor is set, except in local mode.
Review Comment:
this paragraph prob can be removed it doesn't announce anything
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]