sentinel哨兵模式的缺点 1.在sentinel选举出来新master时,选举期间会存在访问瞬断的情况 2.哨兵模式对外只有master节点可以写,slave节点只能用于读,写的压力相对较大,高并发场景下不合适 3.Redis的单节点内存不能设置过大,若数据过大在主从同步将会很慢;在节点启动的时候由于需要全量同步很慢
Redis集群的优点
Redis集群有多个master,不需要切换,可以减小访问瞬断问题的影响
Redis集群有多个master,可以提供更高的并发量
Redis集群可以分片存储,这样就可以存储更多的数据
Redis集群是一个由多个主从节点 群组成的分布式服务集群,它具有复制、高可用和分片 特性。
适合在数据量特别大的时候使用
Redis-Cluster工作原理
slots(槽位)机制 Redis Cluster将所有数据划分为16384个slots(槽位),每个节点负责其中一部分槽位。槽位的信息存储于每个节点中。只有master节点会被分配槽位,slave节点不会分配槽位。
第一步: 客户端连接到集群时,会给客户端返回一个槽位对应表,并且将其缓存到客户端本地
第二步: Cluster 默认会对 key 值使用 crc16 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模来得到具体槽位。 (根据k1计算出的槽值进行切换节点,并存入数据。不在一个slot下的键值,是不能使用mget、mset等多建操作)
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 redis-cluster的安装详见下面部分 192.168.10.116:8001> set k1 v1 -> Redirected to slot [12706] located at 192.168.10.118:8001 OK 192.168.10.118:8001> 在这里我set 了一个key之后 redis自动将key进行了hash 运算,并且计算出这个槽位是分配给192.168.10.118的 就自动给我切换过去了 同时也只能在192.168.10.118进行get k1的操作 在另外节点就无法get到 192.168.10.116:8001> get k1 -> Redirected to slot [12706] located at 192.168.10.118:8001 "v1" 通过{}来定义组,相同组中的键值对放到同个slot中 192.168.10.117:8001> mset k1{wang} 10 k2{wang} 20 k3{wang} 30 -> Redirected to slot [2919] located at 192.168.10.116:8001 OK 192.168.10.117:8001> get k2{wang} -> Redirected to slot [2919] located at 192.168.10.116:8001 "20" 192.168.10.117:8001> get k2 -> Redirected to slot [449] located at 192.168.10.116:8001 (nil)
Redis-Cluster通讯 在分布式存储中提供维护节点元数据信息的机制,使用gossip协议。
每个节点都会单独开辟一个tcp通道用于特殊通信,通信端口的在基础上加10000,如8001端口,开辟的就是18001端口。(发送ping消息,用pong消息作为相应)
在生产环境中,安全配置需要考虑到这个特殊端口
meeting消息
消息发送者发送给meeting,消息通信正常完成后,接受节点开始收发ping和pong消息
Redis-Cluster搭建
环境与配置文件 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 环境: centos7.9 redis版本5.0.5 192.168.10.116 redis1 192.168.10.117 redis2 192.168.10.118 redis3 使用8001端口作为master端口 使用8002端口作为slave端口 部署redis的过程略过 mkdir -p /usr/local/redis-cluster/8001mkdir -p /usr/local/redis-cluster/8002cd /usr/local/redis-clusterpkill redis rm -rf /usr/local/redis-cluster/8001/*rm -rf /usr/local/redis-cluster/8002/*cat >redis-cluster.conf<<EOF port 8001 daemonize yes pidfile "/var/run/redis_8001.pid" dir /usr/local/redis-cluster/8001 cluster-enabled yes #设置以集群模式启动 cluster-config-file nodes-8001.conf #集群节点信息文件 cluster-node-timeout 5000 #离线超时时间 bind 0.0.0.0 protected-mode no appendonly yes #使用aof EOF cat >redis-slave.conf<<EOF port 8002 daemonize yes pidfile "/var/run/redis_8002.pid" dir /usr/local/redis-cluster/8002 cluster-enabled yes cluster-config-file nodes-8002.conf cluster-node-timeout 5000 bind 0.0.0.0 protected-mode no appendonly yes EOF scp -r /usr/local/redis-cluster redis2:/usr/local/redis-cluster scp -r /usr/local/redis-cluster redis3:/usr/local/redis-cluster
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 redis-server /usr/local/redis-cluster/redis-cluster.conf redis-server /usr/local/redis-cluster/redis-slave.conf redis-cli -h 192.168.10.116 -p 8001 cluster nodes CLUSTER MEET 192.168.10.116 8002 cluster nodes 9a81edf239c532b6736a8910b2caddfae77ee93c 192.168.10.116:8002@18002 master - 0 1727091025966 0 connected 38a18490e78a35ef22f35ef80cd00c07389a2baa 192.168.10.116:8001@18001 myself,master - 0 0 1 connected cat 8001/nodes-8001.conf9a81edf239c532b6736a8910b2caddfae77ee93c 192.168.10.116:8002@18002 master - 0 1727091005009 0 connected 38a18490e78a35ef22f35ef80cd00c07389a2baa 192.168.10.116:8001@18001 myself,master - 0 0 1 connected vars currentEpoch 1 lastVoteEpoch 0 cluster info cluster_state:fail ... cluster_known_nodes:2 ... CLUSTER MEET 192.168.10.117 8001 CLUSTER MEET 192.168.10.117 8002 CLUSTER MEET 192.168.10.118 8001 CLUSTER MEET 192.168.10.118 8002 cluster nodes 9a81edf239c532b6736a8910b2caddfae77ee93c 192.168.10.116:8002@18002 master - 0 1727092265579 0 connected f5b3f524b1b024df2e74f749e8023dec2f6c2da6 192.168.10.118:8002@18002 slave 1b93b48276aece5b94de1ed9e060b65aa6c376a0 0 1727092265000 3 connected 06aada2ea17a85743fb7e02ae1cfcfb12c3acef1 192.168.10.118:8001@18001 master - 0 1727092266000 5 connected 10923-16383 1b93b48276aece5b94de1ed9e060b65aa6c376a0 192.168.10.117:8001@18001 master - 0 1727092266582 3 connected 5461-10922 38a18490e78a35ef22f35ef80cd00c07389a2baa 192.168.10.116:8001@18001 myself,master - 0 1727092265000 1 connected 736d0f4ccd33b00c0c128db6f9fd37da9e10d484 192.168.10.117:8002@18002 slave - 0 1727092267083 1 connected cluster info cluster_state:fail 集群状态依然失败,因为没有分配slots
手动分配槽位
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 cluster addslots {0..槽位数} 给上面三个的主节点添加: redis-cli -c -h 192.168.10.116 -p 8001 CLUSTER ADDSLOTS {0..5460} redis-cli -c -h 192.168.10.117 -p 8001 CLUSTER ADDSLOTS {5461..10922} redis-cli -c -h 192.168.10.118 -p 8001 CLUSTER ADDSLOTS {10923..16383} 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
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 redis-server /usr/local/redis-cluster/redis-cluster.conf redis-server /usr/local/redis-cluster/redis-slave.conf ps -ef | grep redis root 10389 1 0 22:46 ? 00:00:00 redis-server 0.0.0.0:8001 [cluster] root 10395 1 0 22:46 ? 00:00:00 redis-server 0.0.0.0:8002 [cluster] root 10414 8863 0 22:46 pts/1 00:00:00 grep --color=auto redis ss -tunlp | grep 800 tcp LISTEN 0 128 *:8001 *:* users :(("redis-server",pid=2 tcp LISTEN 0 128 *:8002 *:* users:(("redis-server",pid=2 tcp LISTEN 0 128 *:18001 *:* users:(("redis-server",pid=2 tcp LISTEN 0 128 *:18002 *:* users:(("redis-server",pid=2 ↑元数据通信端口 在初始化之前需要先清空数据库中的数据 redis-cli -h redis1 -p 8001 flushdb redis-cli -h red is2 -p 8001 flushdb redis-cli -h redis3 -p 8001 flushdb # 每个redis进程都会有一个对应的节点id cat 8001 /nodes-8001 .conf d7866353d9e708a59525c9783ff312459cd8f14d :0 @0 myself,master - 0 0 0 connected 或者 127.0 .0.1 :8001 > CLUSTER NODESd7866353d9e708a59525c9783ff312459cd8f14d :8001 @18001 myself,master - 0 0 0 connected 查看 # 初始化集群 redis-cli --cluster create --cluster-replicas 1 \ 192.168 .10.116 :8001 192.168 .10.116 :8002 192.168 .10.117 :8001 \192.168 .10.117 :8002 192.168 .10.118 :8001 192.168 .10.118 :8002 参数说明: -a 密码 --cluster create 表示新创建状态 --cluster-replicas 1 表示每个主节点的从节点数为1
Redis-Cluster信息 再次查看集群节点
这些节点都是各个节点中查看到的node-id信息
1 2 3 4 5 6 7 redis-cli -h redis1 -p 8001 cluster nodes f5b3f524b1b024df2e74f749e8023dec2f6c2da6 192.168.10.118:8002@18002 slave 1b93b48276aece5b94de1ed9e060b65aa6c376a0 0 1727089606773 6 connected d7866353d9e708a59525c9783ff312459cd8f14d 192.168.10.116:8001@18001 myself,master - 0 1727089607000 1 connected 0-5460 736d0f4ccd33b00c0c128db6f9fd37da9e10d484 192.168.10.117:8002@18002 slave d7866353d9e708a59525c9783ff312459cd8f14d 0 1727089608276 4 connected 1b93b48276aece5b94de1ed9e060b65aa6c376a0 192.168.10.117:8001@18001 master - 0 1727089606272 3 connected 5461-10922 06aada2ea17a85743fb7e02ae1cfcfb12c3acef1 192.168.10.118:8001@18001 master - 0 1727089607074 5 connected 10923-16383 c93652ccdcb6a640b66ffbfff913ba923d3995d7 192.168.10.116:8002@18002 slave 06aada2ea17a85743fb7e02ae1cfcfb12c3acef1 0 1727089607273 5 connected
查看集群状态
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 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:809 cluster_stats_messages_pong_sent:847 cluster_stats_messages_sent:1656 cluster_stats_messages_ping_received:842 cluster_stats_messages_pong_received:809 cluster_stats_messages_meet_received:5 cluster_stats_messages_received:1656
Redis-Cluster简单故障恢复测试 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 CLUSTER NODES 1da6c02ff0dbbfbb13a36e2763b9ec9cec5e712c 192.168.10.118:8001@18001 master - 0 1721143350546 5 connected 10923-16383 d5a3fe999c0375bf625d7e7038b22f27616d5d71 192.168.10.117:8001@18001 master - 0 1721143351548 3 connected 5461-10922 2c767536a9cbe2a0afafe154fd2a7c925cff5afc 192.168.10.116:8002@18002 slave 1da6c02ff0dbbfbb13a36e2763b9ec9cec5e712c 0 1721143351548 5 connected bd04e3bd7b58e60732fd243d002497633790c85e 192.168.10.118:8002@18002 slave d5a3fe999c0375bf625d7e7038b22f27616d5d71 0 1721143350000 6 connected 2bf33697731457bcfcbe11cffbec0ed70dde9330 192.168.10.117:8002@18002 slave 2031e58e9a74a6fb3e4a71d29e1f0aea3758902f 0 1721143350546 4 connected 2031e58e9a74a6fb3e4a71d29e1f0aea3758902f 192.168.10.116:8001@18001 myself,master - 0 1721143350000 1 connected 0-5460 ps -ef | grep redis root 10389 1 0 22:46 ? 00:00:02 redis-server 0.0.0.0:8001 [cluster] root 10395 1 0 22:46 ? 00:00:02 redis-server 0.0.0.0:8002 [cluster] kill 10389CLUSTER NODES 2c767536a9cbe2a0afafe154fd2a7c925cff5afc 192.168.10.116:8002@18002 slave 1da6c02ff0dbbfbb13a36e2763b9ec9cec5e712c 0 1721143556539 5 connected 1da6c02ff0dbbfbb13a36e2763b9ec9cec5e712c 192.168.10.118:8001@18001 master - 0 1721143556038 5 connected 10923-16383 bd04e3bd7b58e60732fd243d002497633790c85e 192.168.10.118:8002@18002 slave d5a3fe999c0375bf625d7e7038b22f27616d5d71 0 1721143557000 6 connected 2bf33697731457bcfcbe11cffbec0ed70dde9330 192.168.10.117:8002@18002 master - 0 1721143555035 8 connected 0-5460 d5a3fe999c0375bf625d7e7038b22f27616d5d71 192.168.10.117:8001@18001 myself,master - 0 1721143555000 3 connected 5461-10922 2031e58e9a74a6fb3e4a71d29e1f0aea3758902f 192.168.10.116:8001@18001 master,fail - 1721143509189 1721143508000 1 disconnected 可以看到刚刚那台192.168.10.116:8001现在是fail状态 原本的备机192.168.10.117:8002变成了master