Skip to content

docs: Dekaf consumer behaviors + Spark Structured Streaming guidance#3094

Open
jwhartley wants to merge 1 commit into
masterfrom
docs/dekaf-consumer-spark
Open

docs: Dekaf consumer behaviors + Spark Structured Streaming guidance#3094
jwhartley wants to merge 1 commit into
masterfrom
docs/dekaf-consumer-spark

Conversation

@jwhartley

Copy link
Copy Markdown
Contributor

What

Extends using-dekaf.md with consumer guidance that has come up repeatedly in support, in two layers:

  1. Consumer behaviors to know (any client): offsets are journal byte positions; the advertised latest offset can transiently move backward during a broker hand-off and is not data loss (with how to confirm via flowctl collections read); Avro logicalType decoding (e.g. uuid -> UUID object); parallelism via journal splits.
  2. Reading from Apache Spark Structured Streaming: avoid maxOffsetsPerTrigger (byte-budget cap drops partial records), handle failOnDataLoss (it aborts on the transient backward-offset case), and set spark.sql.avro.datetimeRebaseModeInRead explicitly (PERMISSIVE silently nulls pre-Gregorian dates, SPARK-31404). Plus an example reader config.

Why

These are recurring, non-obvious Dekaf consumer issues. The byte-offset model, the transient latest-offset regression, and the Avro decoding traps each surfaced as "missing data" reports that turned out to be consumer-side or transient. The transient-latest behavior is tracked in #3092.

Part 1 lives with the general consumer guidance so non-Spark consumers (Flink, librdkafka, kcat) benefit too; Part 2 is the Spark-specific config that builds on it.

Notes

  • Single file changed, no code. Generic content, no customer specifics.

Add a 'Consumer behaviors to know' section to using-dekaf.md (offsets are
journal byte positions; the advertised latest offset can transiently move
backward on a broker hand-off and is not data loss; Avro logicalType
decoding; parallelism via journal splits) and a 'Reading from Apache Spark
Structured Streaming' section (avoid maxOffsetsPerTrigger, handle
failOnDataLoss, set the Avro datetime rebase mode explicitly).
@github-actions

Copy link
Copy Markdown

🚀 Preview deployed to https://docs.estuary.dev/pr-preview/pr-3094/

📄 Changed pages:

@jwhartley jwhartley requested review from aeluce and jshearer June 30, 2026 02:50

@aeluce aeluce 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.

Super helpful to collect these from real support cases, thanks!

Had some minor suggestions, though fine from my end to continue without them.

silently drop records that fail to decode — switch to a strict or fail-fast mode to surface
the error rather than discarding the record.

## Consumer behaviors to know

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.

Suggested change
## Consumer behaviors to know
## Consumer behaviors

Minor nit that anything in docs is something we think someone should know so we could leave that part off. Would affect anchor links further down the doc.

collection into more journals. A split only distributes data written after it; to spread an
existing backlog across the new journals you also need to re-backfill from the source. A
split is a collection-level change, so every materialization on the collection sees the new
journals (non-breaking). Contact Estuary support before splitting a production collection.

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.

Will journal auto-splitting for v2 affect this advice?


### Set the Avro datetime rebase mode explicitly

Spark's `PERMISSIVE` Avro mode silently nulls values it cannot parse, including dates before

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.

This section doesn't scan super easily and may be difficult to parse. What do you think of reordering it like this?

Spark's `PERMISSIVE` Avro mode silently nulls values it cannot parse, so affected records
look empty or missing. Use `FAILFAST` while debugging to surface the real error. You can
then choose how you'd like to handle these values.

For example, dates before the Gregorian cutover, like `1582-10-15`, cannot be parsed with
permissive null-ing. With `FAILFAST`, the underlying
`INCONSISTENT_BEHAVIOR_CROSS_VERSION.READ_ANCIENT_DATETIME` error is exposed,
and you can set `spark.sql.avro.datetimeRebaseModeInRead` to handle old datetime values:
* Use `CORRECTED` to read values as-is
* Use `LEGACY` to rebase across the calendar difference

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants