1. 首页
  2. >
  3. 数据库技术
  4. >
  5. Redis

Redis 高可用

主从复制#

Redis 5.0 之后提供了REPLICAOF替代了之前的SLAVEOF命令来实现Master-Slave之间的数据交换 接下来我们设置主从复制模型:

  • Master节点

首先修改redis-master.conf配置文件来配置端口和安全认证

bind 127.0.0.1
port 6379 #端口
requirepass redis #配置密码之后需要先认证,然后才能继续进行后续操作
  • Slave节点

首先修改redis-slave.conf配置文件来配置端口和安全认证

bind 127.0.0.1
port 6379 #端口
masterauth redis #配置密码之后需要先认证,然后才能继续进行后续操作
replicaof 127.0.0.1 6379 #设置其为127.0.0.1:6379的备机

启动主节点

redis-server redis-master.conf
29035:C 18 Mar 2019 23:21:32.272 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
29035:C 18 Mar 2019 23:21:32.273 # Redis version=5.0.3, bits=64, commit=00000000, modified=0, pid=29035, just started
29035:C 18 Mar 2019 23:21:32.273 # Configuration loaded
29035:M 18 Mar 2019 23:21:32.275 * Increased maximum number of open files to 10032 (it was originally set to 4864).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 5.0.3 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 29035
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'

29035:M 18 Mar 2019 23:21:32.287 # Server initialized
29035:M 18 Mar 2019 23:21:32.289 * DB loaded from disk: 0.003 seconds
29035:M 18 Mar 2019 23:21:32.289 * Ready to accept connections
29035:M 18 Mar 2019 23:26:58.112 * Replica 127.0.0.1:6380 asks for synchronization
29035:M 18 Mar 2019 23:26:58.112 * Full resync requested by replica 127.0.0.1:6380
29035:M 18 Mar 2019 23:26:58.112 * Starting BGSAVE for SYNC with target: disk
29035:M 18 Mar 2019 23:26:58.112 * Background saving started by pid 29298
29298:C 18 Mar 2019 23:26:58.114 * DB saved on disk
29035:M 18 Mar 2019 23:26:58.118 * Background saving terminated with success
29035:M 18 Mar 2019 23:26:58.119 * Synchronization with replica 127.0.0.1:6380 succeeded

启动从节点

redis-server redis-slave.conf
29297:C 18 Mar 2019 23:26:58.107 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
29297:C 18 Mar 2019 23:26:58.107 # Redis version=5.0.3, bits=64, commit=00000000, modified=0, pid=29297, just started
29297:C 18 Mar 2019 23:26:58.107 # Configuration loaded
29297:S 18 Mar 2019 23:26:58.108 * Increased maximum number of open files to 10032 (it was originally set to 4864).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 5.0.3 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6380
| `-._ `._ / _.-' | PID: 29297
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'

29297:S 18 Mar 2019 23:26:58.110 # Server initialized
29297:S 18 Mar 2019 23:26:58.110 * DB loaded from disk: 0.000 seconds
29297:S 18 Mar 2019 23:26:58.110 * Ready to accept connections
29297:S 18 Mar 2019 23:26:58.110 * Connecting to MASTER 127.0.0.1:6379
29297:S 18 Mar 2019 23:26:58.110 * MASTER <-> REPLICA sync started
29297:S 18 Mar 2019 23:26:58.111 * Non blocking connect for SYNC fired the event.
29297:S 18 Mar 2019 23:26:58.111 * Master replied to PING, replication can continue...
29297:S 18 Mar 2019 23:26:58.111 * Partial resynchronization not possible (no cached master)
29297:S 18 Mar 2019 23:26:58.113 * Full resync from master: e98b4a9238559875100344dea137f9a803c5f805:0
29297:S 18 Mar 2019 23:26:58.119 * MASTER <-> REPLICA sync: receiving 365 bytes from master
29297:S 18 Mar 2019 23:26:58.119 * MASTER <-> REPLICA sync: Flushing old data
29297:S 18 Mar 2019 23:26:58.119 * MASTER <-> REPLICA sync: Loading DB in memory
29297:S 18 Mar 2019 23:26:58.119 * MASTER <-> REPLICA sync: Finished with success

从节点启动之后会自动从主节点同步数据,接下来我们测试从主节点写入数据,从节点读数据

主节点写入mastermsg

redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> auth redis
OK
127.0.0.1:6379> set mastermsg "master msgs"
OK

从节点读mastermsg

redis-cli -h 127.0.0.1 -p 6380
127.0.0.1:6380> get msg
"hello world"
127.0.0.1:6380> get mastermsg #第一次获取时没有获取到,因为还未同步
(nil)
127.0.0.1:6380> get mastermsg
"master msgs"
127.0.0.1:6380>

哨兵(Sentinel)#

哨兵(Sentinel)是Redis的高可用性解决方案,由一个或多个Sentinel实例组成的Sentinel系统,可以监视任意多个主服务器以及主服务器下的从服务器。并在主服务器下线状态是,自动将从服务器选举为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。

假设由四个服务器server1 为主服务器,server2,server3,server4 为从服务器 主从切换按照如下步骤进行:

  • server1 主服务器下线
  • server2,server3,server4 从服务器终端与主服务器的复制操作
  • Sentinel 系统察觉到 server1下线
  • Sentinel会从从服务器列表中选择一个服务器作为新的主服务器,假设为server2
  • Sentinel系统向除server2以外的其他从服务器发送新的复制指令让他们从server2复制数据
  • Sentinel监视到server1重新上线,会将其重新加入到server2的从服务器列表

Sentinel 配置文件:

配置哨兵时,最好禁用redis.conf中的requirepass,否则哨兵启动时会认为主机下线,或者需要在哨兵配置文件中增加sentinel auth-pass master-name password

master 配置文件

# The port that this sentinel instance will run on
port 26379

# By default Redis Sentinel does not run as a daemon. Use 'yes' if you need it.
daemonize no

# When running daemonized, Redis Sentinel writes a pid file in
# /var/run/redis-sentinel.pid by default.
pidfile /var/run/redis-sentinel.pid

# Specify the log file name. Also the empty string can be used to force
# Sentinel to log on the standard output.
logfile ""

dir /tmp

sentinel monitor mymaster 127.0.0.1 6379 2 #配置监视的Redis 主机,判断一个主机下线需要两个哨兵达成一致
sentinel down-after-milliseconds mymaster 5000 #Redis主机断线5秒认为其下线
sentinel parallel-syncs mymaster 1 #选项指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步
sentinel failover-timeout mymaster 10000 #故障转移超时时间
sentinel deny-scripts-reconfig yes

slave1 配置文件

port 26380

# By default Redis Sentinel does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis-sentinel.pid when
# daemonized.
daemonize no
pidfile "/var/run/redis-sentinel-slave1.pid"
sentinel myid 524b588bb23f15e6a2f749698ff7359c0ae6a2f1
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 127.0.0.1 6380 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel config-epoch mymaster 1

# Generated by CONFIG REWRITE
dir "/Users/jet"
protected-mode no
sentinel leader-epoch mymaster 1
sentinel known-replica mymaster 127.0.0.1 6381
sentinel known-replica mymaster 127.0.0.1 6379
sentinel known-sentinel mymaster 127.0.0.1 26381 8a1794781323d413d9753c497a637c7cb9ca1462
sentinel known-sentinel mymaster 127.0.0.1 26379 524b588bb23f15e6a2f749698ff7359c0ae6a2f0
sentinel current-epoch 1

slave 2 配置文件

port 26381

# By default Redis Sentinel does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis-sentinel.pid when
# daemonized.
daemonize no
pidfile "/var/run/redis-sentinel-slave2.pid"

sentinel myid 8a1794781323d413d9753c497a637c7cb9ca1462
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 127.0.0.1 6380 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel config-epoch mymaster 1

# Generated by CONFIG REWRITE
dir "/Users/jet"
protected-mode no
sentinel leader-epoch mymaster 1
sentinel known-replica mymaster 127.0.0.1 6381
sentinel known-replica mymaster 127.0.0.1 6379
sentinel known-sentinel mymaster 127.0.0.1 26380 524b588bb23f15e6a2f749698ff7359c0ae6a2f1
sentinel known-sentinel mymaster 127.0.0.1 26379 524b588bb23f15e6a2f749698ff7359c0ae6a2f0
sentinel current-epoch 1

操作结果如图:

如果设置了密码,执行完故障转移之后哨兵会修改配置文件,哨兵会重写master,slave, 之前如果配置了密码此时很可能会产生AUTH失败的问题


Redis 高可用