[ 
https://issues.apache.org/jira/browse/SPARK-58774?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

ASF GitHub Bot updated SPARK-58774:
-----------------------------------
    Labels: kafka pull-request-available structured-streaming usability  (was: 
kafka structured-streaming usability)

> Support topic-level earliest/latest values in the Kafka source 
> startingOffsets/endingOffsets JSON
> -------------------------------------------------------------------------------------------------
>
>                 Key: SPARK-58774
>                 URL: https://issues.apache.org/jira/browse/SPARK-58774
>             Project: Spark
>          Issue Type: Improvement
>          Components: Structured Streaming
>    Affects Versions: 4.2.0
>            Reporter: Joaquín Antonio De Vicente López
>            Priority: Minor
>              Labels: kafka, pull-request-available, structured-streaming, 
> usability
>
> h2. Problem
> The Kafka source accepts {{startingOffsets}} in three forms:
>  * {{"earliest"}} — applies to every subscribed topic-partition
>  * {{"latest"}} — applies to every subscribed topic-partition
>  * a JSON object mapping every topic-partition to an explicit offset, where
> {{-2}} means earliest and {{-1}} means latest
> There is no way to express "earliest for topic A, latest for topic B".
> In steady state this rarely matters: a single {{"earliest"}} or {{"latest"}}
> covers the whole subscription, which is why {{subscribePattern}} works well
> today. The gap becomes acute during incident recovery or a targeted replay, 
> when
> one topic has to be rewound while the others stay where they are — precisely 
> the
> moment when hand-editing a multi-thousand-character string is most 
> error-prone.
> As soon as two topics need different starting positions, the only option is 
> the
> fully enumerated JSON, and every partition of every topic must be listed
> explicitly. On a production cluster with 24 partitions per topic and 5 
> subscribed
> topics, that is 120 entries whose only content is the sentinel {{{}-2{}}}:
> {code:none}
> startingOffsets={"topicA":{"0":-2,"1":-2,"2":-2,...,"23":-2},
>                  "topicB":{"0":-2,"1":-2,"2":-2,...,"23":-2},
>                  "topicC":{"0":-1,"1":-1,"2":-1,...,"23":-1}}
> {code}
> This has several practical drawbacks:
>  # *Verbosity.* The value is a single-line JSON string of several thousand
> characters. In {{.properties}} or YAML configuration this is a frequent
> source of accidental line breaks, which silently truncate the value and
> surface as a confusing \{{IllegalArgumentException: Expected e.g. 
> {"topicA":\{"0":23,"1":-1}
> ,"topicB":\{"0":-2}}}}.
>  # *Opacity.* {{-1}} and {{-2}} are magic numbers. A reviewer looking at 120
> occurrences of {{-2}} cannot tell at a glance that the intent was simply
> "earliest", and a single mistyped {{-1}} in the middle of the block silently
> changes the semantics for one partition.
>  # *Brittleness under repartitioning.* The JSON hard-codes the partition 
> count.
> If a topic is expanded from 24 to 32 partitions, the enumerated set no longer
> matches the assigned one and the query fails to start with
> {{KAFKA_START_OFFSET_DOES_NOT_MATCH_ASSIGNED}} ("Partitions specified for 
> Kafka
> start offsets don't match what are assigned"). Failing loudly is the right
> behaviour, but the only remedy is to hand-edit the multi-thousand-character
> string after every repartitioning.
>  # *No composability.* The all-or-nothing nature means that wanting a 
> different
> position for a single topic forces explicit enumeration of all the others.
> h2. Proposal
> Allow the value associated with a topic key to be the string {{"earliest"}} or
> {{{}"latest"{}}}, in addition to the existing partition-to-offset object:
> {code:none}
> startingOffsets={"topicA":"earliest","topicB":"earliest","topicC":"latest"}
> {code}
> Mixed forms would be accepted, so per-partition control remains available 
> where
> it is actually needed:
> {code:none}
> startingOffsets={"topicA":"earliest",
>                  "topicB":{"0":1234,"1":-2,...,"23":-2},
>                  "topicC":"latest"}
> {code}
> Semantics: a topic-level {{"earliest"}} is equivalent to writing {{-2}} for
> every partition of that topic that is assigned to the query at the time 
> offsets
> are resolved; {{"latest"}} is equivalent to {{{}-1{}}}. Because the expansion
> happens against the discovered partition set rather than against a hard-coded
> list, no edit is needed when the partition count changes: batch queries 
> resolve
> on every run, and streaming queries on start. Partitions appearing later 
> within
> a running streaming query keep the existing behaviour of starting at earliest.
> The same syntax should apply to {{endingOffsets}} for batch queries, for
> symmetry.
> As today, the JSON has to account for every topic subscribed at the moment the
> offsets are resolved, so with {{subscribePattern}} the matched topics must be
> known then. Topics matched later are discovered as new partitions, exactly as
> with the enumerated form.
> h2. Backwards compatibility
> The change is purely additive. The topic-level value is disambiguated by JSON
> type: an object continues to be parsed as a partition-to-offset map, while a
> string is the new shorthand. Existing configurations are unaffected, and no
> currently valid document changes meaning.
> An unrecognised string value should be rejected at parse time with a message
> naming the accepted values, rather than being silently ignored.
> Likewise, a topic-level entry naming a topic with no assigned partition should
> be rejected rather than expanding to nothing, so that a typo in a topic name
> cannot silently cause the query to read less than intended.
> I am happy to work on a patch if the approach seems reasonable.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

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

Reply via email to