[ 
https://issues.apache.org/jira/browse/KAFKA-20887?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18107378#comment-18107378
 ] 

md tanwir edited comment on KAFKA-20887 at 8/29/26 10:40 AM:
-------------------------------------------------------------

https://github.com/apache/kafka/pull/23255


was (Author: JIRAUSER314232):
https://github.com/apache/kafka/pull/21674

> IQ metadata is incomplete during "streams" protocol rebalances, causing 
> incorrect IQ results
> --------------------------------------------------------------------------------------------
>
>                 Key: KAFKA-20887
>                 URL: https://issues.apache.org/jira/browse/KAFKA-20887
>             Project: Kafka
>          Issue Type: Bug
>          Components: streams
>    Affects Versions: 4.1.0
>            Reporter: Matthias J. Sax
>            Assignee: md tanwir
>            Priority: Critical
>              Labels: needs-kip
>
> Setting "Affects Version" to 4.1.0, even if "streams" is only "early access" 
> in 4.1.0, and should not be used in production.
> Using the new "streams" groups, KafkaStreams#queryMetadataForKey() can 
> compute the wrong partition for a key *_during a rebalance_* and return the 
> wrong host, so IQ may return a "not found" for a keys that exist. Note, this 
> is not an exception, but an incorrectly empty query result. This problem is 
> affecting all IQ queries across IQv1 and IQv2, leading to incorrect query 
> results that the user cannot detect.
> *Root cause*
> The client infers each source topic's partition count from the reported "host 
> endpoint information":
>  - StreamThread → getTopicPartitionInfo(activeHostInfoMap) → 
> StreamsMetadataState#onChange → partitionsByTopic
>  - SourceTopicsInfo#maxPartitions = partitionsByTopic.get(topic).size()
>  - keyQueryMetadataForKey passes maxPartitions to 
> StreamPartitioner#partitions as the modulo
> This assumes every task is present in the reported "host endpoint" metadata 
> at all times. In the "classic" protocol this invariant is guaranteed — 
> partitionsByHost is built from the assignor's complete target 
> (StreamsPartitionAssignor Step Three), before cooperative revocation 
> withholds anything.
> However, it does not hold for the "streams" protocol. 
> EndpointToPartitionsManager builds each EndpointToPartitions entry from that 
> member's current assignedTasks(), and during reconciliation a migrating task 
> sits in the old owner's tasksPendingRevocation — in no member's 
> assignedTasks(), so in no entry at all.
> It was a deliberate improvement via KIP-1071 (and the impact on IQ was 
> missed): if a task is not assigned, IQ metadata should not claim it is, 
> resulting in spurious user facing exception ("task migrated to another 
> instance"), requiring user-code retries.
> *Impact*
> An in-flight task on a 4-partition topic drops the count to 3, so keys hash % 
> 3 instead of % 4. Roughly 75% of keys resolve to a wrong partition, and each 
> maps to a host that legitimately owns that partition — live, store open — 
> which may answers "key not found". No exception, no retry signal. Only the 
> migrating partition's own keys should have been unavailable.
> *Proposal*
> Have the broker send the missing information in StreamsGroupHeartbeatResponse 
> instead of the client inferring it — e.g. a field "unassigned partitions" or 
> similar as part of `EndpointInformationEpoch` field, so the client's existing 
> derivation keeps working with minimal client-side change.
> Deriving the topic/partition metadata from the "host metadata" map was a 
> deliberate choice to avoid an extra RPC from the client to the broker to 
> fetch topic metadata, so having the client query the cluster is not the 
> desired direction.
> *Note:* The new fields must also consider tasks assigned to a client with 
> `application.server=null`. – These tasks are filtered out from the "host 
> endpoint" map, too.
> The `application.server` issue is actually a long standing bug also affecting 
> "classic". It's a corner case, of a mis-configured application. Applications 
> should be configured such that all KafkaStreams clients set 
> `application.server` or none; a mixed configuration is a wrong config – 
> nevertheless, it should not break IQ's correctness, but rather only result in 
> that the client with the missing config cannot be queried, ie, some tasks 
> would be unavailable for IQ. We can fix this "for free" for the "streams" 
> case when we do this ticket. Cf the linked ticket for "classic" which must 
> get its own fix independently. Of course, the client side code (which is 
> shared across both protocols) must be setup such that is works for both 
> "streams" and "classic" case. Thus, as long as it's not fixed for "classic", 
> we need to still ensure that the code does not crash for "classic" if we fix 
> it for "streams".



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

Reply via email to