avatarG e o r g i a n

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

3955

Abstract

ike setting an alarm to wake up your application at specific intervals or conditions.</p><h1 id="b22a">1. Trigger default</h1><p id="14a0">The <b>default trigger</b> runs your query as fast as possible, processing any data as soon as it arrives. Structured Streaming defaults to fixed interval micro-batches of 500ms.</p><p id="43b3"><b>Step 1:</b> Write the Streaming query.</p><div id="15b2"><pre>writeStreamDefault = ( df.writeStream.<span class="hljs-built_in">format</span>(<span class="hljs-string">"delta"</span>) .option(<span class="hljs-string">"checkpointLocation"</span>, <span class="hljs-string">f"<span class="hljs-subst">{checkpoint_location}</span>"</span>) .outputMode(<span class="hljs-string">"append"</span>) .queryName(<span class="hljs-string">"DefaultTrigger"</span>) .toTable(<span class="hljs-string">"default.streaming_circuits"</span>) )</pre></div><p id="af52"><b>Step 2:</b> Visualize the Input and Processing Rate of the stream. First a spike is observed until the data is streamed and then the Input Rate drops to 0.</p><figure id="8f21"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*PM2gRMl-r_Okj9xciuD7fw.png"><figcaption>Write Stream Query — default</figcaption></figure><p id="3aad"><b>Step 3: </b>Data is streamed to the destination — 77 rows.</p><figure id="a10e"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*9rQVpjrZk5NfG2BqvDD83g.png"><figcaption>Data Stream to Destination Table Destination Table</figcaption></figure><p id="898f"><b>Step 4</b>: Update new batch to the same location</p><figure id="088b"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*OMmwNZD24I53XvTXT2B2jQ.png"><figcaption>Adding New Batch</figcaption></figure><p id="ada8"><b>Step 5</b>: Observe data is streamed automatically, while the stream query is still alive. The new batch is appended to the destination and the count rows is increased. A spike in Input Rate can also be observed.</p><figure id="dc75"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*sjBL9JV2KpST67SoyUC_wQ.png"><figcaption>New Batch Steam</figcaption></figure><p id="92c0"><b>Result</b>: Query discovered the new csv file in the location and streamed the data to the Delta table automatically.</p><h2 id="d605">When to Use:</h2><ul><li>Real-time use cases where low latency is crucial (e.g., detecting fraud or monitoring sensors).</li><li>The system can handle the incoming data volume.</li></ul><h1 id="cc0c">2. Trigger availableNow</h1><p id="6c6d">The <b>availableNow</b> trigger processes all the data currently available in the source and then stops. It’s like a one-time cleanup of everything in your inbox.</p><p id="8125"><b>Step 1:</b> drop the table and recreate the checkpoint location</p><div id="aee4"><pre><span class="hljs-operator">%</span><span class="hljs-keyword">sql</span> <span class="hljs-keyword">drop</span> <span class="hljs-keyword">table</span> default.streaming_circuits</pre></div><div id="ab5e"><pre>dbutils.fs.mkdirs(<span class="hljs-string">'/FileStore/tables/streaming/checkpoints'</span>)</pre></div><div id="7f42"><pre>dbutils.fs.ls(<span class="hljs-string">'/FileStore/tables/streaming/checkpoints'</span>)</pre></div><p id="de19"><b>Step 2:</b> write the Streaming query with <b>available=True</b></p><div id="dada"><pre>writeStreamAvailableNow = ( df.writeStream.<span class="hljs-built_in">format</span>(<span class="hljs-string">"delta"</span>) .option(<span class="hljs-string">"checkpointLocation"</span>, <span class="hljs-string">f"<span class="hljs-subst">{checkpoint_location}</span>"</span>) .trigger(availableNow=<span class="hljs-literal">True</span>) .outputMode(<span class="hljs-string">"append"</span>) .queryName(<span class="hljs-string">"AvailableNow"</span>) .toTable(<span class="hljs-string">"default.streaming_circuits"</span>) )</pre></div><p id="9bc1"><b>Step 3</b>: observe the be

Options

havior.</p><figure id="9bd8"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*ndXGMFg0kt2vU6Oc9Pznjw.png"><figcaption>Streamed stopped automatically</figcaption></figure><p id="9065"><b>Result:</b> here, the query processes all data available in the source and then terminates. This is a great choice when you want to process data in a “stream-like” fashion but only once.</p><h2 id="bb24">When to Use:</h2><ul><li>Migrating streaming workloads to batch.</li><li>One-off processing of historical or near-real-time data.</li></ul><h1 id="ea1e">3. Trigger processingTime</h1><p id="2ca9">The <b>processingTime</b> trigger processes data at fixed time intervals, regardless of when it arrives. Imagine a worker who checks for new tasks every 2 minutes.</p><p id="6106"><b>Step 1:</b> repeat the Step 1 from the “<b>Trigger availableNow</b>” section</p><p id="cfd1"><b>Step 2: </b>write the Streaming script with the option processingTime = “2 minutes”.</p><div id="cf98"><pre>writeStreamProcessingTime = ( df.writeStream.<span class="hljs-built_in">format</span>(<span class="hljs-string">"delta"</span>) .option(<span class="hljs-string">"checkpointLocation"</span>, <span class="hljs-string">f"<span class="hljs-subst">{checkpoint_location}</span>"</span>) .trigger(processingTime = <span class="hljs-string">"2 minutes"</span>) .outputMode(<span class="hljs-string">"append"</span>) .queryName(<span class="hljs-string">"ProcessingTime"</span>) .toTable(<span class="hljs-string">"default.streaming_circuits"</span>) )</pre></div><p id="bb81"><b>Step 3: </b>the data found in the location is processed first time at 16:12:35. The best way to observe the <b>processingTime </b>behavior is using the Spark UI</p><figure id="0fe1"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*2nEILd5k-6coJWfFNOGEyQ.png"><figcaption>First Processing Time</figcaption></figure><p id="3f0a"><b>Step 4: </b>another batch was added to the location to the location at 16:12:56, but the process didn`t streamed the data as arrived, but it consumed the data when the n<b>ext 2 minutes window started. </b>This was happening at 16:14:01</p><figure id="7711"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*Nf3Pa38o9IAx7uRhgV04LA.png"><figcaption>Next 2 Minutes Window</figcaption></figure><p id="69cc"><b>Result:</b> the query processes incoming data every 2 minutes, regardless of when it arrives. It’s ideal for workloads that prioritize efficiency over real-time responsiveness.</p><h2 id="4737">When to Use:</h2><ul><li>Use cases where you can tolerate some delay (e.g., aggregating data every 2 minutes).</li><li>Preventing resource exhaustion by batching data processing.</li></ul><h1 id="296d">Conclusion</h1><p id="d5f1">Understanding the key differences in Databricks Spark Structured Streaming triggers — <b>Default</b>, <b>processingTime</b>, and <b>availableNow</b> — is crucial for optimizing your streaming workloads. Each trigger serves specific use cases, whether it’s real-time processing with minimal latency, periodic processing for efficiency, or batch-like processing for historical data.</p><figure id="075f"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*Zpx80BaQCrdNAZSqoQwEpg.png"><figcaption>Trigger Usecases</figcaption></figure><h1 id="182d">Choosing the right trigger:</h1><ul><li><b>Choose Default</b> when latency is key and your system can handle high throughput.</li><li><b>Choose <code>processingTime</code></b> when you prefer periodic processing to balance performance and resource usage.</li><li><b>Choose <code>availableNow</code></b> for one-time analysis or batch-like scenarios on streaming sources.</li></ul><p id="a431">Enjoy Databricks and cloud computing!</p><p id="0fd0">Source: <a href="https://docs.databricks.com/en/structured-streaming/index.html">https://docs.databricks.com/en/structured-streaming/index.html</a></p></article></body>

Understanding Triggers with Databricks Spark Structured Streaming: Default, ProcessingTime, and AvailableNow

Introduction

Structured Streaming is one of the most powerful features of Apache Spark, enabling you to process data in real time. However, not all streaming scenarios are the same, and the trigger you choose can greatly affect how your data flows through your application.

In this article, I’ll walk you through three common trigger types — default, processingTime, and availableNow — using simple explanations and code examples. By the end, you’ll understand when and why to use each of them.

Information about the data set:

  1. We are going to use a Formula 1 table that contains all F1 circuits. Below is a preview
F1 — Circuits table

2. Data was uploaded to the following path in CSV format: dbutils.fs.ls(‘/FileStore/tables/streaming’)

3. Schema was created before hand to avoid automatic inference:

from pyspark.sql.types import StructType, StructField, StringType , IntegerType, FloatType

schema = StructType([   
                     StructField('circuitId',StringType()),
                     StructField('circuitRef',StringType()),
                     StructField('name',StringType()),
                     StructField('location',StringType()),
                     StructField('country',StringType()),
                     StructField('lat',FloatType()),
                     StructField('lng',FloatType()),
                     StructField('altitude',IntegerType()),
                     StructField('url',StringType())
])

4. Destination is a hive metastore table:

%sql
create table default.streaming_circuits (
  circuitId STRING,
  circuitRef STRING,
  name STRING,
  location STRING,
  country STRING,
  lat FLOAT,
  lng FLOAT,
  altitude INT,
  url STRING
) stored as parquet

5. Setup of the variables for the readStream and writeStream:

# File location and type
file_location = "/FileStore/tables/streaming"
file_type = "csv"
checkpoint_location = "/FileStore/tables/streaming/checkpoints"

# CSV options
infer_schema = "false"
first_row_is_header = "false"
delimiter = ","

df = spark.readStream.format("csv")\
        .option('header','true')\
        .schema(schema)\
        .load(file_location)

What is a trigger in the context of Databricks Spark Structured Streaming?

A trigger in Structured Streaming determines how often the streaming query runs to process incoming data. Think of it like setting an alarm to wake up your application at specific intervals or conditions.

1. Trigger default

The default trigger runs your query as fast as possible, processing any data as soon as it arrives. Structured Streaming defaults to fixed interval micro-batches of 500ms.

Step 1: Write the Streaming query.

writeStreamDefault = (
    df.writeStream.format("delta")
    .option("checkpointLocation", f"{checkpoint_location}")
    .outputMode("append")
    .queryName("DefaultTrigger")
    .toTable("default.streaming_circuits")
)

Step 2: Visualize the Input and Processing Rate of the stream. First a spike is observed until the data is streamed and then the Input Rate drops to 0.

Write Stream Query — default

Step 3: Data is streamed to the destination — 77 rows.

Data Stream to Destination Table Destination Table

Step 4: Update new batch to the same location

Adding New Batch

Step 5: Observe data is streamed automatically, while the stream query is still alive. The new batch is appended to the destination and the count rows is increased. A spike in Input Rate can also be observed.

New Batch Steam

Result: Query discovered the new csv file in the location and streamed the data to the Delta table automatically.

When to Use:

  • Real-time use cases where low latency is crucial (e.g., detecting fraud or monitoring sensors).
  • The system can handle the incoming data volume.

2. Trigger availableNow

The availableNow trigger processes all the data currently available in the source and then stops. It’s like a one-time cleanup of everything in your inbox.

Step 1: drop the table and recreate the checkpoint location

%sql
drop table default.streaming_circuits
dbutils.fs.mkdirs('/FileStore/tables/streaming/checkpoints')
dbutils.fs.ls('/FileStore/tables/streaming/checkpoints')

Step 2: write the Streaming query with available=True

writeStreamAvailableNow = (
    df.writeStream.format("delta")
    .option("checkpointLocation", f"{checkpoint_location}")
    .trigger(availableNow=True)
    .outputMode("append")
    .queryName("AvailableNow")
    .toTable("default.streaming_circuits")
)

Step 3: observe the behavior.

Streamed stopped automatically

Result: here, the query processes all data available in the source and then terminates. This is a great choice when you want to process data in a “stream-like” fashion but only once.

When to Use:

  • Migrating streaming workloads to batch.
  • One-off processing of historical or near-real-time data.

3. Trigger processingTime

The processingTime trigger processes data at fixed time intervals, regardless of when it arrives. Imagine a worker who checks for new tasks every 2 minutes.

Step 1: repeat the Step 1 from the “Trigger availableNow” section

Step 2: write the Streaming script with the option processingTime = “2 minutes”.

writeStreamProcessingTime = (
    df.writeStream.format("delta")
    .option("checkpointLocation", f"{checkpoint_location}")
    .trigger(processingTime = "2 minutes")
    .outputMode("append")
    .queryName("ProcessingTime")
    .toTable("default.streaming_circuits")
)

Step 3: the data found in the location is processed first time at 16:12:35. The best way to observe the processingTime behavior is using the Spark UI

First Processing Time

Step 4: another batch was added to the location to the location at 16:12:56, but the process didn`t streamed the data as arrived, but it consumed the data when the next 2 minutes window started. This was happening at 16:14:01

Next 2 Minutes Window

Result: the query processes incoming data every 2 minutes, regardless of when it arrives. It’s ideal for workloads that prioritize efficiency over real-time responsiveness.

When to Use:

  • Use cases where you can tolerate some delay (e.g., aggregating data every 2 minutes).
  • Preventing resource exhaustion by batching data processing.

Conclusion

Understanding the key differences in Databricks Spark Structured Streaming triggers — Default, processingTime, and availableNow — is crucial for optimizing your streaming workloads. Each trigger serves specific use cases, whether it’s real-time processing with minimal latency, periodic processing for efficiency, or batch-like processing for historical data.

Trigger Usecases

Choosing the right trigger:

  • Choose Default when latency is key and your system can handle high throughput.
  • Choose processingTime when you prefer periodic processing to balance performance and resource usage.
  • Choose availableNow for one-time analysis or batch-like scenarios on streaming sources.

Enjoy Databricks and cloud computing!

Source: https://docs.databricks.com/en/structured-streaming/index.html

Databricks
Spark Streaming
Lakehouse Architecture
Azure
Cloud Computing
Recommended from ReadMedium