-
Notifications
You must be signed in to change notification settings - Fork 432
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
scan
and scan_iter
stuck to first iteration
#1402
Comments
it works when we use this "obscure" python package : https://pypi.org/project/kvrocks-scan/ Which does the following: import redis
def parse_scan(response, **options):
cursor, r = response
if cursor == b"0" or cursor == "0":
return int(cursor),r;
return cursor, r
redis.client.AbstractRedis.RESPONSE_CALLBACKS["SCAN"] = parse_scan;
# Redis scan_iter etc I'm not sure why this works and the forked Redis python by @hashlookup, which seems to handle this int/str cast, doesn't. Edit: Actually, with this method, |
Hi, @kinoute Thanks for your feedback, we would take a look. |
@kinoute The root cause is right that the Kvrocks scan command would return a string cursor instead of the integer, so it's not compatible with the official Python client. Another workaround can use the raw client to send and parse the scan command. For why the scan_iter didn't, to see if @adulau or other guys who are familiar with Python can help. |
But it seems the forked Redis-py client the Kvrocks team recommends in many issues should handle this problem? See this commit: redis/redis-py@e9c53fb Or am I missing something here? |
Yes, we recommend using the fork redis-py, and it should be fine to add a wrap function to work around this. |
The Redis documentation clearly states that the cursor is unsigned 64 bit number. Do we not need to fully compatible with Redis protocol? |
I approve your point.@jihuayu |
@jihuayu The underly storage is different between Kvrocks and Redis, so what we can do is try our best to be compatible with Redis. Welcome to submit the proposal if you have any ideas to achieve this. |
@git-hulk SCAN commond is frequently used in Redis clients.It's important to ensure SCAN commond is correct for Redis toolchains to work with Kvrocks. After carefully reading the Redis documentation, I found that cursors have the following features:
Therefore, I think we can use a ring array to store the key names for the most recently used cursors. When SCAN end_cursor is "keyname1" we push {key:keyname1,cursor:1276} to cursor-ring. If client call many SCAN command, cursor-ring will be filled and the oldest cursor will be discarded. Based on the above design, we will have the following additional costs.
Because SCAN command is a slow command, so the additional cursor translation has a minimal impact. |
@jihuayu Thanks for your solution. The ring buffer or LRU cache is good for me. For the HSCAN and SSCAN commands, we need to use the subkey to map the string cursor and number. By the way, to be compatible with the older version, we should add a configuration to allow users to enable this feature. And can enable it by default in the next major version. |
Thanks @jihuayu, assigned |
Nice catch! @jihuayu
|
Thank you! @mapleFU
|
Search before asking
Version
2.3.0
Minimal reproduce step
docker run -it -p 6666:6666 apache/kvrocks
What did you expect to see?
I expected both commands to iterate through every
dba_*
key.What did you see instead?
Instead, both commands are stuck on the first iteration of default size and keep printing the same batch of keys every time.
Exemple with
scan_iter
:etc.
Anything Else?
While being inefficient,
keys
doesn't suffer from this problem and return every key matching the pattern:Are you willing to submit a PR?
The text was updated successfully, but these errors were encountered: