用Python命名当前Redis主机(在Docker中运行)

2024-04-24 00:44:52 发布

您现在位置:Python中文网/ 问答频道 /正文

如果主机关闭,如何使Python故障转移到Redis slave?你知道吗

在当前的配置中,sentinel选择一个新的主节点,但是Python停止写入。你知道吗

我想我不应该像docker那样使用redis master-合成.yml文件;有哪些替代方案?你知道吗

在网络模式下,我无法让哨兵相互识别。你知道吗

码头工人-合成.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)

谢谢,任何意见都将不胜感激。你知道吗


Tags: nameimagebuildmasterredisappenvironmenttime
1条回答
网友
1楼 · 发布于 2024-04-24 00:44:52

您需要一个函数来重新定义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)

在主设备停机的情况下,将调用该函数并将连接切换到从设备,反之亦然。如果两个都关闭,则外部except捕获的Exception将被提升,程序将崩溃

编辑

对于可变默认值(通常是BIG NO-NO),这可能是一个非常有趣的用例。注意,我仍然不会在任何生产代码中实现这一点,只是在这里显示副作用

deque支持就地旋转,因此可以使用它来切换hostother_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)


相关问题 更多 >