Redis3.0版本以上开始支持cluster,采用的是hashslot(hash槽),可以将多个Redis实例整合在一起,形成一个群集,也就是将数据分散到群集的多台机器上。
Redis Cluster是一个无中心的结构(无中心管理节点),每个节点都保存数据和整个群集的状态。每个节点都会保存其他节点的信息,知道其他节点所负责的槽,并且会与其他节点定时发送心跳信息,能够及时感知群集中异常的节点。(heart-beat)#集群之间状态互通,数据不互通,只有主从之间数据互通
- 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
- 节点的失效(fail)在群集中超过半数的主(master)节点检测失效时才生效。
- 客户端与 redis 节点直连,不需要中间代理(proxy)层,客户端不需要连接群集所有节点,连接群集中任何一个可用节点即可。
- redis-cluster 把所有的物理节点映射到【0-16383】slot 上,cluster 负责维护 node<->slot<->key。
- 每个主都至少有一个从
- 选举过程是群集中所有master参与,如果半数以上master节点与当前 master 节点通信超时(cluster—node—timeout),认为当前 master 节点挂掉。以下两种情况为整个群集不可用(cluster_state:fail),当群集不可用时,所有对群集的操作都不可用,收到((error)CLUSTEFDOWN The cluster is down)错误。
- 如果群集任意 master挂掉,且当前 master 没有 slave,则群集进入 fail状态,也可以理解成群集的slot映射【0 ~16383】不完整时进入fail状态。\
- 如果群集中超过半数的master挂掉,无论是否有slave,群集都进入 fail状态。
- 默认情况下,每个群集的节点都使用两个TCP端口.一个是6379,一个是16379;6379服务于客户端的连接,16379 用于群集总线,即使用二进制协议的节点到节点通信通道。节点使用群集总线进行故障检测、配置更新、故障转移授权等。如果开启了防火墙,需要开放这两个端口。
此实验依托于redis主从同步,为方便将使用一台linux虚拟机进行,主从同步请见上一篇帖子。
Yum -y install epel-release
Yum -y install redis
Mkdir /etc/redis
Cp /etc/redis.conf /etc/redis/6379.conf #创建配置文件
Cd /etc/redis
for i in 6380 6381 6382 6383; do cp 6379.conf ${i}.conf;done
#创建6379,6380,6381,6382,6383,6384配置文件,此命令是用shell脚本的方式
ls #查看一下是否创建成功
批量更改各个配置文件中的port端口号
for i in {0..4};do sed -i "s/port 6379/port 638${i}/" ./638${i}.conf;done
for i in {0..4};do sed -i "s/port 6379/port 638${i}/" ./638${i}.conf;done
for i in {6379..6384};do sed -i "s#logfile /var/log/redis/redis.log#logfile /var/log/redis/${i}/redis.log#" ${i}.conf;done
for i in {6379..6384};do sed -i "s#pidfile /var/run/redis_6379.pid#pidfile /var/run/redis_${i}.pid#" ${i}.conf;done
for i in {6379..6384};do sed -i "s#protected-mode yes#protected-mode no#" ${i}.conf;done
for i in {6379..6384};do sed -i "s#daemonize no#daemonize yes#" ${i}.conf;done
for i in {6379..6384};do sed -i "s#bind 127.0.0.1#bind 192.168.112.161#" ${i}.conf;done
Mkdir 6379 638{0..4}
#创建四个日志目录
Mkdir 6379 638{0..4}
#创建四个数据目录
port
cluster-enabled yes
cluster-config-file nodes-【6379~6384】.conf
cluster-node-timeout 15000
可以直接执行脚本更改完成除了port之外的配置:
for i in {6379..6384};do echo -e "cluster-enabled yes\ncluster-config-file nodes-${i}.conf\ncluster-node-timeout 15000" >> ${i}.conf;done
for i in { 6379..6384} ; do sed -i “s#bind 127.0.0.1#bind 192.168.12.161#” ${i}.conf; done
也可以进入6379-6380.conf找到bind字段更改,此处更改的IP地址可根据实际情况指定的IP来定
for((i=6379;i<=6384;i++));do redis-server /etc/redis/${i}.conf;done
#批量启动
Netstat -anput | awk ‘/redis/{print $7}’
#查看一下服务是否启动
#for i in `netstat - anptu / awk ' /redis/[ print $7) ' | awk -F / ' { print $1) '` ; do kill -9$i; done
#可用此脚本批量停止服务,此时不使用,启动即可
将其他节点加入集群
redis- cli -h 192.168.112.161 - p 6379 cluster meet 192.168.112.161 6380
redis- cli -h 192.168.112.161 - p 6379 cluster meet 192.168.112.161 6381
redis- cli -h 192.168.112.161 - p 6379 cluster meet 192.168.112.161 6382
redis- cli -h 192.168.112.161 - p 6379 cluster meet 192.168.112.161 6383
redis- cli -h 192.168.112.161 - p 6379 cluster meet 192.168.112.161 6384
或者可以执行脚本批量加入:
for i in {6380..6384};do redis-cli -h 192.168.112.161 -p 6379 cluster meet 192.168.112.161 $i;done
redis-cli -p 6379 cluster addslots {0..5461}
redis-cli -p 6381 cluster addslots {5462..10922}
redis-cli -p 6383 cluster addslots {10923..16383}
登录6379redis,执行cluster nodes #查看所有群集节点,查看master节点ID,复制
登出执行:
redis-cli -p 6379 cluster addslots {0..5461}
redis-cli -p 6381 cluster addslots {5462..10922}
redis-cli -p 6383 cluster addslots {10923..16383}
#此时6380为6379的从
redis-cli -p 6382 cluster replicate 5cca472f9816273103769adb32b3a1b562f42655
#此时6382为6381的从
redis-cli -p 6384 cluster replicate 6d7219fd6db32e6014955edbeda26af6b59b9078
#此时6384为6383的从
登录6379redis,执行CLUSTER NODES #再次查看节点,是否已经配置上主从
执行CLUSTER INFO查看状态是否OK
重置集群命令:cluster reset
#数据的key不能相同
kill -9 杀死其中一个redis进程
在6379中进入6379数据库执行set f2 123查看是否可以随机分配槽
更换到6383中就可以执行成功了
启动杀死的redis进程
通过 cluster nodes查看节点状态
通过 cluster info 查看集群状态
登录所有从节点cluster failover