redis.retry
>>> 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)
As you can see from the example above, Redis client supports 3 parameters to configure the retry behaviour:
retry
:~.Retry
instance with abackoff-label
strategy and the max number of retriesretry_on_error
: list ofexceptions-label
to retry onretry_on_timeout
: ifTrue
, retry on~.TimeoutError
only
If either retry_on_error
or retry_on_timeout
are passed and no retry
is given, by default it uses a Retry(NoBackoff(), 1)
(meaning 1 retry right after the first failure).
>>> 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)
Retry behaviour in Redis Cluster is a little bit different from Standalone:
retry
:~.Retry
instance with abackoff-label
strategy and the max number of retries, default value isRetry(NoBackoff(), 0)
cluster_error_retry_attempts
: number of times to retry before raising an error when~.TimeoutError
or~.ConnectionError
or~.ClusterDownError
are encountered, default value is3
Let's consider the following example:
>>> 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')
- the client library calculates the hash slot for key 'foo'.
- given the hash slot, it then determines which node to connect to, in order to execute the command.
- during the connection, a
~.ConnectionError
is raised. - because we set
retry=Retry(ExponentialBackoff(), 6)
, the client tries to reconnect to the node up to 6 times, with an exponential backoff between each attempt. - even after 6 retries, the client is still unable to connect.
- because we set
cluster_error_retry_attempts=1
, before giving up, the client starts a cluster update, removes the failed node from the startup nodes, and re-initializes the cluster. - after the cluster has been re-initialized, it starts a new cycle of retries, up to 6 retries, with an exponential backoff.
- if the client can connect, we're good. Otherwise, the exception is finally raised to the caller, because we've run out of attempts.