重试助手#
- class redis.retry.Retry(backoff, retries, supported_errors=(<class 'redis.exceptions.ConnectionError'>, <class 'redis.exceptions.TimeoutError'>, <class 'socket.timeout'>))[source]#
在失败后重试特定次数
在 Redis 独立模式中重试#
>>> from redis.backoff import ExponentialBackoff
>>> from redis.retry import Retry
>>> from redis.client import Redis
>>> from redis.exceptions import (
>>> BusyLoadingError,
>>> ConnectionError,
>>> TimeoutError
>>> )
>>>
>>> # Run 3 retries with exponential backoff strategy
>>> retry = Retry(ExponentialBackoff(), 3)
>>> # Redis client with retries on custom errors
>>> r = Redis(host='localhost', port=6379, retry=retry, retry_on_error=[BusyLoadingError, ConnectionError, TimeoutError])
>>> # Redis client with retries on TimeoutError only
>>> r_only_timeout = Redis(host='localhost', port=6379, retry=retry, retry_on_timeout=True)
如上例所示,Redis 客户端支持 3 个参数来配置重试行为
retry_on_error
: 重试的异常列表,参见 Exceptionsretry_on_timeout
: 如果为True
,仅在遇到TimeoutError
时重试
如果同时传递了 retry_on_error
或 retry_on_timeout
,并且没有指定 retry
,则默认使用 Retry(NoBackoff(), 1)
(表示在第一次失败后立即重试一次)。
Redis 集群中的重试#
>>> from redis.backoff import ExponentialBackoff
>>> from redis.retry import Retry
>>> from redis.cluster import RedisCluster
>>>
>>> # Run 3 retries with exponential backoff strategy
>>> retry = Retry(ExponentialBackoff(), 3)
>>> # Redis Cluster client with retries
>>> rc = RedisCluster(host='localhost', port=6379, retry=retry, cluster_error_retry_attempts=2)
Redis 集群中的重试行为与独立模式略有不同
retry
:Retry
实例,包含 Backoff 策略和最大重试次数,默认值为Retry(NoBackoff(), 0)
cluster_error_retry_attempts
: 在遇到TimeoutError
、ConnectionError
或ClusterDownError
时,重试的次数,默认值为3
让我们考虑以下示例
>>> from redis.backoff import ExponentialBackoff
>>> from redis.retry import Retry
>>> from redis.cluster import RedisCluster
>>>
>>> rc = RedisCluster(host='localhost', port=6379, retry=Retry(ExponentialBackoff(), 6), cluster_error_retry_attempts=1)
>>> rc.set('foo', 'bar')
客户端库计算键“foo”的哈希槽。
根据哈希槽,它确定连接到哪个节点以执行命令。
在连接过程中,抛出了
ConnectionError
。因为我们设置了
retry=Retry(ExponentialBackoff(), 6)
,客户端会尝试最多 6 次重新连接到节点,每次尝试之间会进行指数级回退。即使经过 6 次重试,客户端仍然无法连接。
因为我们设置了
cluster_error_retry_attempts=1
,在放弃之前,客户端会启动集群更新,从启动节点中移除失败的节点,并重新初始化集群。集群重新初始化后,会开始新的重试循环,最多重试 6 次,每次尝试之间会进行指数级回退。
如果客户端可以连接,我们就成功了。否则,异常最终会传递给调用者,因为我们已经用尽了尝试次数。