如果主人关机,如何使Python故障转移到Redis从服务器?
使用当前的配置,哨兵会选择一个新的主机,但是Python会写stop。
我想我不应该像在docker-come.yml文件中那样使用redis-master;有什么可供选择的?
在网络模式下,我无法让哨兵认出对方。
docker-compose.yml
version: '3'
services:
redis-master:
container_name: redis-master
image: redis:latest
command: redis-server --port 6379
ports:
- "6379:6379"
volumes:
- .:/app
redis-slave:
container_name: redis-slave
image: redis:latest
command: redis-server --slaveof redis-master 6379 --protected-mode no
volumes:
- .:/app
sentinel-1:
container_name: sentinel-1
build: sentinel
environment:
- SENTINEL_DOWN_AFTER=5000
- SENTINEL_FAILOVER=5000
sentinel-2:
container_name: sentinel-2
build: sentinel
environment:
- SENTINEL_DOWN_AFTER=5000
- SENTINEL_FAILOVER=5000
sentinel-3:
container_name: sentinel-3
build: sentinel
environment:
- SENTINEL_DOWN_AFTER=5000
- SENTINEL_FAILOVER=5000
app:
container_name: python-app
image: pyredis
command: python app.py
Python应用程序:
import redis
import random
import time
r = redis.StrictRedis(host="redis-master", port=6379, db=0)
for i in range(0, 1000):
timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
num = random.randint(1,101)
r.set(timestamp, num)
time.sleep(2)
谢谢,如有任何意见请见谅。
发布于 2019-08-29 08:17:16
您需要一个函数来重新定义您的r
值:
import redis
from redis.exceptions import ConnectionError
def get_connection(host):
global r
other_host = "redis-slave" if "master" in host else "redis-master"
try:
r = redis.StrictRedis(host=host, port=6379, db=0)
except ConnectionError:
# connection against host failed, try other_host
host = other_host
r = redis.StrictRedis(host=host, port=6379, db=0)
return host
host = get_connection('redis-master')
for i in range(0, 1000):
timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
num = random.randint(1,101)
try:
r.set(timestamp, num)
# handles explicitly redis.exceptions.ConnectionError
except ConnectionError:
host = get_connection(host)
r.set(timestamp, num)
time.sleep(2)
在主程序下降的情况下,将调用该函数,并将连接切换到从服务器,反之亦然。如果两者都关闭,则外部Exception
将引发except
,程序将崩溃。
编辑
对于通常是大不-不的可变默认值,这可能是一个非常有趣的用例。Note,我仍然不会在任何生产代码中实现这一点,只是在这里显示了副作用。
deque支持就地旋转,因此您可以使用它来切换host
和other_host
,如下所示:
from collections import deque
d = deque(('redis-master', 'redis-slave'), maxlen=2)
d
deque(['redis-master', 'redis-slave'], maxlen=2)
d.rotate()
d
deque(['redis-slave', 'redis-master'], maxlen=2)
现在,您可以使用它作为缓存,只需交换订单。
def get_connection(d=deque(('redis-master', 'redis-slave'), maxlen=2)):
global r
host, other_host = d # unpacks the two values
try:
r = redis.StrictRedis(host=host, port=6379, db=0)
except ConnectionError:
r = redis.StrictRedis(host=other_host, port=6379, db=0)
d.rotate() # changes the order of the hosts
为了显示这是如何工作的:
def get_connection(d=deque(('redis-master', 'redis-slave'), maxlen=2)):
print(d)
try:
raise ValueError # as a test
except ValueError:
print("Caught error")
d.rotate()
print(d)
get_connection()
deque(['redis-master', 'redis-slave'], maxlen=2)
Caught error
deque(['redis-slave', 'redis-master'], maxlen=2)
get_connection()
deque(['redis-slave', 'redis-master'], maxlen=2)
Caught error
deque(['redis-master', 'redis-slave'], maxlen=2)
现在,您的外部程序不需要了解host
,它只需在必要时调用retry函数:
for i in range(0, 1000):
timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
num = random.randint(1,101)
try:
r.set(timestamp, num)
# handles explicitly redis.exceptions.ConnectionError
except ConnectionError:
get_connection() # host doesn't need to be returned anymore
r.set(timestamp, num)
time.sleep(2)
https://stackoverflow.com/questions/57714028
复制