为什么要使用集群:
redis为了提高网站响应速度,总是把热点数据保存在缓存中而不是直接从后端数据库中读取。一般大型网站有28定律 80%访问量集中在20%的业务上。大型网站应用,热点数据量往往巨大,使用一台 Redis 实例无满足需求,这时就需要使用 多台 Redis (集群)作为缓存数据库。才能在用户请求时快速的进行响应。
优点:
1.高可用,防止单点故障
2.高性能,集群每一台主机读写能力与单节点相同级别,写压力多多分担点
3.方便扩展,当单个节点压力变大或者变小时,可以动态新加或者移除节点,集群正常使用
架构原理
1.所有的redis节点彼此互联(ping-pong机制),内部使用二进制协议优化传输速度和宽带
2.节点的fail是通过集群中超过半数的节点检测失效时才生效的
3.客户端与redis节点直连,不需要中间poxy层,客户端不需要连接集群中的所有节点,连接集群中的一个节点就可以
4.redis-cluster吧所有的物理节点映射到【0-1638】slot上,cluster负责维护node<->slot<->value(key=values) 16384
总的来说,redis-cluster就是为了去中心化,去中间件,,使集群中的每个节点都是平等的关系,都是对等,每个节点都保存各自数据和整个集群的状态,每个节点都和其它所有节点连接,这些节点连接保持活跃,就可以保证我们连接集群中的任何一个节点就可以获取其它节点的数据
具体实现:
1.单机创建节点
1./usr/redis目录下创建cluster目录;mkdir /usr/redis/cluster
2.在redis1-3中创建目录节点,每台机器创建两个
mkdir /usr/redis/custer/6001-6
3.复制redis.conf配置到节点目录下,每个节点复制一个
cp /usr/redis/redis-5.0.5/redis.conf /usr/redis/custer/6001-6
4.修改配置,六个节点都要改
vim /usr/redis/cluster/6001-6/redis.conf
:69 bing本机ip
:92 端口号 port 6001-6
:136 允许后台运行 daemonize yes
:158 pidfile文件对应端口号 pidfile /var/run/redis_6001.pid
:699 aof日志开启 有需要就开启,它会每次写操作都记录一条日志 appendonly yes
:832 开启集群 cluster-enable yes
:840 集群的配置,配置文件首次启动自动生成 cluster-config-file nodes_6001.conf
:846 请求超时,默认十五秒 cluster-node-timeout 15000
创建方式二:
1.复制6001下redis.conf 到6002-6006
本机复制:cp /usr/redis/custer/6001/redis.conf /usr/redis/cluster/6002
跨机复制:
scp -r /usr/redis/cluster/6001/redis.conf 192.168.152.32:/usr/redis/cluster/6003-4
scp -r /usr/redis/cluster/6001/redis.conf 192.168.152.33:/usr/cluster/6005-6
修改2和3虚拟机下复制过来的文件
vim /usr/redis/cluster/6002-6/redis.conf
主机本机ip的修改
在底行模式下使用全局替换,把6001替换到相应2-6:
%s/6001/6002-6/g
启动:
redis1:
/usr/redis/bin/redis-server /usr/redis/cluster/6001/redis.conf
/usr/redis/bin/redis-server /usr/redis/cluster/6002/redis.conf
redis2
/usr/redis/bin/redis-server /usr/redis/cluster/6003/redis.conf
/usr/redis/bin/redis-server /usr/redis/cluster/6004/redis.conf
redis3
/usr/redis/bin/redis-server /usr/redis/cluster/6005/redis.conf
/usr/redsi/bin/redis-server /usr/redis/cluster/6006/redis.conf
在all-session中检查:
ps -ef|grep redis-server |grep -v grep |wc -l
可以查看到六个
创建集群
redis-cli --cluster create ip1:6001 ip2:6002 ip3:6003 ip4:6004 ip5:6005 ip6:6006 --cluster-replicas 1
然后yes
[OK] All 16384 slots covered // 成功!!
每次set get重定向原因:
Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽 (hash slot)的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384。所以我们在测试的时候看到set 和 get 的时候,直接跳转到了7000端口的节点。
集群的使用
关闭,就是关闭所有节点
启动,就是启动所有节点(即使虚拟机重启,也不受影响)
为了方便集群的启动和关闭,编写一个脚本
#!/bin/bash
rpsnum=`ps -ef|grep redis-server|grep -v grep|wc -l`
if [ $rpsnum -eq 0 ];then
echo '准备启动redis集群'
ssh 192.168.170.41 "/usr/redis/bin/redis-server /usr/redis/cluster/6001/redis.conf"
ssh 192.168.170.41 "/usr/redis/bin/redis-server /usr/redis/cluster/6002/redis.conf"
ssh 192.168.170.42 "/usr/redis/bin/redis-server /usr/redis/cluster/6003/redis.conf"
ssh 192.168.170.42 "/usr/redis/bin/redis-server /usr/redis/cluster/6004/redis.conf"
ssh 192.168.170.43 "/usr/redis/bin/redis-server /usr/redis/cluster/6005/redis.conf"
ssh 192.168.170.43 "/usr/redis/bin/redis-server /usr/redis/cluster/6006/redis.conf"
echo 'redis集群启动完毕'
else echo '准备关闭redis集群'
ssh 192.168.170.41 "/usr/redis/bin/redis-cli -h 192.168.170.41 -p 6001 shutdown"
ssh 192.168.170.41 "/usr/redis/bin/redis-cli -h 192.168.170.41 -p 6002 shutdown"
ssh 192.168.170.42 "/usr/redis/bin/redis-cli -h 192.168.170.42 -p 6003 shutdown"
ssh 192.168.170.42 "/usr/redis/bin/redis-cli -h 192.168.170.42 -p 6004 shutdown"
ssh 192.168.170.43 "/usr/redis/bin/redis-cli -h 192.168.170.43 -p 6005 shutdown"
ssh 192.168.170.43 "/usr/redis/bin/redis-cli -h 192.168.170.43 -p 6006 shutdown"
echo 'redis集群关闭完毕
'fi
chmod u+x /root/shelldir/redis-cluster-start-stop.sh 改变执行权限
/root/shelldir/redis-cluster-start-stop.sh 启动/关闭
ps -ef |grep redis-server |grep -v grep 在all-session测试
主节点异常,从节点自动顶替主节点
让任意主节点故障
/usr/redis/bin/redis-cli -h 192.168.152.33 -p 6005 shutdown
查看进程;
ps -ef|grep redis-server|grep -v grep
再次连接:
/usr/redis/bin/redis-cli -h 192.168.152.31 -p 6002 -c
info发现6005主节点fail
再次启动6005:
/usr/redis/bin/redis-server /usr/reids/cluster/6005/redis.conf
查看是否启动成功:
ps -ef|grep redsi-server|grep -v grep
发现6005主节点变为从节点
集群的fail
- 集群任意master挂掉,且当前master没有slave.集群进入fail状态,因为集群的slot映射[0-16383]不完整,集群进入fail状态.
挂掉一个从节点,再挂断其主节点:
/usr/redsi/bin/redis-cli -h 192.168.152.31 -p 6004 shutdown
再次连接查看宕机情况:
/usr/redis/bin/redis-cli -h 192.168.152.31 -p 6001 -c
cluster nodes
宕机主节点
/usr/redis/bin/redis-cli -h 192.168.152.31 -p 6001 shutdown
查看:
ps -ef |grep redsi-server|grep -v grep
再次连接查看:
/usr/redis/bin/redis-cli -h 192.168.152.32 -p 6003 -c
查看cluster nodes
发现cluster-state:fail
2)集群超过半数以上master挂掉,无论是否有slave集群进入fail状态.
挂掉两个主机:
/usr/redis/bin/redis-cli -h 192.168.31 -p 6001 shutdown
/usr/redsi/bin/redis/redis-cli -h 192.168.152.32 -p 6005 shutdown
再次连接没有挂的主节点查看:
/usr/redsi/bin/redis-cli -h 192.168.152.33 -p 6003 -c
cluster info
发现cluster-state:fail
免密登陆:
转换方:生成密钥
ssh-keygen -t rsa
然后免密到目的放:
ssh-copy-id 目的ip
shell 192.168.152.32