前一章的主从架构无法实现master和slave角色的自动切换,即当master出现redis服务异常、主机断电、磁盘损坏等问题导致master无法使用,而redis高可用无法实现自故障转移(将slave提升为master),需要手动改环境配置才能切换到slave redis 服务器,另外也无法横向扩展Redis服务的并行写入性能,当单台Redis服务器性能无法满足业务写入需求的时候就必须要一种方式解决以上的两个核心问题。 即:
1)master和slave角色的无缝切换,让业务无感知从而不影响业务使用
2)可以横向动态扩展Redis服务器,从而实现多台服务器并行写入以实现更高并发的目的
Redis集群实现方式:客户端分片 代理分片 Redis Cluster
需要手动先指定某一台redis服务器为master,然后将其他slave服务器使用命令配置为master服务器的slave,哨兵的前提是已经手动实现了一个redis master-slave的运行环境。
replicaof 192.168.56.199 6379
config set masterauth "123456"
info replication
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.56.200,port=6379,state=online,offset=938,lag=1
slave1:ip=192.168.56.201,port=6379,state=online,offset=938,lag=1
master_replid:4ee19541109d46e9080b7df4d8ca422dd1447936
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:938
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:938
grep "^[a-Z]" /usr/local/redis/etc/sentinel.conf
bind 0.0.0.0
port 26379
daemonize yes #前台启动redis,一般不是作为守护进程运行的,如果你想让他在后台运行,就改成yes
pidfile "redis-sentinel.pid"
logfile "sentinel_26379.log"
dir "/usr/local/redis/log"
sentinel monitor mymaster 192.168.56.199 6379 2 #法定人数限制(quorum),即有几个slave认为master down了就进行故障转移
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 30000 #(SDOWN)主观下线的时间
sentinel parallel-syncs mymaster 1 #发生故障转移时候同时向新master同步数据的slave数量,数字越小总同步时间越长
sentinel failover-timeout mymaster 180000 #所有slaves指向新的master所需的超时时间
sentinel deny-scripts-reconfig yes #禁止修改脚本
bind 192.168.56.200
port 26379
daemonize yes
pidfile "redis-sentinel.pid"
logfile "sentinel_26379.log"
dir "/usr/local/redis/logs"
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 192.168.56.199 6379 2
sentinel auth-pass mymaster 123456
bind 192.168.56.201
port 26379
daemonize yes
pidfile "redis-sentinel.pid"
logfile "sentinel_26379.log"
dir "/usr/local/redis/logs"
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 192.168.56.199 6379 2
sentinel auth-pass mymaster 123456
三台都启动
/usr/local/redis/bin/redis-sentinel /usr/local/redis/etc/sentinel.conf
ss -tnl
[root@gbase8c_private logs]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:26379 *:*
LISTEN 0 128 *:6379 *:*
7697:X 23 Oct 2023 23:23:07.005 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
7697:X 23 Oct 2023 23:23:07.005 # Redis version=5.0.3, bits=64, commit=00000000, modified=0, pid=7697, just started
7697:X 23 Oct 2023 23:23:07.005 # Configuration loaded
7698:X 23 Oct 2023 23:23:07.012 * Increased maximum number of open files to 10032 (it was originally set to 1024).
7698:X 23 Oct 2023 23:23:07.013 * Running mode=sentinel, port=26379.
7698:X 23 Oct 2023 23:23:07.013 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
7698:X 23 Oct 2023 23:23:07.025 # Sentinel ID is 384dd1ae7d9bb72582e456bb3034e933a01f9a02
7698:X 23 Oct 2023 23:23:07.025 # +monitor master mymaster 192.168.56.199 6379 quorum 2
7698:X 23 Oct 2023 23:23:07.026 * +slave slave 192.168.56.200:6379 192.168.56.200 6379 @ mymaster 192.168.56.199 6379
7698:X 23 Oct 2023 23:23:07.040 * +sentinel sentinel 36e21559a613411909783767ebb9f6b1e0b7dcdd 192.168.56.201 26379 @ mymaster 192.168.56.199 6379
7698:X 23 Oct 2023 23:23:07.904 * +sentinel sentinel f54d54116f14b06d3ce7bd01f3b05e43ad5ef51d 192.168.56.200 26379 @ mymaster 192.168.56.199 6379
7698:X 23 Oct 2023 23:24:38.555 # +sdown sentinel f54d54116f14b06d3ce7bd01f3b05e43ad5ef51d 192.168.56.200 26379 @ mymaster 192.168.56.199 6379
7698:X 23 Oct 2023 23:26:56.788 # -sdown sentinel f54d54116f14b06d3ce7bd01f3b05e43ad5ef51d 192.168.56.200 26379 @ mymaster 192.168.56.199 6379
7698:X 23 Oct 2023 23:26:57.936 * +sentinel-invalid-addr sentinel f54d54116f14b06d3ce7bd01f3b05e43ad5ef51d 192.168.56.200 26379 @ mymaster 192.168.56.199 6379
7698:X 23 Oct 2023 23:26:57.938 * +sentinel sentinel 8858b85d3062bc377c0e070a3506b8f435251baf 192.168.56.200 26379 @ mymaster 192.168.56.199 6379
7698:X 23 Oct 2023 23:27:27.781 # +sdown sentinel f54d54116f14b06d3ce7bd01f3b05e43ad5ef51d 192.168.56.200 0 @ mymaster 192.168.56.199 6379
7698:X 23 Oct 2023 23:27:39.793 * +sentinel-invalid-addr sentinel 36e21559a613411909783767ebb9f6b1e0b7dcdd 192.168.56.201 26379 @ mymaster 192.168.56.199 6379
7698:X 23 Oct 2023 23:27:39.794 * +sentinel sentinel 909a40efe22be3aee7fd1e8fc6c06ed4ffb485f2 192.168.56.201 26379 @ mymaster 192.168.56.199 6379
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.56.200,port=6379,state=online,offset=149577,lag=0
slave1:ip=192.168.56.201,port=6379,state=online,offset=149577,lag=0
master_replid:b199fbbded506cbf59da3d4ab113369e573436df
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:149577
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:149577
尤其是最后一行,涉及到master IP是多少,有几个slave,有几个sentinels,必须是符合全部服务器数量的。
info sentinel
[root@gbase8c_private logs]# redis-cli -h 192.168.56.199 -p 26379
192.168.56.199:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.56.199:6379,slaves=2,sentinels=5
停止192.168.56.199 的redis服务
查看集群信息:
[root@gbase8c_2 redis]# hostname
gbase8c_2
[root@gbase8c_2 redis]# redis-cli
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.56.200,port=6379,state=online,offset=218102,lag=0
master_replid:a95e33bcecb06d694dc736c6135c5e7a8286a4f1
master_replid2:b199fbbded506cbf59da3d4ab113369e573436df
master_repl_offset:218102
second_repl_offset:176344
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:146967
repl_backlog_histlen:71136
查看哨兵信息:
[root@gbase8c_private logs]# redis-cli -h 192.168.56.199 -p 26379
192.168.56.199:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.56.201:6379,slaves=2,sentinels=5
故障转移时sentinel的日志:
7698:X 23 Oct 2023 23:33:31.994 # +sdown master mymaster 192.168.56.199 6379
7698:X 23 Oct 2023 23:33:32.121 # +new-epoch 1
7698:X 23 Oct 2023 23:33:32.123 # +vote-for-leader 8858b85d3062bc377c0e070a3506b8f435251baf 1
7698:X 23 Oct 2023 23:33:32.851 # +config-update-from sentinel 8858b85d3062bc377c0e070a3506b8f435251baf 192.168.56.200 26379 @ mymaster 192.168.56.199 6379
7698:X 23 Oct 2023 23:33:32.851 # +switch-master mymaster 192.168.56.199 6379 192.168.56.201 6379
7698:X 23 Oct 2023 23:33:32.853 * +slave slave 192.168.56.200:6379 192.168.56.200 6379 @ mymaster 192.168.56.201 6379
7698:X 23 Oct 2023 23:33:32.853 * +slave slave 192.168.56.199:6379 192.168.56.199 6379 @ mymaster 192.168.56.201 6379
7698:X 23 Oct 2023 23:34:02.872 # +sdown slave 192.168.56.199:6379 192.168.56.199 6379 @ mymaster 192.168.56.201 6379
故障转移后redis.conf中的replicaof行的master IP 会被修改,sentinel.conf 中的sentinel monitor IP 会被修改
[root@gbase8c_1 etc]# grep "^[a-Z]" /usr/local/redis/etc/redis.conf | grep replicaof
replicaof 192.168.56.201 6379
200:
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.56.201 #故障转移后的master IP
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:262726
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:a95e33bcecb06d694dc736c6135c5e7a8286a4f1 #故障转移以后的当前master_replid
master_replid2:b199fbbded506cbf59da3d4ab113369e573436df #故障转移后上一次的master_replid
master_repl_offset:262726
second_repl_offset:176344
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:262726
[root@gbase8c_1 etc]# grep "^[a-Z]" /usr/local/redis/etc/sentinel.conf
bind 192.168.56.200
port 26379
daemonize yes
pidfile "redis-sentinel.pid"
logfile "sentinel_26379.log"
dir "/usr/local/redis/logs"
sentinel myid 8858b85d3062bc377c0e070a3506b8f435251baf
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 192.168.56.201 6379 2
protected-mode no
sentinel auth-pass mymaster 123456
sentinel config-epoch mymaster 1
sentinel leader-epoch mymaster 1
sentinel known-replica mymaster 192.168.56.199 6379
sentinel known-replica mymaster 192.168.56.200 6379
sentinel known-sentinel mymaster 192.168.56.201 26379 909a40efe22be3aee7fd1e8fc6c06ed4ffb485f2
sentinel known-sentinel mymaster 192.168.56.199 26379 384dd1ae7d9bb72582e456bb3034e933a01f9a02
sentinel known-sentinel mymaster 192.168.56.201 0 36e21559a613411909783767ebb9f6b1e0b7dcdd
sentinel current-epoch 1
除了redis官方自带的redis cluster集群之外,还有一些开源的集群解决方案可供参考使用。
codis
Codis是一个分布式Redis解决方案,对于上层的应用来说,连接到Codis Proxy和连接原生的Redis Server没有显著区别。
上层应用可以像使用单机的redis一样使用,Codis 底层会处理请求的转发,不停机的数据迁移等工作,所有后边的一切事情,对于前面的客户端来说都是透明的,可以简单的认为后边连接的是一个内存无限大的redis服务.
codis-proxy 相当于redis,即连接codis-proxy和连接redis是没有任何区别的,codis-proxy无状态,不负责记录是否在哪保存,数据在zookeeper 记录,即codis proxy向zookeeper查询key的记录位置,proxy将请求转发到一个组进行处理,一个组里面有一个master和一个或多个slave组成,默认有1024个槽位,redis cluster默认有16384个槽位,其把不同的槽位的内容放在不同的group。
Github地址:https://github.com/CodisLabs/codis/blob/release3.2/doc/tutorial_zh.md
twemproxy
由twemproxy双向代理客户端实现分片,即代替用户将数据分片到不同的后端服务器进行读写,其还支持memcached,可以为proxy配置算法,缺点为twemproxy是瓶颈,不支持数据迁移
Github地址:https://github.com/twitter/twemproxy