SCAN方法和REDIS不一致
Closed this issue · 1 comments
chekun commented
如题
命令:
> scan 0 match abc*
Kedis:
1) (nil)
2) (empty list or set)
REdis
1) "36"
2) (empty list or set)
两个疑问:
- redis的cursor是数字,而kedis不是
- 当没有数据的时候,redis cursor依然是数字,而kedis是nil
这样的话,使用现有的redis客户端(非redis-cli)比如python的redis客户端,就会报错。
请问是设计上的就是如此吗?这好像就不是100%兼容redis协议了哦。
chekun commented
Update:
- 看到了@jianqingdu 的注释,里面说明了区别https://github.com/jianqingdu/kedis/blob/master/src/server/cmd_keys.cpp#L325
- 我用的Python Redis客户端,自己处理了一下,暂时先解决使用,也方便给遇到一样问题的小伙伴参考。
class Kedis(redis.StrictRedis):
# SCAN FOR Kedis
def kedis_scan(self, cursor=0, match=None, count=None):
pieces = [cursor]
if match is not None:
pieces.extend([redis.connection.Token.get_token('MATCH'), match])
if count is not None:
pieces.extend([redis.connection.Token.get_token('COUNT'), count])
return self.kedis_execute_command('SCAN', *pieces)
def kedis_scan_iter(self, match=None, count=None):
cursor = '0'
while cursor:
cursor, data = self.kedis_scan(cursor=cursor, match=match, count=count)
for item in data:
yield item
# COMMAND EXECUTION AND PROTOCOL PARSING
def kedis_execute_command(self, *args, **options):
pool = self.connection_pool
command_name = args[0]
connection = pool.get_connection(command_name, **options)
try:
connection.send_command(*args)
return self.kedis_parse_response(connection, command_name, **options)
except (redis.exceptions.ConnectionError, redis.exceptions.TimeoutError) as e:
connection.disconnect()
if not connection.retry_on_timeout and isinstance(e, redis.exceptions.TimeoutError):
raise
connection.send_command(*args)
return self.kedis_parse_response(connection, command_name, **options)
finally:
pool.release(connection)
def kedis_parse_response(self, connection, command_name, **options):
response = connection.read_response()
return response
使用也简单
for key in r.kedis_scan_iter("abc:*"):
print key
最后 再次感谢@jianqingdu提供如此棒的作品 👍