Grokzen / redis-py-cluster

Python cluster client for the official redis cluster. Redis 3.0+.
https://redis-py-cluster.readthedocs.io/
MIT License
1.1k stars 315 forks source link

Eventspace notifications- Not recieving notification for all nodes #436

Closed hkd1996 closed 3 years ago

hkd1996 commented 3 years ago

I get eventspace notifications for a randome node after subscribing using the following command: pubsub.psubscribe('key*:*') Is there any way to subscribe to all nodes?

Grokzen commented 3 years ago

No. Pubsub is not recommended to use in a cluster and until/unless redis-server itself solves the n**2 full mesh problem i will not make an effort to sort out pubsub subscription in this lib as i do not want to provide code features for something that is inherit broken on the server side when you run a cluster.

My recommendation is to use a sentinel setup for pubsub and run it separate from your regular cluster.

There is also lots of documentation i written about it if you look inside docs/ folder.

hkd1996 commented 3 years ago

@Grokzen My bad I was just trying to ask if there is any way to achieve this- "Every node of a Redis cluster generates events about its own subset of the keyspace as described above. However, unlike regular Pub/Sub communication in a cluster, events' notifications are not broadcasted to all nodes. Put differently, keyspace events are node-specific. This means that to receive all keyspace events of a cluster, clients need to subscribe to each of the nodes." To be precise subscribe for events with respect to each node in cluster?

Grokzen commented 3 years ago

@hkd1996 When did this change happen as the links that is in the docs talking about it i think is still relevant and i know that antirez did not change anything inside redis-server to my knowledge at least to solve this problem. If there has been changes into this as from the old posts i read up on this there was lots of low level debugging and investigating that needed to be done to verify that fanout dont happen any longer in certain conditions. I have not tested this for some time now and it might be time to test this again with 6.0 and 6.2 as the old issue was from like 3.x and 4.x time and that was some time ago.

But to look at the code pov in your question, there is no way to send a subscribe event to multiple nodes at the same time as it would mean threads and more complexity in our lib compared to redis-py that only have to solve it for one node and not multiple nodes.

Is there some official documentation about this keyspace events in a clustered environment i can read up on where you found out about this information?

hkd1996 commented 3 years ago

https://redis.io/topics/notifications Refer to "Events in a cluster" that is where i came to know about this! @Grokzen

Grokzen commented 3 years ago

Thank you, will dig into this a bit so i am updated to any changes that has happen the last few years, will ask redis-labs if they know anything and see what you can do.

If you want to solve your problem a hacky way because it is not possible to solve this with the default code as the default code is written to not be threaded in this case when you subscribe and it will only take your key and hash it with the crc16 algorithm to determine what node to talk to. So what you can do is that you can spin up a RedisCluster instance and let it fetch the cluster state, then you can take what data that NodeManager/ClusterConnectionPool contains and build your own solution with threads to parallel the multiple subscribe that you are looking for by creating multiple Redis class instances and just send psubscribe to each node manually so you can talk to each node as you want.

hkd1996 commented 3 years ago

@Grokzen I'm new to python development can you help me in achieving this? - "So what you can do is that you can spin up a RedisCluster instance and let it fetch the cluster state, then you can take what data that NodeManager/ClusterConnectionPool contains and build your own solution with threads to parallel the multiple subscribe that you are looking for by creating multiple Redis class instances and just send psubscribe to each node manually so you can talk to each node as you want."

Grokzen commented 3 years ago

@hkd1996 If you are new to python and not familiar with wither socket programming or threads programming then i think doing this yourself is a big task and might be out of your reach of what you are capable of. But what i can give you advice on is that if you create a RedisCluster object and point it to a running cluster and you can run simple commands like get/set against the cluster successfully, then you can go through the connectionpool object into the nodes tracking object here https://github.com/Grokzen/redis-py-cluster/blob/master/rediscluster/connection.py#L149 and then futher on use this method https://github.com/Grokzen/redis-py-cluster/blob/master/rediscluster/nodemanager.py#L122 to hopefully get access to all nodes in some way where you can then build your own threaded solution to run parralell psubscribe to all nodes at the same time and listen to all nodes at the same time inside your threads.

I can't give you more then that help as i have no plans to support this keyspace feature in the near future due to the complexity of having to listen to all nodes at the same time in some kind of threaded environment. The solution would need to make to many assumptions on what each user wants and a generic use-case probably do not fit everyone and then i get into maintainers hell by needing to support each use-case and variant. I rather just say that how you can get access to each node object/connection and implement whatever you wish there instead.