-
Notifications
You must be signed in to change notification settings - Fork 315
Undefined behavior for ZSCAN using readonly cluster client. #222
Comments
@theanti9 Interesting edge case that you found. I get that the error happens and i get how/why but i have to think/tinker some in order how to solve this issue. |
There are several other commands (at least per the documentation) that are always directed at the appropriate master node. Maybe the |
@theanti9 I am working on a fix, it should not be that difficult to solve, i just have to identify all methods that require this change and patch them inside the ReadonlyConnectionPool. Will update when i am done with it. |
Awesome, thanks! |
Ignore that commit, it was broken af... I am working on a new solution. |
Just a note, all |
While using a
ClusterReadOnlyConnectionPool
, thezscan
andzscan_iter
will not successfully provide the scan guarantees. I believe this will apply tosscan
andhscan
as well, though I've not tested.The issue arises from the overridden
get_node_by_slot
onClusterReadOnlyConnectionPool
. This will randomly choose between any master or slave node that has the slot for the key. So as subsequent scan commands are issued, it will issue them to random nodes. The cursor values Redis returns are stateless, they are effectively offsets, however, they're not guaranteed to be consistent between master and slave.An example I used to debug this was on a sorted set that currently contains 164 values, but has fluctuated significantly over its lifetime. If I issue an initial ZSCAN request to the master that owns it, I get the following response:
Command:
ZSCAN mysortedset 0
Note: cursor value of
136
.If I run this same command on the slave node that has this slot, I get the following results.
Note: Different values, fewer values, and different cursor offset.
While the underlying set doesn't change, reissuing these commands on the same server does provide consistent results, but switching between servers means that you end up with an arbitrary subset of what's actually in the sorted set. This can be demonstrated through the python library with the following (called on the same set as above with no underlying changes in between)
Using the readonly cluster client, called in quick succession:
Using a non-readonly cluster client, called in quick succession
The text was updated successfully, but these errors were encountered: