# import redis
:Python 的第三方库,提供了 Redis 客户端的功能。
- GitHub (opens new window)
- 安装:
pip install redis
# 用法示例
# 连接到单节点Redis
- 创建 Redis 客户端:
>>> import redis >>> client = redis.Redis(host='127.0.0.1', port=6379, password='******', db=0, decode_responses=True) >>> client.ping() True
- Redis 服务器的响应消息默认是 bytes 类型,设置 decode_responses=True 会将它转换成 str 类型。
- 如果要创建多个 Redis 客户端,则可让它们共用一个连接池,避免重复建立连接的开销。如下:
>>> pool = redis.ConnectionPool(host='127.0.0.1', port=6379, password='******', db=0, decode_responses=True) >>> client = redis.Redis(connection_pool=pool)
# 连接到主从+哨兵集群
连接到哨兵:
>>> from redis.sentinel import Sentinel >>> sentinels = [('10.0.0.1', 26379), ('10.0.0.2', 26379), ('10.0.0.3', 26379)] >>> sentinel = Sentinel(sentinels, sentinel_kwargs={'password': '******'})
通过哨兵连接到 master :
>>> master = sentinel.master_for('master1', password='******', db=0, socket_timeout=1) >>> master Redis<SentinelConnectionPool<service=master1(master)> >>> master.set('key1', 'Hello') True
- 调用 sentinel.master_for()、sentinel.slave_for() 会返回 ConnectionPool 。
- 此时并没有建立连接,即使密码错误也不会报错。等到执行 master.set() 等操作时才会从 ConnectionPool 中自动选择一个有效的 Redis 服务器,建立连接。
- 调用 sentinel.master_for()、sentinel.slave_for() 会返回 ConnectionPool 。
通过哨兵连接到 slave :
>>> slave = sentinel.slave_for('master1', password='******', db=0, socket_timeout=1) >>> slave.get('key1') b'Hello' >>> slave.info() {'redis_version': '5.0.6', 'redis_git_sha1': 0, 'redis_git_dirty': 0, ...}
通过哨兵发现 master 和 slave 的地址:
>>> sentinel.discover_master('master1') ('10.0.0.3', 6379) >>> sentinel.discover_slaves('master1') [('10.0.0.1', 6379), ('10.0.0.2', 6379)]
客户端与 Redis 服务器建立连接之后,会保持并复用该连接。
- 当客户端执行操作时,如果 master 故障了,则执行操作时会抛出以下异常,表示与服务器的连接已断开:然后客户端会尝试连接到 ConnectionPool 中其它有效的 Redis 服务器。
>>> master.set('key1', 'Hello') redis.exceptions.ConnectionError: Connection closed by server ConnectionRefusedError: Connection refused
- 如果客户端继续尝试执行操作,则会抛出以下异常:
>>> master.set('key1', 'Hello') redis.sentinel.MasterNotFoundError: No master found for 'master1'
- 等哨兵选出新 master 之后,客户端才能成功执行操作:
>>> master.set('key1', 'Hello') True
- 当客户端执行操作时,如果 master 故障了,则执行操作时会抛出以下异常,表示与服务器的连接已断开:
# 读写数据
client 提供了与 Redis 大部分命令同名的方法,例如:
string 类型的方法
def set(name, value, ex=None, px=None, nx=False, xx=False)
- name 表示 key 的名字。
- ex(单位秒)、px(单位毫秒)表示过期时间。
- 如果 nx=True ,则只有当该 name 不存在时,才执行该操作。
- 如果 xx=True ,则只有当该 name 存在时,才执行该操作。
def mset(mapping)
def get(name)
def mget(*names)
hash 类型的方法
def hset(name, key, value)
def hget(name, key)
def hgetall(name) -> dict
例:拷贝一个 Redis 的所有 key 到另一个 Redis
client_old = redis.Redis(...) client_new = redis.Redis(...) # 遍历名称匹配 match 的 key ,每次获取 count 个 for key in client_old.scan_iter(match='*', count=1000): key_type = client_old.type(key) # 根据 key 的数据类型,用不同的方法读取 key 的值 if key_type == 'string': print(key, client_old.get(key)) client_new.set(key, client_old.get(key)) elif key_type == 'list': client_new.lpush(key, *client_old.lrange(key, start=0, end=-1)) elif key_type == 'set': client_new.sadd(key, *client_old.smembers(key)) elif key_type == 'hash': client_new.hmset(key, client_old.hgetall(key)) else: raise TypeError(key_type, key) # 如果原 key 的 ttl 不为 -1 ,说明存在 ttl ,需要设置新 key 的 ttl key_ttl = client_old.ttl(key) if key_ttl != -1 : client_new.expire(key, key_ttl)