Scenario: I have a Redis stream being read by multiple consumers in a consumer group. I need to get some sort of visibility into the system to understand what is the pending count, number of consumers, number of acked messages etc.
Now a lot of things are resolved by the XINFO command. But there are some things which I couldn't find in any of the APIs -
- How do I find for a given consumer group how many (and list of) messages that have been acked
- How do I find how far is my consumer group in terms of count of messages than the current Redis streams HEAD
Any workaround for any of the above would be highly appreciated.
Also, is there any good monitoring dashboard which gives these metrics exposed directly for all the streams in a Redis instance to monitor? (Grafana or something?)
Comment From: quintonparker
hey @raj454raj
AFAICT so there's no direct support for such functionality in the available XSTREAM and friends commands
But a simple workaround in my mind would be to use another stream to record all the processed stream entries that the consumer group is subscribed to
ie. while sending XACK to acknowledge processing of a stream entry, the consumer can simultaneously write the same entry to another stream which thus represents a log of processed entries
Now you have 1. A log of all processed stream entries 2. a way to determine consumer subscription progress by comparing the result of XLEN commands on each stream respectively
As for monitoring, have you seen Redis Data Source plugin for Grafana? It supports stream commands amongst others
https://grafana.com/grafana/plugins/redis-datasource
Comment From: itamarhaber
Hello @raj454raj
As @quintonparker had replied, both use cases are not covered by Redis out of the box, but can be implemented using additional data structures.
In the future it is possible that Redis will provide better introspection for the 2nd use case - cc'ing @guybe7
Comment From: JamesRamm
Hi, Just came across this as I am trying something similar - monitoring the stream. For the acked messages, I think it may be possible to get a general idea from the XINFO / XPENDING commands. Correct me if I am wrong, but with XINFO we can get:
- the last entry of the stream
- the last delivered id to consumer groups
so, if we can count the number of entries from the last delivered id to the last stream entry, we have the number of messages which are either not yet delivered or still being processed. The total length of the stream minus this number is your 'acked' messages. By using XPENDING you can also find out how many of the remaining messages are currently being processed and how many are waiting to be delivered.
In summary, to get 'waiting' messages:
XINFO STREAM key to get 'last-generated-id'XINFO GROUPS keyto get 'last-delivered-id' for all groupsXRANGE key <last-delivered-id> <last-generated-id>to get all the messages waiting to be delivered
@quintonparker's solution is probably simple though - when you 'ack' a message just log it in redis somehow - post to another stream or just increment a counter or list, depending on your needs. Put the 'ack' and your logging command in a transaction to guarantee consistency If you are using a capped stream, it may be necessary to do this to ensure your 'acked' count is correct.
Comment From: itamarhaber
Hi @JamesRamm
The biggest problem that I see with the proposed approach is its time complexity - the stream doesn't provide a way to count the number of entries in a range, which means you have to iterate these in order to do the counting (as you've shown with XRANGE).
I've managed to come up with (what I think is a neat albeit) a partial answer to this specific need - i.e. the "lag" of a consumer group in the sense of yet-to-be-delivered messages - in #9127. If all goes as planned, it should be a part of Redis 7.
Comment From: dzmitry-kankalovich
In 2024 the answer is what @itamarhaber says.
Disclaimer: here I assume what OP means by acked/unacked as pending/lag as you can see below (because acked strictly speaking in Redis terms means messages that were consumed and done processing). depending on what @raj454raj originally meant, he might be able to use entries-read instead of lag
With XINFO GROUPS you get:
pending: the length of the group's pending entries list (PEL), which are messages that were delivered but are yet to be acknowledgedlag: the number of entries in the stream that are still waiting to be delivered to the group's consumers, or a NULL when that number can't be determinedentries-read: the logical "read counter" of the last entry delivered to the group's consumers
These three is everything you need for a basic visibility into the stream state.
I think the issue can be closed.