I have few queries regarding how it internally works :
1.) Redis cluster does Hash slot based uniform partitioning . If we create a channel say C1 and its created in node1 then whatever we push in the channel will always get store in C1 in node1 of redis cluster . My understanding is correct ?
2.) If total size of messages in single channel exceeds node capacity then will it split elements in the channel to multiple nodes in redis cluster ?
Pub/Sub isn't keyspace-related so cluster partitioning doesn't apply to it.
WRT 1: Pub/Sub in a cluster is a full-mesh, so any node getting a PUBLISH broadcasts it in the cluster bus to all other nodes. All nodes then send the published message to their respective subscribers (if any)
WRT 2: There is no maximal channel capacity - messages are sent immediately as they are published.
Related
I'm working on messaging project, where I need to have a large number of Redis PubSub channel subscriptions as shown in the graphic below . I'm on NestJS and use 'ioredis' library. I have few questions regarding this design,
Assuming there is only one subscriber client, do all channel subscriptions get multiplexed through a single Redis connection?
Is there a limit to how many channel subscriptions a client can have assuming Redis cluster is able to scale.
Thanks.
We are shifting from Monolithic to Microservice Architecture for our e-commerce marketplace application. We chosen Redis pub/sub for microservice to microservice communication and also for some push notification purpose. Push notification strategy is like below:
Whenever an order is created (i,e customer creates an order), the backend publishes an event in respective channel (queue) and the specific push-notification-microservice consumes this event (json message) and sends push notification to the seller mobile.
For the time being we are using redis-server installed in our ubuntu machine without any hassle. But the headache is in future when millions of order will be generated in a point of time then how can we handle this situation ? That means, we need to scale the Redis Queue, right ?
My exact clean question (regardless the above scenario) is:
How can I horizontally scale Redis Queue instead of increasing the RAM in same machine ?
Whenever an order is created (i,e customer creates an order), the
backend publishes an event in respective channel (queue) and the
specific push-notification-microservice consumes this event (json
message) and sends push notification to the seller mobile.
IIUC you're sending a message over Redis PUB/SUB, that's not durable that means if the only producer is up and other services/consumers are down then consumers will miss messages. Any services that are down will lose all those messages that are sent when the said service was down.
Now let's assume, you're using Redis LIST and other combinations of data structures to solve the missing events issue.
Scaling Redis queue is a little bit tricky since entire data is stored in a list, that resides on a single Redis machine/host. What you can do is create your own partitioning scheme and design your Redis keys as per the partitioning scheme as Redis does internally when we add a new master in the cluster, creating consistent hashing would require some efforts.
Very simple you can distribute loads based on the userId for example if userId is between 0 and 1000 then use queue_0, 1000-2000 queue_1, and so on. This is a manual process that you can be automated using some script. Whenever a new queue is added to the set all consumers have to be notified and the publisher will be updated as well.
Dividing based on the number is a range partition scheme, you can use a hash partition scheme as well, either you use a range or hash partitioning scheme, whenever a new queue is added to the queue set the consumers must be notified for potential updates. Consumers can spawn a new worker for the new queue, removing a queue could be tricky as all consumers must have drained their respective queue.
You might consider using Rqueue
I am new to RabbitMQ and not too sure if my goal is achievable. Basically, my goal is to be able to setup a highly available and load balanced queues.
So given 3 nodes with 1 queue each (let's say Node1 has Queue1, Queue2, Queue3. Node2 also has Queue1, Queue2, Queue3, and the same for Node3). Each queue has it's own consumer.
I would like to load balance the messages in the queues so that producers can send the message to any of the queue and get the consumer to process the queue.
I would also like to implement mirroring so that if one of the Nodes goes down (lets say Node1 goes down for some reason), the messages sent to queues in Node1 will not be lost and will still be processed.
From my understanding in Clustering, messages are stored to where the master queue is so therefore I didn't achieved the load balanced queue that I want.
Is my goal achievable? If yes, how can I do that?
I was looking at Federated queues but not too sure if I can implement mirroring with it.
Thanks.
GGarcia
According to this no, it's not possible:
https://www.rabbitmq.com/blog/2013/10/23/federated-queues-in-3-2-0/
'Federated queues will only ever contain a given message in one location; there's no mirroring.'
I've been thinking, what about implementing federated queues, and providing HA to every node using a 'low level' solution like Pacemaker/DRBD?
https://www.rabbitmq.com/pacemaker.html
Haven't tried it, it's just an idea.
The other thing to try is maybe using sharding instead of federated queues, here it says it should be possible to mirror its sharded queues:
https://github.com/rabbitmq/rabbitmq-sharding/issues/12
Good luck!
RabbitMQ can send one message to different queues through exchange. While queueA and queueB on different node accept same message, will these two nodes store the message respectively on their own disk or using a common database to store this message once for sharing between nodes?
RabbitMQ in cluster does not share the same database-messages.
Each node has its own local database.
If want to learn more about that, I suggest to read:
https://github.com/rabbitmq/internals/blob/master/queues_and_message_store.md
I was reading following article, I am not able to understand how Unicast will require more bandwidth and network calls.
Suppose, I am having a multicast cluster having 4 nodes, now a message is to be replicated so node having the message will multicast it to the multicast address and then it will replicated to other cluster nodes.
Same thing in Unicast will have a leader of the cluster so node having message will transmit it to cluster leader and cluster leader will replicate it to remaining 2 nodes.
So, in both cases I see same bandwidth consumption and network calls.
That web page really makes it clear in the Considerations section, but in summary:
unicast sends one targeted update message, which is replicated a few times by each recipient until every server in the cluster is updated
multicast sends a single message that all servers on the network subnet receive with no retransmit delays
So in the case of a 4-node cluster:
Unicast will result in 1 message to group node + 2 messages to the member nodes = 3 total
Multicast will result in 1 message to the subnet = 1 total