前言
前面学习了redis的主从复制和哨兵模式,提高了redis可用性。但是也存在一定的问题,哨兵模式下,主节点若突然卡顿或下线,可能会有几秒钟的写操作丢失。一般解决办法是在调用方捕捉到写失败时,通过代码控制重试。
这里介绍另一种主从复制的高可用方案,从3.0开始redis已经支持集群的容错功能。
redis集群模式是一种去中心化的模式,数据才存储时redis会根据算法(crc16)计算出一个结果,再拿这个结果对总槽数(16384)取余,得到的结果即要存储的槽数,随后切换至该槽所对应的节点进行数据的存取操作
集群搭建
redis集群至少需要3个主节点,因为redis集群有投票机制,超过半数的节点认为某个节点挂了,才能确认该节点挂了,很明显2个主节点无法投出超过半数的(挂)票。下面为具体搭建步骤:
-
复制6分配置文件模拟6台服务器(因为我只有一台云主机,电脑内存也不支持开6台虚拟机……)。
-
分别将端口配置为7001-7006。
-
6台服务器配置为3主3从,即每台master挂一个slave。
-
安装ruby(5.0已不需要安装ruby)
-
创建集群
配置cluster
-
创建文件夹存放cluster节点。
[root@VM-0-4-centos local]# mkdir -p redis-cluster/7001 [root@VM-0-4-centos local]# cd redis-cluster/7001/
-
将redis.conf文件copy至7001目录
[root@VM-0-4-centos 7001]# cp ../../redis-5.0.5/redis.conf ./
-
配置redis.conf文件的以下项目
bind 0.0.0.0 #bind修改为0.0.0.0或本机IP。 port 7001 #port修改为7001-7006。 daemonize yes #守护打开,运行方式改为后台运行。 dir /usr/local/redis-cluster/7001/ #指定数据文件存放位置 appendonly yes #持久化使用aof方式 cluster-enabled yes #打开集群模式 cluster-config-file nodes-7001.conf #指定节点的conf文件 cluster-node-timeout 15000 #指定节点超时
-
循环上述操作,分别配置7002-7006节点
过程略。
-
安装ruby(5.0版本可跳过本步骤)
redis集群需要使用ruby指令,所以需要安装ruby,分别执行以下指令安装ruby。
PS:centos7支持ruby至2.0.0,建立redis连接时会报错,需要升级ruby版本。参考连接:解决redis requires ruby version 2.3.0
[root@VM-0-4-centos redis-cluster]# yum install ruby [root@VM-0-4-centos redis-cluster]# yum install rubygems [root@VM-0-4-centos redis-cluster]# gem install redis
-
分别启动6台redis
[root@VM-0-4-centos redis-cluster]# redis-server 7001/redis.conf [root@VM-0-4-centos redis-cluster]# redis-server 7002/redis.conf [root@VM-0-4-centos redis-cluster]# redis-server 7003/redis.conf [root@VM-0-4-centos redis-cluster]# redis-server 7004/redis.conf [root@VM-0-4-centos redis-cluster]# redis-server 7005/redis.conf [root@VM-0-4-centos redis-cluster]# redis-server 7006/redis.conf [root@VM-0-4-centos redis-cluster]# ps -ef| grep redis root 21251 1 0 20:21 ? 00:00:00 redis-server 0.0.0.0:7001 [cluster] root 21258 1 0 20:21 ? 00:00:00 redis-server 0.0.0.0:7002 [cluster] root 21263 1 0 20:21 ? 00:00:00 redis-server 0.0.0.0:7003 [cluster] root 21268 1 0 20:21 ? 00:00:00 redis-server 0.0.0.0:7004 [cluster] root 21275 1 0 20:21 ? 00:00:00 redis-server 0.0.0.0:7005 [cluster] root 21280 1 0 20:21 ? 00:00:00 redis-server 0.0.0.0:7006 [cluster]
-
执行redis-trid.rb创建集群
-
5.0以下版本执行redis-trid.rb创建集群
# create:创建 # replicas:每个主节点下挂在几个子节点,1即 主节点数:从节点数 = 1:1 [root@VM-0-4-centos src]# ./redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006
-
5.0版本执行redis-cli --cluster创建集群
[root@VM-0-4-centos src]# redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluster-replicas 1>>> Performing hash slots allocation on 6 nodes... Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 Adding replica 127.0.0.1:7005 to 127.0.0.1:7001 Adding replica 127.0.0.1:7006 to 127.0.0.1:7002 Adding replica 127.0.0.1:7004 to 127.0.0.1:7003 >>> Trying to optimize slaves allocation for anti-affinity [WARNING] Some slaves are in the same host as their master M: 27799119db44ff70c9c0249bc68303fa163f46fc 127.0.0.1:7001 slots:[0-5460] (5461 slots) master M: 090839249a4993d5f63333622a19ba29aadd2be4 127.0.0.1:7002 slots:[5461-10922] (5462 slots) master M: da56283c9e47c44514a297e9c684ef23fd2b367f 127.0.0.1:7003 slots:[10923-16383] (5461 slots) master S: 70d0b084ed68e5ee5988cd50d62154f7e5124459 127.0.0.1:7004 replicates 090839249a4993d5f63333622a19ba29aadd2be4 S: dd44407bf6cfc543a7b59603ae6b7164c3bf3299 127.0.0.1:7005 replicates da56283c9e47c44514a297e9c684ef23fd2b367f S: 1f73e3d6bd5ed45c4a046b2de6943ef9c23f98d3 127.0.0.1:7006 replicates 27799119db44ff70c9c0249bc68303fa163f46fc Can I set the above configuration? (type 'yes' to accept): ==========================>这里打印了IP的角色分配,及每个节点的hash槽分配1、2、3为主节点,4、5、6为从节点,确认无误后输入yes保存配置 Can I set the above configuration? (type 'yes' to accept): 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 127.0.0.1:7001) M: 27799119db44ff70c9c0249bc68303fa163f46fc 127.0.0.1:7001 slots:[0-5460] (5461 slots) master 1 additional replica(s) M: da56283c9e47c44514a297e9c684ef23fd2b367f 127.0.0.1:7003 slots:[10923-16383] (5461 slots) master 1 additional replica(s) M: 090839249a4993d5f63333622a19ba29aadd2be4 127.0.0.1:7002 slots:[5461-10922] (5462 slots) master 1 additional replica(s) S: 1f73e3d6bd5ed45c4a046b2de6943ef9c23f98d3 127.0.0.1:7006 slots: (0 slots) slave replicates 27799119db44ff70c9c0249bc68303fa163f46fc S: dd44407bf6cfc543a7b59603ae6b7164c3bf3299 127.0.0.1:7005 slots: (0 slots) slave replicates da56283c9e47c44514a297e9c684ef23fd2b367f S: 70d0b084ed68e5ee5988cd50d62154f7e5124459 127.0.0.1:7004 slots: (0 slots) slave replicates 090839249a4993d5f63333622a19ba29aadd2be4 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. ============================[OK]到此全部16384个槽已经分配完毕,集群配置已保存至node.conf文件
-
登录客户端查看
redis-cli -c -h 127.0.0.1 -p 7001
- -c:集群
- -h:host
- -p:port
cluster info
- info :查看集群信息
- nodes:查看节点信息
# 查看集群信息 [root@VM-0-4-centos src]# redis-cli -c -h 127.0.0.1 -p 7001 127.0.0.1:7001> cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 <== 16384个槽OK cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 <== 共计6个节点 cluster_size:3 <== 3主从集群 cluster_current_epoch:6 cluster_my_epoch:1 cluster_stats_messages_ping_sent:667 cluster_stats_messages_pong_sent:657 cluster_stats_messages_sent:1324 cluster_stats_messages_ping_received:652 cluster_stats_messages_pong_received:667 cluster_stats_messages_meet_received:5 cluster_stats_messages_received:1324 =============================================================================================== 127.0.0.1:7001> cluster nodes da56283c9e47c44514a297e9c684ef23fd2b367f 127.0.0.1:7003@17003 master - 0 1597425171850 3 connected 10923-16383 <======节点信息,ip、端口、角色、槽数、连接数等 090839249a4993d5f63333622a19ba29aadd2be4 127.0.0.1:7002@17002 master - 0 1597425171000 2 connected 5461-10922 1f73e3d6bd5ed45c4a046b2de6943ef9c23f98d3 127.0.0.1:7006@17006 slave 27799119db44ff70c9c0249bc68303fa163f46fc 0 1597425170830 6 connected dd44407bf6cfc543a7b59603ae6b7164c3bf3299 127.0.0.1:7005@17005 slave da56283c9e47c44514a297e9c684ef23fd2b367f 0 1597425169000 5 connected 70d0b084ed68e5ee5988cd50d62154f7e5124459 127.0.0.1:7004@17004 slave 090839249a4993d5f63333622a19ba29aadd2be4 0 1597425169810 4 connected 27799119db44ff70c9c0249bc68303fa163f46fc 127.0.0.1:7001@17001 myself,master - 0 1597425170000 1 connected 0-5460
使用集群
使用集群登录主节点客户端进行数据操作
127.0.0.1:7001> keys * (empty list or set) <==== 其实为空 127.0.0.1:7001> set name zmc -> Redirected to slot [5798] located at 127.0.0.1:7002 OK <==== 设定值时重定向到[5798]槽存储,而5798槽位于7002节点 127.0.0.1:7002> set age 18 -> Redirected to slot [741] located at 127.0.0.1:7001 OK <==== 重定向到7001节点 127.0.0.1:7001> set sex male OK <==== 未进行重定向,扔存储于7001节点 127.0.0.1:7001> set addr1 sz -> Redirected to slot [12108] located at 127.0.0.1:7003 OK <==== 重定向至7003节点 127.0.0.1:7003>
分析上述打印信息可得知:
- 7001主节点下存储两个key:age和sex
- 7002主节点下存储一个key:name
- 7003主节点下存储一个key addr1
我们分别登陆三个节点查看keys
127.0.0.1:7001> keys * 1) "sex" 2) "age" 127.0.0.1:7002> keys * 1) "name" 127.0.0.1:7003> keys * 1) "addr1"
查看结果与预测一致,redis集群模式是一种去中心化的模式,数据才存储时redis会根据算法(crc16)计算出一个结果,再拿这个结果对总槽数(16384)取余,得到的结果即要存储的槽数,随后切换至该槽所对应的节点进行数据的存取操作。
-