This is an automated email from the ASF dual-hosted git repository.

viirya pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/branch-4.2 by this push:
     new 5471de05232d [SPARK-57234][4.2][SS][DOC] Add Real-time Mode 
documentation page to the Structured Streaming guide
5471de05232d is described below

commit 5471de05232d1082fee50a1d5d9424c81215600a
Author: Boyang Jerry Peng <[email protected]>
AuthorDate: Fri Jul 17 11:49:48 2026 -0700

    [SPARK-57234][4.2][SS][DOC] Add Real-time Mode documentation page to the 
Structured Streaming guide
    
    ### What changes were proposed in this pull request?
    
    This is a backport of #56314 to `branch-4.2`.
    
    This PR adds a new documentation page for **Real-time Mode** in Structured 
Streaming, introduced in Spark 4.1.0 (SPARK-53736): 
`docs/streaming/real-time-mode.md`. The page covers:
    
    - **How Real-time Mode works**: long-running tasks (one per input 
partition) that process records continuously, in contrast to the 
per-micro-batch task scheduling of the default engine.
    - **Batch duration is a checkpoint interval, not a latency target**.
    - A **comparison** with the other execution modes.
    - **Enabling Real-time Mode**: the `Trigger.RealTime(...)` API (Scala/Java) 
and the `realTime` trigger keyword argument (Python), plus the requirements to 
start (update output mode, checkpoint location, minimum batch duration).
    - **Supported queries** (stateless only), **fault tolerance** (exactly-once 
processing semantics; sinks such as Kafka provide at-least-once delivery), 
**configuration**, **examples** (Python/Scala/Java), and **caveats**.
    
    It also registers the new page in the Structured Streaming left navigation 
(`docs/_data/menu-streaming.yaml`).
    
    ### Why are the changes needed?
    
    Real-time Mode (stateless) was added in Spark 4.1.0 but has no user-facing 
documentation in the Structured Streaming programming guide. This PR adds that 
page. See SPARK-57234.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No. This is a documentation-only change.
    
    ### How was this patch tested?
    
    Documentation-only change. The new page was validated for structure (front 
matter, code tabs, Liquid `{% highlight %}` tags), internal links and in-page 
anchors, navigation-menu anchors, and ASCII-only content. All trigger API 
signatures, configuration keys and defaults, the supported-operator and sink 
lists, and error-class references were cross-checked against the Spark 4.1.0 
source (`Trigger.java`, `Triggers.scala`, `RealTimeModeAllowlist.scala`, 
`SQLConf.scala`, `KafkaMicroBatchSt [...]
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Opus 4.8)
    
    Closes #57325 from jerrypeng/backport-SPARK-57234-branch-4.2.
    
    Authored-by: Boyang Jerry Peng <[email protected]>
    Signed-off-by: Liang-Chi Hsieh <[email protected]>
---
 docs/_data/menu-streaming.yaml   |  23 ++
 docs/streaming/real-time-mode.md | 488 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 511 insertions(+)

diff --git a/docs/_data/menu-streaming.yaml b/docs/_data/menu-streaming.yaml
index b1dd02445112..7f01bb0c28cd 100644
--- a/docs/_data/menu-streaming.yaml
+++ b/docs/_data/menu-streaming.yaml
@@ -39,6 +39,29 @@
       url: 
streaming/apis-on-dataframes-and-datasets.html#recovering-from-failures-with-checkpointing
     - text: Recovery Semantics after Changes in a Streaming Query
       url: 
streaming/apis-on-dataframes-and-datasets.html#recovery-semantics-after-changes-in-a-streaming-query
+- text: Real-time Mode
+  url: streaming/real-time-mode.html
+  subitems:
+    - text: How Real-time Mode Works
+      url: streaming/real-time-mode.html#how-real-time-mode-works
+    - text: Batch Duration Is a Checkpoint Interval
+      url: 
streaming/real-time-mode.html#batch-duration-is-a-checkpoint-interval
+    - text: Comparison with Other Modes
+      url: streaming/real-time-mode.html#comparison-with-other-modes
+    - text: Enabling Real-time Mode
+      url: streaming/real-time-mode.html#enabling-real-time-mode
+    - text: Supported Queries
+      url: streaming/real-time-mode.html#supported-queries
+    - text: Fault Tolerance
+      url: streaming/real-time-mode.html#fault-tolerance
+    - text: Examples
+      url: streaming/real-time-mode.html#examples
+    - text: Configuration
+      url: streaming/real-time-mode.html#configuration
+    - text: Best Practices
+      url: streaming/real-time-mode.html#best-practices
+    - text: Caveats
+      url: streaming/real-time-mode.html#caveats
 - text: Performance Tips
   url: streaming/performance-tips.html
   subitems:
diff --git a/docs/streaming/real-time-mode.md b/docs/streaming/real-time-mode.md
new file mode 100644
index 000000000000..15731dfb36a7
--- /dev/null
+++ b/docs/streaming/real-time-mode.md
@@ -0,0 +1,488 @@
+---
+layout: global
+displayTitle: Structured Streaming Programming Guide
+title: Structured Streaming Programming Guide
+license: |
+  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.
+---
+
+* Table of contents
+{:toc}
+
+# Real-time Mode
+
+**Real-time Mode** is a new streaming execution mode introduced in Spark 4.1.0 
that
+targets ultra-low end-to-end latency with the exact same API and processing 
guarantees / semantics as the current structured streaming engine.
+It is intended for operational workloads
+that must react to data the moment it arrives, such as fraud detection, 
real-time alerting, and live
+personalization.
+
+In this release, Real-time Mode in Apache Spark supports **stateless queries** 
only -- projections,
+filters and other map-like operations, unions, and stream-static joins. 
Stateful operations such as
+streaming aggregations, deduplication, stream-stream joins, and 
`transformWithState` are not yet
+supported, but support for them is planned starting in Spark 4.3. See
+[Supported Queries](#supported-queries) for the full list.
+
+The most important thing to know: **the duration you pass to the trigger 
(default 5 minutes) is a
+checkpoint interval, not a latency target.** Records are processed and emitted 
continuously rather
+than at batch boundaries, so the trigger duration does not set latency the way 
a micro-batch interval does. See
+[Batch Duration Is a Checkpoint 
Interval](#batch-duration-is-a-checkpoint-interval).
+
+You enable Real-time Mode by setting a Real-time trigger on the streaming 
write; the rest of your
+query is unchanged. See [Enabling Real-time Mode](#enabling-real-time-mode).
+
+## How Real-time Mode Works
+
+By default, Structured Streaming runs a query as a series of small batch jobs 
-- the *micro-batch*
+model. For each micro-batch, the driver plans the batch and launches a fresh 
set of short-lived
+tasks. Those tasks read and process a bounded slice of the input, and the 
driver commits progress
+before planning the next batch. The fixed per-batch planning and 
task-scheduling overhead places a
+floor on end-to-end latency.
+
+Real-time Mode removes this per-batch overhead by launching **long-running 
tasks** -- one per input
+partition. These tasks stay alive for the duration of a (long) batch and 
process records
+continuously as they arrive. Because tasks are scheduled once per batch rather 
than once per slice
+of data, records flow through the operator pipeline (source -> transformations 
-> sink) without
+waiting for a batch boundary. End-to-end latency drops from the ~100 ms 
micro-batch floor to roughly
+the time needed to process and ship one record (often a few milliseconds).
+
+Since records never wait for a batch boundary, the batch duration mainly 
controls how often the
+query checkpoints progress -- as the next section explains.
+
+## Batch Duration Is a Checkpoint Interval
+
+In Real-time Mode, the batch duration is a **checkpoint interval, not a 
latency interval.** With the
+default 5-minute duration, the query still emits records within milliseconds; 
the 5 minutes only
+controls how often it commits progress and starts the next long-running batch. 
This is the opposite
+of the micro-batch engine, where a longer batch interval directly increases 
latency.
+
+Do not confuse the 5-minute default trigger duration with the 5-second minimum 
allowed duration
+described under [Requirements](#requirements): the former is the checkpoint 
cadence used when you do
+not specify a duration, while the latter is the smallest duration you are 
allowed to set.
+
+Choosing the batch duration is a trade-off:
+
+- A *shorter* batch duration checkpoints more often, giving finer-grained 
recovery (less work to
+  re-process after a failure). However, the query does not process data while 
it commits progress
+  and starts the next batch, so checkpointing too frequently adds more of 
these gaps, which can
+  raise tail (p99) latency, in addition to incurring more planning and commit 
overhead.
+- A *longer* batch duration checkpoints less often, reducing that overhead and 
those gaps, at the
+  cost of coarser-grained recovery (more data re-processed after a failure).
+
+The duration is set on the Real-time trigger, as shown under
+[Enabling Real-time Mode](#enabling-real-time-mode).
+
+## Comparison with Other Modes
+
+The table below summarizes how Real-time Mode relates to the default 
micro-batch engine and to the
+experimental [Continuous 
Processing](./performance-tips.html#continuous-processing) mode. See
+[How Real-time Mode Works](#how-real-time-mode-works) for the mechanism and
+[Supported Queries](#supported-queries) for the full list of supported 
operations.
+
+| Mode | Latency | Processing Guarantees | Supported operations | When to use |
+|---|---|---|---|---|
+| Micro-batch (default) | ~100 ms | Exactly-once | All streaming operations, 
including stateful | Stateful or higher-throughput workloads, or queries 
Real-time Mode does not yet support |
+| Real-time Mode | millisecond-scale | Exactly-once | Stateless today 
(map-like operations, unions, and stream-static joins); designed to support all 
query shapes, including stateful | Low-latency workloads |
+| Continuous Processing (experimental) | ~1 ms | At-least-once | Map-like only 
(projections and selections); no stateful operations | Legacy; use Real-time 
Mode instead |
+
+The **Processing Guarantees** column refers to processing semantics, defined 
under
+[Fault Tolerance](#fault-tolerance); end-to-end delivery additionally depends 
on the sink and is
+independent of the execution mode.
+
+Real-time Mode and Continuous Processing both target millisecond-scale 
latency, but they differ
+substantially:
+
+- **Continuous Processing** (introduced in Spark 2.3) is, and remains, 
experimental. It supports
+  only map-like operations -- projections and selections -- with no stateful 
operations such as
+  aggregations or joins, and it provides at-least-once guarantees. Because it 
is stateless, the
+  exactly-once *processing* guarantee discussed under [Fault 
Tolerance](#fault-tolerance) does not
+  apply to it. These constraints have limited its adoption.
+- **Real-time Mode** is designed to support all query shapes, including 
stateful operations, while
+  reusing Spark's mature components such as state management, the Catalyst 
optimizer, and the
+  existing SQL operators. It provides exactly-once processing semantics. It 
currently supports
+  stateless queries, with stateful support planned starting in Spark 4.3.
+
+For new low-latency workloads, prefer Real-time Mode over Continuous 
Processing.
+
+## Enabling Real-time Mode
+
+To run a supported query in Real-time Mode, set a **Real-time trigger** on the 
streaming write.
+Everything else in the query stays the same. For example, the following query 
reads from a Kafka
+topic, applies a stateless transformation, and writes the result to another 
Kafka topic. Records
+flow through with low latency even though the trigger is 5 minutes.
+
+<div class="codetabs">
+
+<div data-lang="python"  markdown="1">
+{% highlight python %}
+spark \
+  .readStream \
+  .format("kafka") \
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2") \
+  .option("subscribe", "input-topic") \
+  .load() \
+  .selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)") \
+  .writeStream \
+  .format("kafka") \
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2") \
+  .option("topic", "output-topic") \
+  .option("checkpointLocation", "/path/to/checkpoint") \
+  .outputMode("update") \
+  .trigger(realTime="5 minutes") \
+  .start()
+{% endhighlight %}
+</div>
+
+<div data-lang="scala"  markdown="1">
+{% highlight scala %}
+import org.apache.spark.sql.streaming.Trigger
+
+spark
+  .readStream
+  .format("kafka")
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2")
+  .option("subscribe", "input-topic")
+  .load()
+  .selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
+  .writeStream
+  .format("kafka")
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2")
+  .option("topic", "output-topic")
+  .option("checkpointLocation", "/path/to/checkpoint")
+  .outputMode("update")
+  .trigger(Trigger.RealTime("5 minutes"))  // enable Real-time Mode
+  .start()
+{% endhighlight %}
+</div>
+
+<div data-lang="java"  markdown="1">
+{% highlight java %}
+import org.apache.spark.sql.streaming.Trigger;
+
+spark
+  .readStream
+  .format("kafka")
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2")
+  .option("subscribe", "input-topic")
+  .load()
+  .selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
+  .writeStream
+  .format("kafka")
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2")
+  .option("topic", "output-topic")
+  .option("checkpointLocation", "/path/to/checkpoint")
+  .outputMode("update")
+  .trigger(Trigger.RealTime("5 minutes"))  // enable Real-time Mode
+  .start();
+{% endhighlight %}
+</div>
+
+</div>
+
+### Trigger API
+
+- *Scala and Java*: the trigger is `Trigger.RealTime(...)`, imported from
+  `org.apache.spark.sql.streaming.Trigger`. Several forms are available:
+  + `Trigger.RealTime()` -- uses the default batch duration of 5 minutes.
+  + `Trigger.RealTime("5 minutes")` -- a duration string.
+  + `Trigger.RealTime(300000)` -- the batch duration in milliseconds, as a 
`long`.
+  + `Trigger.RealTime(5, TimeUnit.MINUTES)` -- a value together with a
+    `java.util.concurrent.TimeUnit`.
+  + `Trigger.RealTime(Duration("10 seconds"))` -- a Scala 
`scala.concurrent.duration.Duration`.
+- *Python*: pass the batch duration as a string to the `realTime` keyword 
argument of `trigger()`,
+  for example `.trigger(realTime="5 minutes")`. The duration is required in 
Python.
+
+### Requirements
+
+A query must satisfy all of the following before it can start in Real-time 
Mode; each is checked when
+the query starts:
+
+- The output mode must be `update`. Any other output mode fails to start with
+  `STREAMING_REAL_TIME_MODE.OUTPUT_MODE_NOT_SUPPORTED`.
+- A `checkpointLocation` is required, as with any other Structured Streaming 
query.
+- The batch duration must be at least 
`spark.sql.streaming.realTimeMode.minBatchDuration`
+  (5000 ms, i.e. 5 seconds, by default); a shorter interval fails to start with
+  `INVALID_STREAMING_REAL_TIME_MODE_TRIGGER_INTERVAL`. The duration string 
must parse to a positive
+  interval, and month-based intervals (for example, `"1 month"`) are not 
accepted. (This 5-second
+  minimum is distinct from the 5-minute default; see
+  [Batch Duration Is a Checkpoint 
Interval](#batch-duration-is-a-checkpoint-interval).)
+
+## Supported Queries
+
+Real-time Mode supports stateless, map-like queries only.
+
+The following operations, sources, and sinks are supported as of Spark 4.1.0:
+
+- *Operations*: stateless, map-like operations are supported:
+  + Projections: `select`, `selectExpr`, `withColumn`, `drop`, and the typed 
`map` / `flatMap` Dataset operations.
+  + Selections: `where` / `filter`.
+  + Expressions that compile to a projection -- including functions such as 
`from_json` / `to_json`
+    and scalar user-defined functions (UDFs).
+  + Column generators such as `explode`.
+  + `union` of two or more *distinct* streaming sources. Referencing the same 
source DataFrame more
+    than once is not supported and fails with
+    `STREAMING_REAL_TIME_MODE.IDENTICAL_SOURCES_IN_UNION_NOT_SUPPORTED`; 
create a separate DataFrame
+    for each source instead.
+  + Stream-static joins, where a streaming DataFrame is joined with a static 
DataFrame. The static
+    side must be broadcast (use the `broadcast(...)` hint), because Real-time 
Mode does not support
+    shuffles.
+  + `withWatermark` (event-time watermark declaration) is allowed, although it 
has no effect because
+    stateful operators are not supported. This lets queries that already 
declare a watermark run in
+    Real-time Mode without modification.
+
+- *Sources*: the source must support Real-time Mode. In Apache Spark, the 
**Kafka** source supports
+  Real-time Mode. An unsupported source fails with
+  `STREAMING_REAL_TIME_MODE.INPUT_STREAM_NOT_SUPPORTED`. (The built-in `rate` 
source is not supported
+  as a Real-time source.)
+
+- *Sinks*:
+  + **Kafka** sink.
+  + **Foreach** sink (via `ForeachWriter`), for writing to arbitrary external 
systems one record at
+    a time. See [Using 
Foreach](./apis-on-dataframes-and-datasets.html#using-foreach-and-foreachbatch).
+    Note that `foreachBatch` is *not* supported, because it processes each 
batch as a whole rather
+    than one record at a time.
+  + **Console** and **memory** sinks, which are useful for development and 
debugging.
+
+  Other sinks fail with `STREAMING_REAL_TIME_MODE.SINK_NOT_SUPPORTED`.
+
+The operators and sinks used by a Real-time query are checked against an 
allowlist before the query
+starts; anything outside the allowlist fails with
+`STREAMING_REAL_TIME_MODE.OPERATOR_OR_SINK_NOT_IN_ALLOWLIST`.
+
+### Not supported
+
+Stateful operations of any kind are not supported in this release. This 
includes streaming
+aggregations, `dropDuplicates` / `dropDuplicatesWithinWatermark`, 
stream-stream joins, `repartition`
+and other operations that introduce a shuffle, and stateful operators such as
+`flatMapGroupsWithState` and `transformWithState`. Support for stateful 
operations is planned
+starting in Spark 4.3. Asynchronous progress tracking is also not supported; 
enabling it fails with
+`STREAMING_REAL_TIME_MODE.ASYNC_PROGRESS_TRACKING_NOT_SUPPORTED`.
+
+## Fault Tolerance
+
+Real-time Mode provides the same **exactly-once processing** guarantees as the 
default micro-batch
+engine. Two distinct guarantees are worth separating:
+
+- **Exactly-once processing** means every input record's effect on the state 
the engine manages (for
+  example, aggregation counts) is applied effectively once, even across 
failures and restarts.
+- **Delivery semantics** describe whether a record may be written to the 
external system more than
+  once. This is a property of the **sink**, not the execution mode.
+
+Real-time Mode is exactly-once with respect to processing. End-to-end delivery 
depends on the sink: a
+sink that performs idempotent or transactional writes can deliver 
**exactly-once**, while other sinks
+deliver **at-least-once** (duplicates are possible after a failure). The 
built-in Kafka sink provides
+at-least-once delivery, with or without Real-time Mode. Real-time Mode does 
not yet ship an
+exactly-once sink, though one can be implemented.
+
+Internally, offsets are committed at the *end* of each batch, after the 
corresponding records have
+already been written to the sink. If a query fails partway through a batch, it 
resumes from the last
+committed offsets on restart and may re-write records emitted before the 
failure. Design sinks to
+tolerate duplicates -- for example, with idempotent writes -- where 
exactly-once output matters.
+
+## Examples
+
+The following examples read from Kafka and assume a running Kafka cluster. 
Each example shows the
+same query in Python, Scala, and Java.
+
+### Stream-static join
+
+Enrich a stream by joining it with a static reference dataset. The static side 
is wrapped in
+`broadcast(...)` so the join is executed as a broadcast (map-side) join, which 
avoids a shuffle.
+
+<div class="codetabs">
+
+<div data-lang="python"  markdown="1">
+{% highlight python %}
+from pyspark.sql.functions import broadcast
+
+# Static reference data, read once as a batch DataFrame.
+reference = spark.read.format("parquet").load("/path/to/reference")
+
+spark \
+  .readStream \
+  .format("kafka") \
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2") \
+  .option("subscribe", "input-topic") \
+  .load() \
+  .selectExpr("CAST(key AS STRING) AS joinKey", "CAST(value AS STRING) AS 
value") \
+  .join(broadcast(reference), "joinKey") \
+  .writeStream \
+  .format("kafka") \
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2") \
+  .option("topic", "output-topic") \
+  .option("checkpointLocation", "/path/to/checkpoint") \
+  .outputMode("update") \
+  .trigger(realTime="5 minutes") \
+  .start()
+{% endhighlight %}
+</div>
+
+<div data-lang="scala"  markdown="1">
+{% highlight scala %}
+import org.apache.spark.sql.functions.broadcast
+import org.apache.spark.sql.streaming.Trigger
+
+// Static reference data, read once as a batch DataFrame.
+val reference = spark.read.format("parquet").load("/path/to/reference")
+
+spark
+  .readStream
+  .format("kafka")
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2")
+  .option("subscribe", "input-topic")
+  .load()
+  .selectExpr("CAST(key AS STRING) AS joinKey", "CAST(value AS STRING) AS 
value")
+  .join(broadcast(reference), "joinKey")
+  .writeStream
+  .format("kafka")
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2")
+  .option("topic", "output-topic")
+  .option("checkpointLocation", "/path/to/checkpoint")
+  .outputMode("update")
+  .trigger(Trigger.RealTime("5 minutes"))
+  .start()
+{% endhighlight %}
+</div>
+
+<div data-lang="java"  markdown="1">
+{% highlight java %}
+import static org.apache.spark.sql.functions.broadcast;
+import org.apache.spark.sql.streaming.Trigger;
+
+// Static reference data, read once as a batch DataFrame.
+Dataset<Row> reference = 
spark.read().format("parquet").load("/path/to/reference");
+
+spark
+  .readStream()
+  .format("kafka")
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2")
+  .option("subscribe", "input-topic")
+  .load()
+  .selectExpr("CAST(key AS STRING) AS joinKey", "CAST(value AS STRING) AS 
value")
+  .join(broadcast(reference), "joinKey")
+  .writeStream()
+  .format("kafka")
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2")
+  .option("topic", "output-topic")
+  .option("checkpointLocation", "/path/to/checkpoint")
+  .outputMode("update")
+  .trigger(Trigger.RealTime("5 minutes"))
+  .start();
+{% endhighlight %}
+</div>
+
+</div>
+
+### Writing to the console for development
+
+The console sink prints output to the driver's standard output and is handy 
while developing a
+query. Note that the console sink buffers each batch's rows and prints them 
when the batch commits,
+so its output appears once per batch -- here, every 30 seconds -- rather than 
continuously. This
+makes it useful for inspecting results, but it does not reflect Real-time 
Mode's true per-record
+latency; to observe that, use a row-by-row sink such as Kafka. A shorter batch 
duration simply makes
+the console refresh more often.
+
+<div class="codetabs">
+
+<div data-lang="python"  markdown="1">
+{% highlight python %}
+spark \
+  .readStream \
+  .format("kafka") \
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2") \
+  .option("subscribe", "input-topic") \
+  .load() \
+  .selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)") \
+  .where("value IS NOT NULL") \
+  .writeStream \
+  .format("console") \
+  .option("checkpointLocation", "/path/to/checkpoint") \
+  .outputMode("update") \
+  .trigger(realTime="30 seconds") \
+  .start()
+{% endhighlight %}
+</div>
+
+<div data-lang="scala"  markdown="1">
+{% highlight scala %}
+import org.apache.spark.sql.streaming.Trigger
+
+spark
+  .readStream
+  .format("kafka")
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2")
+  .option("subscribe", "input-topic")
+  .load()
+  .selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
+  .where("value IS NOT NULL")
+  .writeStream
+  .format("console")
+  .option("checkpointLocation", "/path/to/checkpoint")
+  .outputMode("update")
+  .trigger(Trigger.RealTime("30 seconds"))
+  .start()
+{% endhighlight %}
+</div>
+
+<div data-lang="java"  markdown="1">
+{% highlight java %}
+import org.apache.spark.sql.streaming.Trigger;
+
+spark
+  .readStream()
+  .format("kafka")
+  .option("kafka.bootstrap.servers", "host1:port1,host2:port2")
+  .option("subscribe", "input-topic")
+  .load()
+  .selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
+  .where("value IS NOT NULL")
+  .writeStream()
+  .format("console")
+  .option("checkpointLocation", "/path/to/checkpoint")
+  .outputMode("update")
+  .trigger(Trigger.RealTime("30 seconds"))
+  .start();
+{% endhighlight %}
+</div>
+
+</div>
+
+## Configuration
+
+| Configuration | Default | Meaning |
+|---|---|---|
+| `spark.sql.streaming.realTimeMode.minBatchDuration` | `5000` (ms, 5 seconds) 
| The minimum batch duration, in milliseconds, allowed for a Real-time trigger. 
See the batch-duration requirement under [Requirements](#requirements). |
+| `spark.sql.streaming.realTimeMode.allowlistCheck` | `true` | Whether to 
verify that all operators and sinks used by a Real-time query are in the 
supported allowlist. Disabling this check (not recommended) lets unsupported 
operators and sinks run at your own risk. |
+
+## Best Practices
+
+- Real-time Mode launches long-running tasks -- one per input partition -- 
that continuously read,
+  process, and write data. The number of tasks a query needs depends on how 
many partitions it reads
+  from its sources in parallel. Before starting a Real-time query, ensure the 
cluster has enough
+  cores to run all of these tasks simultaneously and continuously. For 
example, reading from a Kafka
+  topic with 10 partitions requires at least 10 cores for the query to make 
progress. Real-time Mode
+  uses a fixed 1:1 mapping between Kafka topic partitions and reader tasks; 
the `minPartitions`
+  option is not supported in Real-time Mode.
+- Run a single Real-time query per cluster. Because Real-time Mode holds its 
task slots for the
+  entire batch duration, any other queries sharing the cluster compete for the 
same slots, which can
+  starve the Real-time query of resources and increase its latency.
+
+## Caveats
+
+- Real-time Mode provides exactly-once processing semantics, but sinks may 
receive duplicate records
+  after a failure. See [Fault Tolerance](#fault-tolerance) for how to design 
sinks for exactly-once
+  writes.
+- Adaptive Query Execution (AQE) is not supported for Real-time Mode queries.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to