jianqingdu/kedis

SCAN方法和REDIS不一致

Closed this issue · 1 comments

如题

命令:

> scan 0 match abc*

Kedis:

1) (nil)
2) (empty list or set)

REdis

1) "36"
2) (empty list or set)

两个疑问:

  1. redis的cursor是数字,而kedis不是
  2. 当没有数据的时候,redis cursor依然是数字,而kedis是nil

这样的话,使用现有的redis客户端(非redis-cli)比如python的redis客户端,就会报错。

请问是设计上的就是如此吗?这好像就不是100%兼容redis协议了哦。

Update:

  1. 看到了@jianqingdu 的注释,里面说明了区别https://github.com/jianqingdu/kedis/blob/master/src/server/cmd_keys.cpp#L325
  2. 我用的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提供如此棒的作品 👍