Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dapr PubSub API: Trim Redis stream when TTL is set #3664

Open
alicejgibbons opened this issue Feb 11, 2025 · 10 comments
Open

Dapr PubSub API: Trim Redis stream when TTL is set #3664

alicejgibbons opened this issue Feb 11, 2025 · 10 comments
Labels
kind/enhancement New feature or request

Comments

@alicejgibbons
Copy link

Describe the feature

Dapr should trim the pubsubs in redis streams honoring TTL.

When using redis streams, redis data is not purged once TTL expires. It's needed to write a custom cleaner, but this cleaner does not have visibility to the requested TTL for the message (and the cleaner would break once implementation details from dapr change).

Release Note

RELEASE NOTE: ADD Redis streams TTL deletes messages.

@elena-kolevska
Copy link
Contributor

dapr/dapr#6948

@elena-kolevska
Copy link
Contributor

elena-kolevska commented Mar 13, 2025

The problem users reported here was high memory usage for Redis topics.

Currently, when a message can't be processed, or expires based on its TTL, Dapr copies it to a Dead Letter Queue (DLQ), if one is configured, but it doesn't delete it from the original topic.

Redis streams work as an append-only-log and even though users have the possibility to delete messages from it, removal is not done automatically when a message is acknowledged. For reference, Kafka and AWS SQS behave the same, while RabbitMQ, ASB or Pulsar for example, do remove messagea after acknowledged.

I see two possible options:

  • We add a component-level config option (specifically for Redis) to delete messages when acknowledged (deleteOnACK)
  • We add a component-level config option specifically for Redis to continuously trim both topics and the DLQ based on number of entries or time (docs)

@alicejgibbons
Copy link
Author

We add a component-level config option (specifically for Redis) to delete messages when acknowledged (deleteOnACK)
We add a component-level config option specifically for Redis to continuously trim both topics and the DLQ based on number of entries or time (docs)

QQ on deleteOnACK:

  • Moving to DLQ is considered an "ACK" correct?
  • This method would allow a case where no consumer ever connects to the broker but if the TTL was set, still wouldn't fill up the memory, correct?

@elena-kolevska
Copy link
Contributor

Moving to DLQ is considered an "ACK" correct?

It's actually the opposite, we move messages to the DLQ when they can't be processed (and thus acknowledged).

This method would allow a case where no consumer ever connects to the broker but if the TTL was set, still wouldn't fill up the memory, correct?

Yes, if the trim option would be enabled, the trimming will happen every time a message is added to the queue.

@elena-kolevska
Copy link
Contributor

I'm gonna move forward implementing option number two above: "We add a component-level config option specifically for Redis to continuously trim both topics and the DLQ based on number of entries or time (docs)"

@elena-kolevska elena-kolevska self-assigned this Mar 18, 2025
@mikeee mikeee moved this from Backlog to Assigned in v1.16 Release Tracking Board Mar 18, 2025
@alicejgibbons
Copy link
Author

We add a component-level config option specifically for Redis to continuously trim both topics and the DLQ based on number of entries or time (docs)

Okay perfect, as we discussed that the second option is more "redis-like" I think it makes sense to go this route. Plus it would give the option for when no consumers ever connect to the pubsub broker, it still wouldn't fill up.

As an aside i do like the deleteOnACK option for an option across ALL stream-like message brokers that don't do this by default.

@elena-kolevska
Copy link
Contributor

So we already supported maxLenApprox (keeps the stream capped at X elements). I added the option to cap by time (entries older than X will be deleted).

@fsedano
Copy link

fsedano commented Mar 20, 2025

Thanks @alicejgibbons and @elena-kolevska - Going the route of delete older than X looks great to me. I'm not sure how 'deleteonAck' would work since it could be many subscribers consuming from the same message.

However, if we're thinking on setting max age per component this won't really work well for our use case. I was expecting per-message or at least per topic. I.e honor the metadata.ttlInSeconds data on the message.

Thanks,

@alicejgibbons
Copy link
Author

@fsedano in this case could you use a separate Dapr component per topic? Then if there was only one topic per component, the maxLenApprox and minIDApprox would trim those streams at the topic level

@elena-kolevska
Copy link
Contributor

I think we can also consider using something like the maxLenApprox and minIDApprox fields in the metadata of the PublishRequest. Because the trimming in Redis happens every time we add a message to the queue, this would be a great way to do it on a topic level.

@mikeee mikeee moved this from Assigned to Backlog in v1.16 Release Tracking Board Mar 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement New feature or request
Projects
Status: Backlog
Development

No branches or pull requests

3 participants