StackExchange / StackExchange.Redis

General purpose redis client
https://stackexchange.github.io/StackExchange.Redis/
Other
5.88k stars 1.51k forks source link

The Subscribe method subscribes to one node only when having Redis cluster #2750

Open orlinhristov opened 3 months ago

orlinhristov commented 3 months ago

I'm trying to write a straightforward .Net app that will subscribe to a cluster of Redis nodes, to receive change notifications.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var redis = ConnectionMultiplexer.Connect("10.0.255.86:6379, 10.0.255.87:6379, 10.0.255.88:6379");

            var subscriber = redis.GetSubscriber();

            RedisChannel topic = "__key*__:*";

            subscriber.Subscribe(topic, (channel, value) =>
            {
                System.Console.WriteLine("Key change notification received. Channel: {0}, Value: {1}", channel, value);
            });

            var endpoint = subscriber.SubscribedEndpoint(topic);

            System.Console.WriteLine("Subscribed to Redis endpoint {0}", endpoint);

            System.Console.ReadLine();
        }
    }
}

I see that the subscriber always subscribes to one of the nodes (in my case "10.0.255.86:6379") and I guess it's because the Redis will broadcast each published message to all other nodes:

"The clients can send SUBSCRIBE to any node and can also send PUBLISH to any node. It will simply broadcast each published message to all other nodes."

It works as described if the message is indeed published by a client, but won't work the same way when it comes to internal messages published by the node itself, when a change occurs. For some reason only the node that owns the key/value entity will receive it. I don't know if that's a bug in Redis or it works this way by design but I tried to workaround it. I created a separate ConnectionMultiplexer connecting it to a single node. However, all the multiplexers always subscribe to "10.0.255.86:6379" including those that are connected to "10.0.255.87:6379" or "10.0.255.88:6379" and receive change notifications that happen on that node. I guess the ConnectionMultiplexer gets the whole list of nodes after connects and always subscribes for the first one.

So, if I'm not doing anything wrong, then I assume there is no way to control to which node to subscribe and respectively there is no way to receive Redis keyspace notifications from all the nodes using StackExchange.Redis.