diff --git a/doc/source/drivers.rst b/doc/source/drivers.rst index b12fa255..75a2524e 100644 --- a/doc/source/drivers.rst +++ b/doc/source/drivers.rst @@ -15,7 +15,7 @@ API, some of them have different properties: on timeout (heartbeats, locks, etc) so are less resilient than other backends. -* `redis`_ is a basic implementation and provides some resiliency +* `redis`_ is a basic implementation and provides reasonable resiliency when used with redis-sentinel. A lot of the features provided in tooz are based on timeout (heartbeats, locks, etc) so are less resilient than other backends. diff --git a/setup-sentinel-env.sh b/setup-sentinel-env.sh index 138e0e23..6c935a30 100755 --- a/setup-sentinel-env.sh +++ b/setup-sentinel-env.sh @@ -1,7 +1,8 @@ #!/bin/bash set -x -e -CONFFILE=$(mktemp -t tooz-sentinel-XXXXXX) +SENTINEL_PORTS="26381 26382 26383" +CONFFILES=() function clean_exit(){ local error_code="$?" @@ -10,29 +11,45 @@ function clean_exit(){ kill $(jobs -p) fi wait $spawned - rm $CONFFILE || true - rm /tmp/sentinel.26381.log || true + rm /tmp/sentinel.2638[123].log || true + rm ${CONFFILES[@]} || true return $error_code } -cat > $CONFFILE < $conffile <:?sentinel= + Additional sentinel hosts are listed with mutiple ``sentinel_fallback`` + parameters as follows: + + redis://:?sentinel=& + sentinel_fallback=:& + sentinel_fallback=:& + sentinel_fallback=: + Further resources/links: - http://redis.io/ @@ -202,6 +210,10 @@ class RedisDriver(coordination.CoordinationDriver): 'ssl_certfile', 'ssl_keyfile', 'sentinel', + 'sentinel_fallback', + ]) + _CLIENT_LIST_ARGS = frozenset([ + 'sentinel_fallback', ]) _CLIENT_BOOL_ARGS = frozenset([ 'retry_on_timeout', @@ -317,6 +329,8 @@ class RedisDriver(coordination.CoordinationDriver): # redis://localhost:6379?timeout=5&timeout=2 if a in cls._CLIENT_BOOL_ARGS: v = strutils.bool_from_string(options[a][-1]) + elif a in cls._CLIENT_LIST_ARGS: + v = options[a] elif a in cls._CLIENT_INT_ARGS: v = int(options[a][-1]) else: @@ -328,14 +342,21 @@ class RedisDriver(coordination.CoordinationDriver): # Ask the sentinel for the current master if there is a # sentinel arg. if 'sentinel' in kwargs: + sentinel_hosts = [ + tuple(fallback.split(':')) + for fallback in kwargs.get('sentinel_fallback', []) + ] + sentinel_hosts.insert(0, (kwargs['host'], kwargs['port'])) sentinel_server = sentinel.Sentinel( - [(kwargs['host'], kwargs['port'])], + sentinel_hosts, socket_timeout=kwargs['socket_timeout']) master_host, master_port = sentinel_server.discover_master( kwargs['sentinel']) kwargs['host'] = master_host kwargs['port'] = master_port del kwargs['sentinel'] + if 'sentinel_fallback' in kwargs: + del kwargs['sentinel_fallback'] return redis.StrictRedis(**kwargs) def _start(self):