如何使用 redis-py 在错误情况下管理客户端重连

最后更新时间 2024 年 11 月 14 日

问题

当无法建立与 Redis 数据库的连接时(例如达到最大连接数),Redis 是否提供了重试机制,还是客户端/应用程序需要实现重试机制?

回答

重试机制通常在所选的 Redis 客户端库中可用,并且可以使用各种参数进行配置以实现所需的行为。此处提供一个示例来说明 redis-py 客户端库的行为。连接到所需的集群节点,并按如下方式限制数据库的最大连接数

rladmin tune db db:1 max_connections 1

现在,在另一个终端中打开一个连接(例如使用 redis-cli),以占用唯一的连接槽位。最后,测试以下脚本。该脚本将尝试建立新连接,并因没有可用的空闲槽位而失败。请注意它将阻塞,直到 redis-cli 会话被释放。

import redis
from redis.retry import Retry
from redis.exceptions import (TimeoutError, ConnectionError)
from redis.backoff import ExponentialBackoff

r = redis.Redis(host='127.0.0.1', port=16071, retry=Retry(ExponentialBackoff(cap=10, base=1), 25), retry_on_error=[ConnectionError, TimeoutError, ConnectionResetError], health_check_interval=1)

print(r.ping())

此配置的详细信息如下。

  • 退避策略ExponentialBackoff(cap=10, base=1)
    • 第一次重试从初始延迟 1 秒开始。
    • 每次重试后延迟加倍,直到达到最大延迟(cap)10 秒。
  • 重试次数25
    • 允许最多重试 25 次后停止。

在第 25 次尝试(总等待时间为 225 秒)后,客户端将放弃并抛出最后遇到的错误。

尝试 延迟 累计等待时间
1 1 1
2 2 3
3 4 7
4 8 15
5 10(达到上限) 25
... ... ...
24 10 215
25 10 225

参考

redis-py 退避接口