Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redis Pub/Sub with Reliability

Tags:

redis

I've been looking at using Redis Pub/Sub as a replacement to RabbitMQ.

From my understanding Redis's pub/sub holds a persistent connection to each of the subscribers, and if the connection is terminated, all future messages will be lost and dropped on the floor.

One possible solution is to use a list (and blocking wait) to store all the message and pub/sub as just a notification mechanism. I think this gets me most of the way there, but I still have some concerns about the failure cases.

  1. what happens when a subscriber dies, and comes back online, how should it process all it's pending messages?
  2. when a malformed message comes though the system, how do you handle those exceptions? DeadLetter Queue?
  3. is there a standard practice to implementing a retry policy?
like image 563
Edward Chan Avatar asked May 31 '11 18:05

Edward Chan


People also ask

Is Redis pub/sub reliable?

Its not pub sub, its more reliable since your consumer can be offline and the messages will queue up instead of being lost.

Is Redis pub/sub real time?

Using Redis for pub/sub Also, note that Redis is an in-memory system and data can only be handled as long the RAM allocated to it is capable. This means that Redis is good for real-time messaging and systems that send data quickly without delay. Other use cases with caching include the following.

What is Redis pub/sub used for?

Redis Pub/Sub implements the messaging system where the senders (in redis terminology called publishers) sends the messages while the receivers (subscribers) receive them. The link by which the messages are transferred is called channel. In Redis, a client can subscribe any number of channels.

Is Redis pub/sub blocking?

Redis' pub/sub sends messages to clients subscribed (listening) on a channel. If you are not listening, you will miss the message (hence the blocking call). If you want to have it non-blocking, I recommend using a queue instead (redis is pretty good at that too).


2 Answers

When a subscriber (consumer) dies, your list will continue to grow until the client returns. Your producer could trim the list (from either side) once it reaches a specific limit, but that is something you would need to handle at the application level. If you include a timestamp within each message, your consumer can then act on the age of a message, assuming you have application logic you want to enforce on message age.

I'm not sure how a malformed message would enter the system, as the connection to Redis is usually TCP with the its integrity assurances. But if this happens, perhaps due to a bug in message encoding at the producer layer, you could provide a general mechanism for handling errors by keeping a queue-per-producer that received consumer's exception messages.

Retry policies will depend greatly on your application needs. If you need 100% assurance that a message has been received and processed, then you should consider using Redis transactions (MULTI/EXEC) to wrap the work done by a consumer, so you can ensure that a client doesn't remove a message unless it has completed its work. If you need explicit acknowlegement, then you could use an explicit ACK message on a queue dedicated to the producer process(es).

Without knowing more about your application needs, it's hard to know how to choose wisely. Generally, if your messages require full ACID protection, then you probably also need to use redis transactions. If your messages are only meaningful when they are timely, then transactions may not be needed. It sounds as though you can't tolerate dropped messages, so your approach of using a list is good. If you need to implement a priority queue for your messages, you can use the sorted set (the Z-commands) to store your messages, using their priority as the score value, along with a polling consumer.

like image 161
Will Pierce Avatar answered Oct 22 '22 14:10

Will Pierce


If you want a pub/sub system where subscribers won't lose messages when they die, consider using Redis Streams instead of Redis Pub/sub.

Redis Streams have their own architecture and pros/cons to Redis Pub/sub. With Redis Streams, a subscriber can issue the command:

the last message I received was X, now give me the next message; if there is no new message, then wait for one to arrive.

Antirez's article linked above is a good intro to Redis streams with more info.

like image 38
Kristopher Windsor Avatar answered Oct 22 '22 15:10

Kristopher Windsor