Skip to content

[Enhancement] Support negative acknowledgement (nack) with Key_Shared subscriptions while preserving ordering #23480

Description

@lhotari

Search before asking

  • I searched in the issues and found nothing similar.

Motivation

Key_Shared subscriptions don't currently support negative acknowledgements (nack).
Consumers can get stuck with Key_Shared subscriptions in all previous versions of Pulsar before 4.0.0.
With Pulsar 4.0.0, the consumers will no longer get stuck due to using nacks. This has been addressed with PIP-379: Key_Shared Draining Hashes for Improved Message Ordering improvements. However, in Pulsar 4.0.0, the nacked messages will get relivered after a delay without considering the ordering.
There's a need to also preserve ordering when using nacks in Key_Shared subscriptions.

Solution

A complete solution would require changes to the Pulsar binary protocol in addition to changes in both the broker and the client, since both sides would need to cooperate to hold back messages for a key. This increases the implementation and rollout effort considerably, as protocol changes also raise compatibility concerns across broker and client versions.

Alternatively, a purely client-side implementation is possible. The high-level idea:

  1. When a message is nacked, the client retains the nacked message and buffers any subsequently received messages with the same key.
  2. Delivery of buffered messages for that key is paused until the nacked message has been redelivered (handled entirely on the client side) and successfully acknowledged.
  3. Once the nacked message is acknowledged, the buffered messages for the key are delivered in order.

The main limitation of a client-side-only approach is flow control: since the broker isn't aware of the nack semantics, it keeps dispatching messages for the affected key, and the consumer could eventually run out of permits if there's a large volume of messages for that key. In that sense, the primary benefit of adding broker-side (and protocol-level) support would be avoiding permit exhaustion, since the broker could hold back messages for the key instead of pushing them to the client.

Until this feature is implemented, applications can achieve similar behavior themselves: retry the failed message in application code and defer processing of any further messages for the same key until the original message has been processed successfully. This has the same drawback as the client-side approach — messages for the key aren't held back on the broker side, so a consumer's permits could still run out.

Alternatives

No response

Anything else?

No response

Are you willing to submit a PR?

  • I'm willing to submit a PR!

Metadata

Metadata

Assignees

Labels

type/enhancementThe enhancements for the existing features or docs. e.g. reduce memory usage of the delayed messages

Type

No type

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions