redis集群

redis集群、架构


一: redis 集群

  • 上一个步骤的主从架构无法实现master和slave角色的自动切换,即当master出现redis服务异常、主机断电、磁盘损坏等问题导致master无法使用,而redis高可用无法实现自故障转移(将slave提升为master),需要手动改环境配置才能切换到slave redis服务器,另外也无法横向扩展Redis服务的并行写入性能,当单台Redis服务器性能无法满足业务写入需求的时候就必须需要一种方式解决以上的两个核心问题,即:
    • 1.master和slave角色的无缝切换,让业务无感知从而不影响业务使用
    • 2.可以横向动态扩展Redis服务器,从而实现多台服务器并行写入以实现更高并发的目的。
  • Redis 集群实现方式:客户端分片 代理分片 Redis Cluster(做集群一般使用奇数台服务器做集群,3、5、7,损坏的节点剩余要大于总节点的一半)

  • Sentinel(哨兵):测试主从是否正常通讯:ping GONG(集群实现的前提是要使主从的版本相同)

    • Sentinel 进程是用于监控redis集群中Master主服务器工作的状态,在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用,其已经被集成在redis2.6+的版本中,Redis的哨兵模式到了2.8版本之后就稳定了下来。一般在生产环境也建议使用Redis的2.8版本的以后版本。哨兵(Sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossipprotocols)来接收关于Master主服务器是否下线的信息,并使用投票协议(Agreement Protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master。每个哨兵(Sentinel)进程会向其它哨兵(Sentinel)、Master、Slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定配置时间(可配置的)内未得到回应,则暂时认为对方已掉线,也就是所谓的”主观认为宕机” ,英文名称:Subjective Down,简称SDOWN。有主观宕机,肯定就有客观宕机。当“哨兵群”中的多数Sentinel进程在对Master主服务器做出 SDOWN 的判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,这种方式就是“客观宕机”,英文名称是:Objectively Down, 简称 ODOWN。通过一定的vote算法,从剩下的slave从服务器节点中,选一台提升为Master服务器节点,然后自动修改相关配置,并开启故障转移(failover)。
      Sentinel 机制可以解决master和slave角色的切换问题。
1
2
3
4
Sentinel(哨兵):哨兵判断服务器是否存活的方式
[root@centos7 redis]# redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> ping
PONG

实现哨兵默认端口26379

(在生产中建议哨兵是一台独立的服务器,这里演示的时redis服务器上实现哨兵,哨兵判断节点的存活状态机制:ping :pang)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
实验准备:
三台主机:全部编译安装,为了避免实验出现差别,尽量使用相同版本

主节点:172.18.135.1
从节点1:172.18.135.2
从节点2:172.18.135.3

实验目的如果主节点挂了,自动其中一个从节点上选择一个自动升级为主节点

第一步:
编辑所有主机的配置文件
修改本机的监听地址
76行
bind 0.0.0.0
修改主从结构的配置
286 replicaof 192.168.7.103 6379
293 masterauth 123456 #master如果密码需要设置
[root@centos7 ~]# systemctl restart redis.service

第二步:
首先实现一主两从架构
从节点1:
127.0.0.1:6379> info [
# Replication
role:slave
master_host:172.18.135.1
master_port:6379
master_link_status:up

从节点2:
127.0.0.1:6379> info [
# Replication
role:slave
master_host:172.18.135.1
master_port:6379
master_link_status:up

第三步:哨兵可以不和Redis服务器部署在一起
配置哨兵:编辑配置文件sentinel.conf:

master 、slave1、slave2 配置:
[root@centos7 ~]# cp /usr/local/src/redis-5.0.3/sentinel.conf /usr/local/redis/etc
[root@centos7 ~]# vim /usr/local/redis/etc/sentinel.conf
port 26379
daemonize yes
pidfile /usr/local/redis/data/redis-sentinel_26379.pid
logfile "/usr/local/redis/logs/sentinel_26379.log"
dir /usr/local/redis/data
sentinel monitor mymaster 172.18.131.1 6379 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 15000 #15秒
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

第四步:启动哨兵

每个节点上都启动哨兵
[root@centos7 ~]# /usr/local/redis/bin/redis-sentinel /usr/local/redis/etc/sentinel.conf
[root@centos7 etc]# ss -tnl
LISTEN 0 511 *:26379
查看哨兵的日志文件

第五步:哨兵验证
[root@centos7 ~]# redis-cli -p 26379
127.0.0.1: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=172.18.135.1:6379,slaves=2,sentinels=3

已经实现哨兵
可以创建值,并停用主节点,哨兵自动选举新的主节点

哨兵配置文件详情

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@redis-s1 etc]# grep "^[a-Z]" /usr/local/redis/etc/sentinel.conf 
bind 0.0.0.0
port 26379
daemonize yes #守护进程运行
pidfile "/usr/local/redis/redis-sentinel.pid"
logfile "/usr/local/redis/sentinel_26379.log"
dir "/usr/local/redis" # 哨兵运行产生的数据目录
sentinel monitor mymaster 192.168.7.101 6379 2 #这里的2表示,多少个哨兵决定主节点挂掉则提升新的主,此实验的哨兵有三个
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 #代表没有调用其他脚本

  • 应用程序如何连接redis?:
    • java客户端连接redis是通过jedis来实现的,java代码用的时候只要创建jedis对象就可以建多个jedis连接池来连接redis,应用程序再直接调用连接池即可连接Redis。
    • 而Redis为了保障高可用,服务一般都是Sentinel部署方式,当Redis服务中的主服务挂掉之后,会仲裁出另外一台Slaves服务充当Master。这个时候,我们的应用即使使用了Jedis连接池,Master服务挂了,我们的应用奖还是无法连接新的Master服务,为了解决这个问题,Jedis也提供了相应的Sentinel实现,能够在Redis Sentinel主从切换时候,通知我们的应用,把我们的应用连接到新的Master服务。
    • Jedis Sentinel的使用也是十分简单的,只是在JedisPool中添加了Sentinel和MasterName参数,Jedis Sentinel底层基于Redis订阅实现Redis主从服务的切换通知,当Reids发生主从切换时,Sentinel会发送通知主动通知Jedis进行连接的切换,JedisSentinelPool在每次从连接池中获取链接对象的时候,都要对连接对象进行检测,如果此链接和Sentinel的Master服务连接参数不一致,则会关闭此连接,重新获取新的Jedis连接对象。

二: Redis Cluster部署

  • Redis cluster之前的分布式方案:

    • 1) 客户端分区:由客户端程序决定key写分配和写入的redis node,但是需要客户端自己处理写入分配、高可用管理和故障转移等
    • 2)代理方案:基于三方软件实现redis proxy,客户端先连接之代理层,由代理层实现key的写入分配,对客户端来说是有比较简单,但是对于集群管节点增减相对比较麻烦,而且代理本身也是单点和性能瓶颈。
  • 在哨兵sentinel机制中,可以解决redis高可用的问题,即当master故障后可以自动将slave提升为master从而可以保证redis服务的正常使用,但是无法解决redis单机写入的瓶颈问题,即单机的redis写入性能受限于单机的内存大小、并发数量、网卡速率等因素,因此redis官方在redis 3.0版本之后推出了无中心架构的redis cluster机制,在无中心的redis集群汇中,其每个节点保存当前节点数据和整个集群状态,每个节点都和其他所有节点连接,特点如下:

    • 1:所有Redis节点使用(PING-PING机制)互联
    • 2:集群中某个节点的实效是整个集群中超过半数的节点监测都实效才算真正的实效
    • 3:客户端不需要proxy即可直接连接redis,且客户端不需要连接集群中的所有节点,只要连接集群中的任何一个节点即可。
    • 4:redis cluster把所有的redisnode映射到 0-16383个槽位(slot)上,读写需要到指定的redis node上进行操作,因此有多少个reids node相当于redis 并发扩展了多少倍。
    • 5:Redis集群预先分配16384个(slot)槽位,当需要在redis集群中写入一个key -value的时候,会使用CRC16(key) mod 16384之后的值,决定将key写入值哪一个槽位从而决定写入哪一个Redis节点上,从而有效解决单机瓶颈。

Redis cluster基本架构

  • 假如三个主节点分别是:A, B, C 三个节点,采用哈希槽 (hash slot)的方式来分配16384个slot 的话,它们三个节点分别承担的slot 区间是:
    • 节点A覆盖0-5460
    • 节点B覆盖5461-10922
    • 节点C覆盖10923-16383
  • 此结构缺点是主节点之间无法数据同步

Redis cluster主从架构:

  • Redis cluster的架构虽然解决了并发的问题,但是又引入了一个新的问题,每个Redis master的高可用如何解决?

部署redis集群:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#####################环境准备####################

三台服务器,每台服务器启动6379和6380两个redis 服务,生产环境建议直接6台服务器。
另外预留一台服务器做集群添加节点测试。

实验方式:基于端口的不同实现(生产环境中最好使用6台主机实现)
172.18.135.1:6379/6380 172.18.135.5:6379/6380
172.18.135.2:6379/6380

##############创建redis cluster集群的前提####目前仅有三台节点####
1.每个redis node节点采用相同的硬件配置、相同的密码
2.每个节点必须开启参数(确保每台节点都是主节点) #编辑配置文件
507 requirepass 123456 # 建议每个节点都设置密码,但是保证每个节点的密码保持一致
838 cluster-enabled yes #必须开启集群状态,开启后redis 进程会有cluster显示
846 cluster-config-file nodes-6380.conf #此文件有redis cluster集群自动创建和维护,不需要任何手动操作

################模拟一台节点上创建第二个节点###################
每台节点上模拟创建第二台节点实现一台机器上两个节点
[root@centos77 ~]# cp /usr/local/redis/etc/redis.conf /usr/local/redis/etc/redis6380.conf
#对原配置文件拷贝进行简单修改
bind 0.0.0.0
port 6380
pidfile "/var/run/redis_6380.pid"
logfile "/usr/local/redis/logs/6380.log"
cluster-config-file nodes-6380.conf

创建启动脚本
[root@centos77 ~]# cp /usr/lib/systemd/system/redis.service /usr/lib/systemd/system/redis6380.service
[root@centos77 ~]# vim !$
vim /usr/lib/systemd/system/redis6380

[Unit]
Description=Redis persistent key-value database
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis6380.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target

######################## 启动############################
[root@centos77 etc]# scp /usr/local/redis/etc/redis6380.conf root@172.18.135.1:/usr/local/redis/etc/
[root@centos77 etc]# scp /usr/local/redis/etc/redis6380.conf root@172.18.135.1:/usr/local/redis/etc/

[root@centos77 etc]# scp /usr/local/redis/etc/redis6380.conf root@172.18.135.1:/usr/local/redis/etc/
[root@centos77 etc]# scp /usr/local/redis/etc/redis6380.conf root@172.18.135.2:/usr/local/redis/etc/
[root@centos77 ~]# scp /usr/lib/systemd/system/redis6380.service root@172.18.135.2:/usr/lib/systemd/system/
[root@centos77 ~]# scp /usr/lib/systemd/system/redis6380.service root@172.18.135.1:/usr/lib/systemd/system/

启动查看端口
[root@centos77 etc]# ss -tnl
6379
6380


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
######################创建集群#####################
[root@redis-s1 ~]# redis-cli -a 123456 --cluster create 192.168.7.101:6379 192.168.7.101:6380 192.168.7.102:6379 192.168.7.102:6380 192.168.7.103:6379 192.168.7.103:6380 --cluster-replicas 1
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.7.102:6380 to 192.168.7.101:6379
Adding replica 192.168.7.101:6380 to 192.168.7.102:6379
Adding replica 192.168.7.103:6380 to 192.168.7.103:6379
>>> Trying to optimize slaves allocation for anti-affinity
[OK] Perfect anti-affinity obtained!
M: f4cfc5cf821c0d855016488d6fbfb62c03a14fda 192.168.7.101:6379 #带M的为master
slots:[0-5460] (5461 slots) master #当前master的槽位起始和结束位
S: 2b6e5d9c3944d79a5b64a19e54e52f83d48438d6 192.168.7.101:6380 #带S的slave
replicates 70de3821dde4701c647bd6c23b9dd3c5c9f24a62
M: 116c4c6de036fdbac5aaad25eb1a61ea262b64af 192.168.7.102:6379
slots:[5461-10922] (5462 slots) master #当前master的槽位起始和结束位
S: 7186c6d03dd9a5e3be658f2d08e800bc55b04a09 192.168.7.102:6380
replicates f4cfc5cf821c0d855016488d6fbfb62c03a14fda
M: 70de3821dde4701c647bd6c23b9dd3c5c9f24a62 192.168.7.103:6379
slots:[10923-16383] (5461 slots) master #当前master的槽位起始和结束位
S: 7eda0bcf0c01bb7343313b81267c42dd1b26c8a6 192.168.7.103:6380
replicates 116c4c6de036fdbac5aaad25eb1a61ea262b64af
Can I set the above configuration? (type 'yes' to accept): yes #输入yes自动创建集群
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.....
>>> Performing Cluster Check (using node 192.168.7.101:6379)
M: f4cfc5cf821c0d855016488d6fbfb62c03a14fda 192.168.7.101:6379 #master的ID及端口
slots:[0-5460] (5461 slots) master #已经分配的槽位
1 additional replica(s) #分配了一个slave
S: 7186c6d03dd9a5e3be658f2d08e800bc55b04a09 192.168.7.102:6380
slots: (0 slots) slave #slave没有分配槽位
replicates f4cfc5cf821c0d855016488d6fbfb62c03a14fda
M: 70de3821dde4701c647bd6c23b9dd3c5c9f24a62 192.168.7.103:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: 116c4c6de036fdbac5aaad25eb1a61ea262b64af 192.168.7.102:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 2b6e5d9c3944d79a5b64a19e54e52f83d48438d6 192.168.7.101:6380
slots: (0 slots) slave
replicates 70de3821dde4701c647bd6c23b9dd3c5c9f24a62
S: 7eda0bcf0c01bb7343313b81267c42dd1b26c8a6 192.168.7.103:6380
slots: (0 slots) slave
replicates 116c4c6de036fdbac5aaad25eb1a61ea262b64af
[OK] All nodes agree about slots configuration. #所有节点槽位分配完成
>>> Check for open slots... #检查打开的槽位
>>> Check slots coverage... #检查插槽覆盖范围
[OK] All 16384 slots covered. #所有槽位(16384个)分配完成


#########################检查状态######################
由于未设置masterauth认证密码,所以主从未建立起来,但是集群已经运行,所以需要在每个slave控制台使用config set设置masterauth密码,或者写在每个redis配置文件中,最好是在控制点设置密码之后再写入配置文件当中。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#######################分别设置masterauth密码#############
[root@redis-s1 ~]# redis-cli -h 192.168.7.101 -p 6380 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.7.101:6380> CONFIG SET masterauth 123456
OK
[root@redis-s1 ~]# redis-cli -h 192.168.7.102 -p 6380 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.7.102:6380> CONFIG SET masterauth 123456
OK
[root@redis-s1 ~]# redis-cli -h 192.168.7.103 -p 6380 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.7.103:6380> CONFIG SET masterauth 123456
OK

#######################确认slave状态为up##################


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
########################验证master状态###################
[root@redis-s1 ~]# redis-cli -h 192.168.7.101 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.7.101:6379> INFO Replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.7.102,port=6380,state=online,offset=840,lag=0
master_replid:0aa3281030eb29bf268f3317d4afe401f661a917
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:840
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:4026531840
repl_backlog_first_byte_offset:1
repl_backlog_histlen:840
192.168.7.101:6379>

###################管理要用集群的命令管理##############
#########################验证集群状态#################
192.168.7.101:6379> CLUSTER INFO
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:1474
cluster_stats_messages_pong_sent:1507
cluster_stats_messages_sent:2981
cluster_stats_messages_ping_received:1502
cluster_stats_messages_pong_received:1474
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:2981

########################查看集群node对应关系################
使用命令cluster nodes:
192.168.7.103:6380> cluster nodes
7186c6d03dd9a5e3be658f2d08e800bc55b04a09 192.168.7.102:6380@16380 slave f4cfc5cf821c0d855016488d6fbfb62c03a14fda 0 1545659135000 4 connected
7eda0bcf0c01bb7343313b81267c42dd1b26c8a6 192.168.7.103:6380@16380 myself,slave 116c4c6de036fdbac5aaad25eb1a61ea262b64af 0 1545659135000 6 conne
ctedf4cfc5cf821c0d855016488d6fbfb62c03a14fda 192.168.7.101:6379@16379 master - 0 1545659135000 1 connected 0-5460
116c4c6de036fdbac5aaad25eb1a61ea262b64af 192.168.7.102:6379@16379 master - 0 1545659136000 3 connected 5461-10922
70de3821dde4701c647bd6c23b9dd3c5c9f24a62 192.168.7.103:6379@16379 master - 0 1545659134000 5 connected 10923-16383
2b6e5d9c3944d79a5b64a19e54e52f83d48438d6 192.168.7.101:6380@16380 slave 70de3821dde4701c647bd6c23b9dd3c5c9f24a62 0 1545659135946 5 connected

##########################验证集群写入key##################
192.168.7.101:6379> SET key1 value1 #经过算法计算,当前key的槽位需要写入指定的node
(error) MOVED 9189 192.168.7.102:6379 #槽位不在当前node所以无法写入
192.168.7.103:6379> SET key1 value1
(error) MOVED 9189 192.168.7.102:6379
192.168.7.102:6379> SET key1 value1 #指定的node就可以写入
OK
192.168.7.102:6379> KEYS *
1) "key1"

192.168.7.101:6379> KEYS *
(empty list or set)
192.168.7.103:6379> KEYS *
(empty list or set)

#############################集群状态监控###################
# redis-cli -a 123456 --cluster check 192.168.7.101:6379

Redis cluster集群节点维护

  • 集群运行时间长久之后,难免由于硬件故障、网络规划、业务增长等原因对已有集群进行相应的调整, 比如增加Redis node节点、减少节点、节点迁移、更换服务器等。
    增加节点和删除节点会涉及到已有的槽位重新分配及数据迁移。

  • 集群维护之动态添加节点:

    • 增加Redis node节点,需要与之前的Redis node版本相同、配置一致,然后分别启动两台Redis node,因为一主一从。
  • 案例:
    • 因公司业务发展迅猛,现有的三主三从redis cluster架构可能无法满足现有业务的并发写入需求,因此公司紧急采购一台服务器192.168.7.104,需要将其动态添加到集群当中其不能影响业务使用和数据丢失,则添加过程如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
为了满足生产需求创建新的服务器
##同步之前Redis node的配置文件到192.168.7.104 Redis编译安装目录,注意配置文件的监听 IP##
scp redis.conf 192.168.7.104:/usr/local/redis/etc/
scp redis_6380.conf 192.168.7.104:/usr/local/redis/etc/

##################分别启动redis服务##########################
systemctl daemon-reload
systemctl restart redis
/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis_6380.conf

################将新创建的新的服务器添加节点到集群############
在新创建的节点上配置(新加入的节点是没有槽位的)
要添加的redis节点IP和端口 添加到的集群中的master IP:端口
# redis-cli -a 123456 --cluster add-node 192.168.7.104:6379 192.168.7.101:6379


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#############################分配槽位######################
添加主机之后需要对添加至集群种的新主机重新分片否则其没有分片
在新创建的节点上配置(分配的槽位是从以前每个节点上瓜分槽位来给新加入的服务器)
使用命令重新分配槽位:
[root@redis-s1 ~]# redis-cli -a 123456 --cluster reshard 192.168.7.104:6379
[root@redis-s1 ~]# redis-cli -a 123456 --cluster reshard 192.168.7.104:6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing Cluster Check (using node 192.168.7.104:6379)
M: 886338acd50c3015be68a760502b239f4509881c 192.168.7.104:6379
slots: (0 slots) master
M: 116c4c6de036fdbac5aaad25eb1a61ea262b64af 192.168.7.102:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 2b6e5d9c3944d79a5b64a19e54e52f83d48438d6 192.168.7.101:6380
slots: (0 slots) slave
replicates 70de3821dde4701c647bd6c23b9dd3c5c9f24a62
S: 7186c6d03dd9a5e3be658f2d08e800bc55b04a09 192.168.7.102:6380
slots: (0 slots) slave
replicates f4cfc5cf821c0d855016488d6fbfb62c03a14fda
M: 70de3821dde4701c647bd6c23b9dd3c5c9f24a62 192.168.7.103:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 7eda0bcf0c01bb7343313b81267c42dd1b26c8a6 192.168.7.103:6380
slots: (0 slots) slave
replicates 116c4c6de036fdbac5aaad25eb1a61ea262b64af
M: f4cfc5cf821c0d855016488d6fbfb62c03a14fda 192.168.7.101:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 4096 #分配多少个槽位192.168.7.104:6379
What is the receiving node ID? 886338acd50c3015be68a760502b239f4509881c #手动输入192.168.7.104的node ID
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1: all #将哪些源主机的槽位分配给192.168.7.104:6379,all是自动在所有的redis node选择划分,如果是从redis cluster删除主机可以使用此方式将主机上的槽位全部移动到别的redis主机
………………………………..
Moving slot 6823 from 116c4c6de036fdbac5aaad25eb1a61ea262b64af
Moving slot 6824 from 116c4c6de036fdbac5aaad25eb1a61ea262b64af
Moving slot 6825 from 116c4c6de036fdbac5aaad25eb1a61ea262b64af
Moving slot 6826 from 116c4c6de036fdbac5aaad25eb1a61ea262b64af
Moving slot 10923 from 70de3821dde4701c647bd6c23b9dd3c5c9f24a62
Moving slot 10924 from 70de3821dde4701c647bd6c23b9dd3c5c9f24a62
Moving slot 10925 from 70de3821dde4701c647bd6c23b9dd3c5c9f24a62
Moving slot 10926 from 70de3821dde4701c647bd6c23b9dd3c5c9f24a62
…………………………………..
Moving slot 1364 from f4cfc5cf821c0d855016488d6fbfb62c03a14fda
Do you want to proceed with the proposed reshard plan (yes/no)? yes #确认分配

##################验证重新分配槽位之后的集群状态#############
重新分配槽位是自动从每个Redis node上移动一些槽位到新的master上


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
###################为新的master添加slave节点###############
#master节点必须有salvae一但挂掉损失惨重
命令格式:(这样加入的192.168.7.104:6380 默认为master)
# redis-cli -a 123456 --cluster add-node 192.168.7.104:6380 192.168.7.104:6379

###################更改新节点更改状态为slave###############
需要手动将其指定为某个master 的slave,否则其默认角色为master
[root@redis-s1 ~]# redis-cli -h 192.168.7.104 -p 6380 -a 123456 #登录到新添加节点
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.7.104:6380> CLUSTER NODES #查看当前集群节点,找到目标master 的ID
7eda0bcf0c01bb7343313b81267c42dd1b26c8a6 192.168.7.103:6380@16380 slave 116c4c6de036fdbac5aaad25eb1a61ea262b64af 0 1545700464964 3 connected
116c4c6de036fdbac5aaad25eb1a61ea262b64af 192.168.7.102:6379@16379 master - 0 1545700470516 3 connected 6827-10922
2b6e5d9c3944d79a5b64a19e54e52f83d48438d6 192.168.7.101:6380@16380 slave 70de3821dde4701c647bd6c23b9dd3c5c9f24a62 0 1545700468498 5 connected
b9a00d59fa3c2a322080a1c7d84f53a2c853b089 192.168.7.104:6380@16380 myself,master - 0 1545700464000 0 connected
886338acd50c3015be68a760502b239f4509881c 192.168.7.104:6379@16379 master - 0 1545700465468 7 connected 0-1364 5461-6826 10923-12287
70de3821dde4701c647bd6c23b9dd3c5c9f24a62 192.168.7.103:6379@16379 master - 0 1545700467489 5 connected 12288-16383
f4cfc5cf821c0d855016488d6fbfb62c03a14fda 192.168.7.101:6379@16379 master - 0 1545700464461 1 connected 1365-5460
7186c6d03dd9a5e3be658f2d08e800bc55b04a09 192.168.7.102:6380@16380 slave f4cfc5cf821c0d855016488d6fbfb62c03a14fda 0 1545700469508 1 connected
192.168.7.104:6380> CLUSTER REPLICATE 886338acd50c3015be68a760502b239f4509881c #将其设置slave,设置为192.168.7.104:6379的slave
#命令格式为cluster replicate MASTERID
OK
192.168.7.104:6380> CLUSTER NODES #再次查看集群节点状态,验证节点是否已经更改为指定master 的slave
7eda0bcf0c01bb7343313b81267c42dd1b26c8a6 192.168.7.103:6380@16380 slave 116c4c6de036fdbac5aaad25eb1a61ea262b64af 0 1545700517970 3 connected
116c4c6de036fdbac5aaad25eb1a61ea262b64af 192.168.7.102:6379@16379 master - 0 1545700514942 3 connected 6827-10922
2b6e5d9c3944d79a5b64a19e54e52f83d48438d6 192.168.7.101:6380@16380 slave 70de3821dde4701c647bd6c23b9dd3c5c9f24a62 0 1545700518979 5 connected
b9a00d59fa3c2a322080a1c7d84f53a2c853b089 192.168.7.104:6380@16380 myself,slave 886338acd50c3015be68a760502b239f4509881c 0 1545700509000 0 connected
886338acd50c3015be68a760502b239f4509881c 192.168.7.104:6379@16379 master - 0 1545700516456 7 connected 0-1364 5461-6826 10923-12287
70de3821dde4701c647bd6c23b9dd3c5c9f24a62 192.168.7.103:6379@16379 master - 0 1545700519988 5 connected 12288-16383
f4cfc5cf821c0d855016488d6fbfb62c03a14fda 192.168.7.101:6379@16379 master - 0 1545700515953 1 connected 1365-5460
7186c6d03dd9a5e3be658f2d08e800bc55b04a09 192.168.7.102:6380@16380 slave f4cfc5cf821c0d855016488d6fbfb62c03a14fda 0 1545700516962 1 connected
192.168.7.104:6380>

#########################验证当前集群状态########################

集群维护之动态删除节点

  • 添加节点的时候是先添加node节点到集群,然后分配槽位,删除节点的操作与添加节点的操作正好相反,是先将被删除的Redis node上的槽位迁移到集群中的其他Redis node节点上,然后再将其删除。
    如果一个Redis node节点上的槽位没有被完全迁移,删除该node的时候会提升有数据且无法删除。
  • 案例:
    • 由于192.168.7.101服务器使用年限已经超过三年,已经超过厂商质保期而且硬盘出现异常报警,经运维部架构师提交方案并同开发同事开会商议,决定将现有Redis集群的4台服务器分别是192.168.7.101/192.168.7.102/192.168.7.103/192.168.7.104中的192.168.7.101临时下线,三台服务器的并发写入性能足够支出未来1-2年的业务需求,则删除Redis node 192.168.7.101的操作如下:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      ##############迁移master 的槽位之其他master##################
      [root@redis-s1 ~]# redis-cli -a 123456 --cluster reshard 192.168.7.102:6379
      Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
      >>> Performing Cluster Check (using node 192.168.7.102:6379)
      M: 116c4c6de036fdbac5aaad25eb1a61ea262b64af 192.168.7.102:6379
      slots:[6827-10922] (4096 slots) master
      1 additional replica(s)
      M: 70de3821dde4701c647bd6c23b9dd3c5c9f24a62 192.168.7.103:6379
      slots:[12288-16383] (4096 slots) master
      1 additional replica(s)
      M: 886338acd50c3015be68a760502b239f4509881c 192.168.7.104:6379
      slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
      1 additional replica(s)
      S: 7eda0bcf0c01bb7343313b81267c42dd1b26c8a6 192.168.7.103:6380
      slots: (0 slots) slave
      replicates 116c4c6de036fdbac5aaad25eb1a61ea262b64af
      S: b9a00d59fa3c2a322080a1c7d84f53a2c853b089 192.168.7.104:6380
      slots: (0 slots) slave
      replicates 886338acd50c3015be68a760502b239f4509881c
      S: 7186c6d03dd9a5e3be658f2d08e800bc55b04a09 192.168.7.102:6380
      slots: (0 slots) slave
      replicates f4cfc5cf821c0d855016488d6fbfb62c03a14fda
      S: 2b6e5d9c3944d79a5b64a19e54e52f83d48438d6 192.168.7.101:6380
      slots: (0 slots) slave
      replicates 70de3821dde4701c647bd6c23b9dd3c5c9f24a62
      M: f4cfc5cf821c0d855016488d6fbfb62c03a14fda 192.168.7.101:6379
      slots:[1365-5460] (4096 slots) master
      1 additional replica(s)
      [OK] All nodes agree about slots configuration.
      >>> Check for open slots...
      >>> Check slots coverage...
      [OK] All 16384 slots covered.
      How many slots do you want to move (from 1 to 16384)? 4096 #迁移master上的多少个槽位
      What is the receiving node ID? 886338acd50c3015be68a760502b239f4509881c #接收槽位的服务器ID
      Please enter all the source node IDs.
      Type 'all' to use all the nodes as source nodes for the hash slots.
      Type 'done' once you entered all the source nodes IDs.
      Source node #1: f4cfc5cf821c0d855016488d6fbfb62c03a14fda #从哪个服务器迁移4096个槽位
      Source node #2: done #写done,表示没有其他master了
      Moving slot 5457 from f4cfc5cf821c0d855016488d6fbfb62c03a14fda
      Moving slot 5458 from f4cfc5cf821c0d855016488d6fbfb62c03a14fda
      Moving slot 5459 from f4cfc5cf821c0d855016488d6fbfb62c03a14fda
      Moving slot 5460 from f4cfc5cf821c0d855016488d6fbfb62c03a14fda
      Do you want to proceed with the proposed reshard plan (yes/no)? yes #是否继续

      迁移完成!

      ######################验证槽位迁移完成########################


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
####################从集群删除服务器##########################
虽然槽位已经迁移完成,但是服务器IP信息还在集群当中,因此还需要将IP信息从集群删除
命令格式: redis-cli -a 123456 --cluster del-node IP:Port ID
#删除master:
[root@redis-s1 ~]# redis-cli -a 123456 --cluster del-node 192.168.7.101:6379 f4cfc5cf821c0d855016488d6fbfb62c03a14fda
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Removing node f4cfc5cf821c0d855016488d6fbfb62c03a14fda from cluster 192.168.7.101:6379
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

#删除slave:
该节点上如果还有其他节点上master 的slave,但是由于服务器下架也要一并删除,因此要提前把保证每个master至少有一个slave。
[root@redis-s1 ~]# redis-cli -a 123456 --cluster del-node 192.168.7.101:6380 2b6e5d9c3944d79a5b64a19e54e52f83d48438d6
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Removing node 2b6e5d9c3944d79a5b64a19e54e52f83d48438d6 from cluster 192.168.7.101:6380
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

####################验证node 是否删除######################
发现192.168.7.101已经被删除,但是由于192.168.7.101:6380之前是192.168.7.103:6379的slave,所以删除后会导致相应的master缺少slave,需要重新为没有slave的master分配slave。
可以发现下图的192.168.7.104有两个slave,分别是192.168.7.102:6380和192.168.7.104:6380,因此需要将其中一个slave转移为192.168.7.103的slave。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
####################重新分配slave#########################
将192.168.7.104:6380 转移为192.168.7.103的slave
[root@redis-s1 ~]# redis-cli -h 192.168.7.104 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.7.104:6379> CLUSTER NODES
116c4c6de036fdbac5aaad25eb1a61ea262b64af 192.168.7.102:6379@16379 master - 0 1545708439000 3 connected 6827-10922
b9a00d59fa3c2a322080a1c7d84f53a2c853b089 192.168.7.104:6380@16380 slave 886338acd50c3015be68a760502b239f4509881c 0 1545708440717 7 connected
7186c6d03dd9a5e3be658f2d08e800bc55b04a09 192.168.7.102:6380@16380 slave 886338acd50c3015be68a760502b239f4509881c 0 1545708437682 7 connected
886338acd50c3015be68a760502b239f4509881c 192.168.7.104:6379@16379 myself,master - 0 1545708439000 7 connected 0-6826 10923-12287
70de3821dde4701c647bd6c23b9dd3c5c9f24a62 192.168.7.103:6379@16379 master - 0 1545708440000 5 connected 12288-16383
7eda0bcf0c01bb7343313b81267c42dd1b26c8a6 192.168.7.103:6380@16380 slave 116c4c6de036fdbac5aaad25eb1a61ea262b64af 0 1545708438697 3 connected
192.168.7.104:6380> CLUSTER REPLICATE 70de3821dde4701c647bd6c23b9dd3c5c9f24a62
OK

##################验证集群Master与Slave对应关系#################
Redis Slave节点一定不能个master在一个服务器,必须为跨主机交叉备份模式,避免主机故障后主备全部挂掉,如果出现Redis Slave与Redis master在同一台Redis node的情况,则需要安装以上步骤重新进行slave分配,直到不相互交叉备份为止。

集群维护之模拟Master宕机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
目前的架构为三主三从,互为跨主机master slave模式。

#####################测试数据写入###########################
测试在master写入数据,并在其对应的slave验证数据:
192.168.7.102:6379> SET key1 value1
OK
192.168.7.102:6379> get key1
"value1"

#######################slave验证数据########################
192.168.7.103:6380> KEYS *
1) "key1"
192.168.7.103:6380> get key1
(error) MOVED 9189 192.168.7.102:6379 #slave不提供读写,只提供数据备份即master选举

####################停止master并验证故障转移################
Redis Master服务停止之后,其对应的slave会被选举为master继续处理数据的读写操作。
# systemctl stop redis

######################验证slave 日志#######################
# tail -f /usr/local/redis/redis_6380.log


1
#####################验证slave状态########################


1
2
3
4
5
6
7
8
9
10
11
12
######################验证数据读写#########################
确认slave 192.168.7.103:6380切换为master之后可以继续为业务提供读写业务且数据没有丢失。
192.168.7.103:6380> KEYS *
1) "key1"
192.168.7.103:6380> SET aaa bbb
OK
192.168.7.103:6380> get key1
"value1"
192.168.7.103:6380> get aaa
"bbb"
192.168.7.103:6380>
注:服务恢复之后重新验证各master的slave。

集群维护之导入现有Redis数据

  • 导入数据需要redis cluster不能与被导入的数据有重复的key名称,否则导入不成功或中断。
  • 案例:
    • 公司将redis cluster部署完成之后,需要将之前的数据导入之Redis cluster集群,但是由于Redis cluster使用的分片保存key的机制,因此使用传统的AOF文件或RDB快照无法满足需求,因此需要使用集群数据导入命令完成。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      #########################基础环境准备#####################

      导入数据之前需要关闭各redis 服务器的密码,包括集群中的各node和源Redis server,避免认证带来的环境不一致从而无法导入,但是可以加参数--cluster-replace 强制替换Redis cluster已有的key。
      [root@redis-s1 ~]# redis-cli -h 192.168.7.102 -p 6379 -a 123456
      Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
      192.168.7.102:6379> CONFIG SET requirepass ""
      OK
      192.168.7.104:6379> exit
      [root@redis-s1 ~]# redis-cli -h 192.168.7.102 -p 6380 -a 123456
      Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
      192.168.7.102:6380> CONFIG SET requirepass ""
      OK
      192.168.7.104:6379> exit

      [root@redis-s1 ~]# redis-cli -h 192.168.7.103 -p 6379 -a 123456
      Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
      192.168.7.103:6379> CONFIG SET requirepass ""
      OK
      192.168.7.103:6379> exit
      [root@redis-s1 ~]# redis-cli -h 192.168.7.103 -p 6380 -a 123456
      Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
      192.168.7.103:6380> CONFIG SET requirepass ""
      OK
      192.168.7.104:6379> exit

      [root@redis-s1 ~]# redis-cli -h 192.168.7.104 -p 6379 -a 123456
      Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
      192.168.7.104:6379> CONFIG SET requirepass ""
      OK
      192.168.7.104:6379> exit
      [root@redis-s1 ~]# redis-cli -h 192.168.7.104 -p 6380 -a 123456
      Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
      192.168.7.104:6380> CONFIG SET requirepass ""
      OK
      192.168.7.104:6379> exit


      #######################执行数据导入###########################
      将源Redis server的数据直接导入之redis cluster。
      命令格式:#redis-cli --cluster import 集群服务器IP:PORT --cluster-from 外部Redis node-IP:PORT --cluster-copy --cluster-replace
      [root@redis-s2 redis]# redis-cli --cluster import 192.168.7.103:6379 --cluster-from 192.168.7.101:6379 --cluster-copy


1
#####################edis cluster验证数据####################

redis扩展集群方案

  • 除了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

-------------------码字不易尊重原创转载标注不胜感激-------------------
Yes or no?
0%