redis主从搭建以及配置哨兵监控

328 阅读3分钟

主从目的

所谓主从,就是启动多个redis实例,这样操作的目的,是为了

1.读写分离,减少单个服务器的压力(写操作在主节点中,从节点不能执行写操作 在配置文件中 replica-read-only 可修改)

2.服务高可用,master挂掉时,从节点升级为主节点,不会导致整个服务不可用。

配置

启动主从

redis服务启动时,默认是主节点。

# info replication 查看节点信息,此时启动的8051端口的redis服务,作为主节点,且没有从节点
127.0.0.1:8051> info replication
# Replication
role:master
connected_slaves:0
...

再启动一个redis实例,启动时指定主节点

# --slaveof 用于指定主节点
redis-server --port 8052 --slaveof 127.0.0.1 8051

# 此时再查看主节点中的信息时,可以发现从节点
127.0.0.1:8051> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=8052,state=online,offset=14,lag=1
...

# 从节点中的信息
127.0.0.1:8052> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:8051
...

# 写入时会拒绝
127.0.0.1:8052> set master 111
(error) READONLY You can't write against a read only replica.

断开

# 在从节点客户端中操作
127.0.0.1:8052> SLAVEOF no one
OK
127.0.0.1:8052> info replication
# Replication
role:master
connected_slaves:0

# 此时从节点和主节点断开连接
# 同样的, SLAVEOF 命令也可以将主节点设置为从节点
127.0.0.1:8052> SLAVEOF 127.0.0.1 8051
OK
127.0.0.1:8052> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:8051
# 又成了从节点

哨兵模式

主从模式可以实现服务的高可用,但是还需要手动来处理从节点升级,处理升级的这段时间中,服务仍然是不可用状态,因此需要自动来完成 redis 主从服务的切换。 哨兵(sentinel)就是提供了这种功能。

sentinel 由redis官方提供,它是独立的进程。

redis 官网中有详细的介绍 sentinel 模式。(Redis Sentinel Documentation – Redis

只有两个哨兵的模式不被官方所推荐,因为故障转移需要多数节点同意,最少要保持三个哨兵节点。

搭建

上面我们已经搭建了一个一主一从的redis服务,端口分别为 8051、8052,接下来我们启动三个哨兵。 按照redis官网默认的配置

vim test_sentinel.conf
# 三个 sentinel 的配置相同,将端口换一下就行分别为 5000、5001、5002
port 5000
sentinel monitor mymaster 127.0.0.1 8051 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000

然后分别启动src/redis-sentinel test_sentinel.conf

然后客户端可以连接到5000端口查看

src/redis-cli -p 5000

# 查看节点信息
127.0.0.1:5000> SENTINEL master mymaster
 1) "name"
 2) "mymaster"
 3) "ip"
 4) "127.0.0.1"
 5) "port"
 6) "8051"
 ...
 # 主节点的从节点数量
31) "num-slaves"
32) "1"
# 其他的哨兵数量
33) "num-other-sentinels"
34) "1"
...
# 获取主节点信息
127.0.0.1:5000> SENTINEL get-master-addr-by-name mymaster
1) "127.0.0.1"
2) "8051"

测试故障转移

将主节点进程关掉

src/redis-cli -p 8051 DEBUG sleep 30

# 过点时间再去查看哨兵中的主节点信息
127.0.0.1:5000> SENTINEL get-master-addr-by-name mymaster
1) "127.0.0.1"
2) "8052"
# 这个时候可以发现8052被自动提升为了主节点。

python 连接 sentinel

redis 模块提供 sentinel 的支持。

>>> import redis
>>> import redis.sentinel
# 链接是需要提供一个 sentinel 地址列表
>>> import redis.sentinel
# 获取主节点和从节点地址
>>> sen.discover_master('mymaster')
('127.0.0.1', 8051)
>>> sen.discover_slaves('mymaster')
[('127.0.0.1', 8052)]

# 获取主节点连接
>>> master=redis.Redis('127.0.0.1', 8051)
>>> master.keys('*')
[b't1',...]
>>> master.set('sen','111')
True
>>> master.get('sen')
b'111'

# 获取从节点连接
>>> slave = redis.Redis('127.0.0.1',8052)
>>> slave.get('sen')
b'111'

# 从节点不能写
>>> slave.set('sen', '222')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/xueruobing/python380/lib/python3.8/site-packages/redis/client.py", line 1801, in set
    return self.execute_command('SET', *pieces)
  File "/home/xueruobing/python380/lib/python3.8/site-packages/redis/client.py", line 901, in execute_command
    return self.parse_response(conn, command_name, **options)
  File "/home/xueruobing/python380/lib/python3.8/site-packages/redis/client.py", line 915, in parse_response
    response = connection.read_response()
  File "/home/xueruobing/python380/lib/python3.8/site-packages/redis/connection.py", line 756, in read_response
    raise response
redis.exceptions.ReadOnlyError: You can't write against a read only replica.