Mastering Redis Streams: From Basics to SpringBoot Integration
This article introduces Redis Streams, explains its core concepts and commands, compares it with Kafka, demonstrates practical SpringBoot integration with code examples, and discusses its suitability as a lightweight message queue, highlighting advantages, limitations, and best‑practice considerations.
1. Basic Knowledge
Redis Streams, introduced in Redis 5.0, is a new data structure for message passing. It is a linked list of messages where each message has a unique ID and payload.
Each stream has a unique name that corresponds to a Redis key. A stream can have multiple consumer groups (ConsumerGroup), which must be created with the XGROUP CREATE command.
Each consumer group maintains a cursor last_delivered_id that moves forward as any consumer reads messages, indicating the group’s consumption progress.
Consumer groups can have multiple consumers; each consumer reads messages in parallel, also advancing the group cursor.
Consumers keep a pending_ids list of messages they have read but not yet acknowledged.
The design of Redis Streams resembles Kafka (consumer groups, offset tracking), but the internal implementation differs: Kafka relies on the file system and partitions, while Redis Streams store data in memory.
2. Core Commands
01 XADD – Add a Message to the End of a Stream
Syntax: XADD key ID field value [field value ...] key : stream name (created if it does not exist)
ID : message ID; use * for an auto‑generated ID or provide a custom increasing ID
field value : the message payload
XADD mystream * name1 value1 name2 value2
"1712473185388-0"
XLEN mystream
(integer) 1
XADD mystream * name2 value2 name3 value3
"1712473231761-0"The auto‑generated ID consists of a millisecond timestamp and a sequence number (e.g., 1712473185388-5).
You can also limit the stream length when adding a message:
XADD mystream MAXLEN 100 * name value1 age 30
"1713082205042-0"02 XRANGE – Retrieve a List of Messages
Syntax: XRANGE key start end [COUNT count] key : stream name
start : start ID (use - for the minimum)
end : end ID (use + for the maximum)
count : optional limit on the number of entries returned
XRANGE mystream - + COUNT 2
1) "1712473185388-0"
1) "name1"
2) "value1"
3) "name2"
4) "value2"
2) "1712473231761-0"
1) "name2"
2) "value2"
3) "name3"
4) "value3"03 XREAD – Read Messages (Blocking or Non‑Blocking)
Syntax:
XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]count : maximum number of entries to return
milliseconds : optional block time; omitted means non‑blocking
key : stream name(s)
id : last ID you have seen (use 0-0 to read from the beginning, $ for the latest)
XREAD streams mystream 0-0
1) "mystream"
1) "1712473185388-0"
1) "name1"
2) "value1"
3) "name2"
4) "value2"
2) "1712473231761-0"
1) "name2"
2) "value2"
3) "name3"
4) "value3"Using BLOCK with $ makes the call wait until new messages arrive.
04 XGROUP CREATE – Create a Consumer Group
Two ways to create a group:
XGROUP CREATE mystream mygroup 0-0 # start from the beginning
XGROUP CREATE mystream mygroup $ # start from the latest message05 XREADGROUP – Read Messages from a Consumer Group
Syntax:
XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] ID [ID ...]group : consumer group name
consumer : consumer name within the group
count : number of entries to return
milliseconds : optional block time
key : stream name
ID : start ID (use > to read new messages)
XREADGROUP GROUP mygroup consumerA COUNT 1 STREAMS mystream >
1) "mystream"
1) "1712473185388-0"
1) "name1"
2) "value1"
3) "name2"
4) "value2"06 XACK – Acknowledge Processed Messages
Syntax:
XACK key group ID [ID ...] XACK mystream mygroup 1713089061658-0
(integer) 1Acknowledgement removes the message from the pending list, increasing reliability.
07 XTRIM – Trim a Stream’s Length
Example of adding messages and then trimming to keep only the latest two entries:
XADD mystream * field1 A field2 B field3 C field4 D
"1712535017402-0"
XTRIM mystream MAXLEN 2
(integer) 4
XRANGE mystream - +
1) "1712498239430-0"
1) "name"
2) "zhangyogn"
2) "1712535017402-0"
1) "field1"
2) "A"
3) "field2"
4) "B"
5) "field3"
6) "C"
7) "field4"
8) "D"Redis Streams support both simple producer‑consumer and publish‑subscribe models.
3. SpringBoot Redis Stream Practical Guide
Add the SpringBoot Redis starter dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>Configure connection properties in application.yml (example omitted for brevity).
Configure a RedisTemplate bean to work with streams.
Define a stream listener class that implements MessageListener (code omitted).
Create a StreamContainer bean to start the listener.
Send messages using RedisTemplate.opsForStream().add(...).
When the application runs, the consumer prints received messages as shown in the logs.
Note: Ensure that the stream key and consumer group are created before starting the listener.
4. Is Redis Stream Perfect for a Message Queue?
Redis Streams bring a publish‑subscribe model with independent consumption and one‑to‑many delivery, solving the lack of ACK in Redis Lists.
However, Redis is fundamentally an in‑memory database designed for caching, not for heavy message accumulation. Its high‑availability mechanisms (AOF, async replication) can still lose messages, whereas dedicated message queues provide stronger guarantees.
Therefore, Redis Streams are best suited for lightweight queue scenarios where data volume is controlled, the business model is simple, message buildup is unlikely, and proper monitoring is in place.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Su San Talks Tech
Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
