一、Redis群集架构细节:
1、所有的Redis节点彼此互联(PING-PONG机制)内部使用二进制协议优先传输速度和带宽。
2、节点的失效(fail)在群集中超过半数的主(master)节点检测失效时才会生效。
3、客户端与redis节点直连,不需要中间代理(proxy)层,客户端不需要连接群集所有节点,连接群集中任何一个可用节点即可。
4、redis-cluster把所有的物理节点映射到 [ 0-1638 ] slot 上,cluster负责维护node< - >slot< - > key。 二、redis-cluster选举: 选举过程是群集中所有master参与,如果半数以上master节点与当前master节点通信超时(cluster-node-timeout),认为当前master节点挂掉。以下两种情况为整个群集不可用(cluster_state:fail),当群集不可用时,所有对群集的操作都不可用,收到((error)CLUSTERDOWN Thecluster is down)错误:
默认情况下,每个群集的节点都是用两个TCP端口,一个是6379,一个是16379;6379服务于客户端的连接,16379用于群集总线,就是使用二进制协议的节点到节点通信通道。节点使用群集总线进行故障检测、配置更新、故障转移授权等。 Redis群集原理:
1、Redis集群架构: Redis Cluster采用虚拟槽分区,将所有的数据根据算法映射到0~16384整数槽内 Redis Cluster是一个无中心的结构 每个节点都保存数据和整个集群的状态 2、集群角色: Master:Master之间分配slots Slave:Slave向它指定的Master同步数据 3、集群节点使用的TCP端口 6379端口用于客户端的连接 16379端口用于群集总线
Redis3.0版本以上开始支持群集,采用的是hash slot(哈希槽),可以将多个Redis实例整合在一起,形成一个群集,也就是将数据分散到群集的多台服务器上。 . Redis cluster(Redis 群集)是一个无中心的结构,如下图所示,每个节点都会保存数据和整个群集的状态。每个节点都会保存其他节点的信息,知道其他节点所负责的槽,并且会与其他节点定时发送心跳信息,能够及时感知群集中异常的节点。
当客户端向群集中任一节点发送与数据库键有关的命令时,接受命令的节点会计算出命令要处理的数据属于哪个槽,并检查这个槽是否指派给了自己,如果键所在的槽正好指派给了当前节点,那么节点直接执这个命令;如果键值所在的槽并没有指派给当前节点,那么节点会向客户端返回一个MOVED错误,指引客户端转向(redirect)正确的节点,并再次发送之前想要执行的命令。 . 群集角色有master和slave。master之间分配slots,一共16384个slot。slave向它指定的master同步数据,实现备份。当其中一个master无法提供服务时,该master的slave将提升为master,以保证群集间slot的完整性。当其中的某一个master和它的slave都失效,导致了slot不完整,群集失效,这时就需要运维人员去处理了。 . 群集搭建好后,群集中的每个节点都会定期地向其他节点发送PING消息,如果接收PING消息的节点没有在规定的时间内返回PONG消息,那么发送PING消息的节点就会将其标记为疑似下线(PFAIL)。各个节点会通过互相发送消息的方式来交换群集中各个节点的状态信息。如果已经在一个群集里面,半数以上的主节点都将某个主节点x报告为疑似下线,那么这个主节点x将被标记为已下线(FAIL),同时会向群集广播一条关于主节点x的FAIL消息,所有收到这条FAIL消息的节点都会立即将主节点x标记为已下线。 . 当需要减少或者增加群集中的服务器时,我们需要将已经指派给某个节点(源节点)的槽改为指派给另一个节点(目标节点),并且将相关槽所包含的键值对从源节点移动到目标节点。 . Redis群集的重新分片操作时由Redis的群集管理软件redis-trib负责执行的,不支持自动分片,而且需要自己计算从哪些节点迁移多少Slot。在重新分片的过程中,群集无需下线,并且源节点和目标节点都可以继续处理命令请求。 准备工作: 1、六台服务器,三台为master、三台为slave,这里均为centos 7,IP地址依次为192.168.1.10--60(参与群集的服务器数量最好为偶数,每个master会自动对应一个slave,若为奇数,群集无法实现冗余,因为必定有一个master没有对应的slave,一旦这个master宕机,整个群集就会丢失一部分数据); 2、所需源码包: https://pan.baidu.com/s/12L6jNOBrXeLH4I445_uUtQ 提取码: smn6 3、所有redis服务器必须保证无任何数据,最好是全新安装的,因为如果有数据存在,在后面进行群集时会报错。 4、配置防火墙放行流量,本人较懒,这里直接关闭了 开始部署: 192.168.1.10 上的配置:
[root@localhost media]# ls
redis-3.2.0.gem redis-3.2.9.tar.gz
[root@localhost media]# cp * /usr/src/ # 将软件包复制
[root@localhost media]# cd /usr/src/
[root@localhost src]# ls # 确认都在呢
debug kernels redis-3.2.0.gem redis-3.2.9.tar.gz
[root@localhost src]# tar zxf redis-3.2.9.tar.gz
[root@localhost src]# cd redis-3.2.9/
[root@localhost redis-3.2.9]# make && make install # 编译并安装
[root@localhost redis-3.2.9]# cd utils/ # 再进一个子目录
[root@localhost utils]# ./install_server.sh # 一路回车即可
# 因为make install 只是安装了二进制文件到系统中,并没有启动脚本和配置文件,所以需要通过install_server.sh来设置 redis 服务所需要的相关配置文件。
[root@localhost utils]# cd /etc/init.d/ #优化redis控制启停方式
[root@localhost init.d]# mv redis_6379 redis
[root@localhost init.d]# chkconfig --add redis #将redis添加为系统服务
[root@localhost init.d]# systemctl restart redis #重启服务,以测试是否生效
[root@localhost /]# vim /etc/redis/6379.conf # 修改配置文件,修改以下几条
.......................
bind 192.168.1.10 // 设置监听 IP 地址
daemonize yes
logfile /var/log/redis_6379.log // 指定日志文件
cluster-enabled yes // 启动群集
cluster-config-file nodes-6379.conf // 群集配置文件
cluster-node-timeout 15000 // 节点超时时间,默认为毫秒
cluster-require-full-coverage no // 将yes改为no
port 6379 // 监听端口
# 保存退出
主配置文件修改完毕后先别着急启服务,因为我们需要在每一台服务器上都要安装 redis ,按照之前的方法安装即可,然后修改配置文件。其中每台服务器都要修改,只是监听IP地址不同而已,其他的配置都一样。所以,嘿嘿嘿~
192.168.1.20 的配置:
# 安装完毕redis后
[root@localhost utils]# scp root@192.168.1.10:/etc/redis/6379.conf /etc/redis/
# 我们直接将第一台的主配文件复制过来使用,修改一下监听IP就可以了
[root@localhost utils]# vim /etc/redis/6379.conf
........................
bind 192.168.1.20
然后将剩下的几台服务器依次配置完毕。 回到 192.168.1.1配置: 使用脚本创建群集:
[root@localhost /]# yum -y install ruby rubygems
# 创建群集会用到ruby的一个脚本,在创建群集前,需要先安装ruby的运行环境和客户端,在任何一台服务器安装都可以
[root@localhost src]# gem install redis --version 3.2.0 # 执行这条命令需要此文件redis-3.2.0.gem,所以执行前切换到拥有此文件的目录
Successfully installed redis-3.2.0
Parsing documentation for redis-3.2.0
Installing ri documentation for redis-3.2.0
1 gem installed
[root@localhost src]# ./redis-trib.rb create --replicas 1 \
> 192.168.1.10:6379 \
> 192.168.1.20:6379 \
> 192.168.1.30:6379 \
> 192.168.1.40:6379 \
> 192.168.1.50:6379 \
> 192.168.1.60:6379
.20:6379 192.168.1.30:6379 192.168.1.40:6379 192.168.1.50:6379 192.168.1.60:6379 >>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.1.10:6379
192.168.1.20:6379
192.168.1.30:6379
Adding replica 192.168.1.40:6379 to 192.168.1.10:6379
Adding replica 192.168.1.50:6379 to 192.168.1.20:6379
Adding replica 192.168.1.60:6379 to 192.168.1.30:6379
M: 4234dad1a041a91401d6e635c800581172e850dc 192.168.1.10:6379
slots:0-5460 (5461 slots) master
M: b386e4089c6f45a59d371549cda306669dd6938f 192.168.1.20:6379
slots:5461-10922 (5462 slots) master
M: c1d6d14364e8c5db2ae1ea3ee07360a8b17127d8 192.168.1.30:6379
slots:10923-16383 (5461 slots) master
S: e772a17543efb1e11cd05d792c11319b0fbfee5f 192.168.1.40:6379
replicates 4234dad1a041a91401d6e635c800581172e850dc
S: f0a387bf5f366de0e25c575588349bd424a0ff90 192.168.1.50:6379
replicates b386e4089c6f45a59d371549cda306669dd6938f
S: abc2fef19988e6626243feff831bced36b83b642 192.168.1.60:6379
replicates c1d6d14364e8c5db2ae1ea3ee07360a8b17127d8
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.1.10:6379)
M: 4234dad1a041a91401d6e635c800581172e850dc 192.168.1.10:6379
slots:0-5460 (5461 slots) master
1 additional replica(s)
M: c1d6d14364e8c5db2ae1ea3ee07360a8b17127d8 192.168.1.30:6379
slots:10923-16383 (5461 slots) master
1 additional replica(s)
M: b386e4089c6f45a59d371549cda306669dd6938f 192.168.1.20:6379
slots:5461-10922 (5462 slots) master
1 additional replica(s)
S: f0a387bf5f366de0e25c575588349bd424a0ff90 192.168.1.50:6379
slots: (0 slots) slave
replicates b386e4089c6f45a59d371549cda306669dd6938f
S: e772a17543efb1e11cd05d792c11319b0fbfee5f 192.168.1.40:6379
slots: (0 slots) slave
replicates 4234dad1a041a91401d6e635c800581172e850dc
S: abc2fef19988e6626243feff831bced36b83b642 192.168.1.60:6379
slots: (0 slots) slave
replicates c1d6d14364e8c5db2ae1ea3ee07360a8b17127d8
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
测试一下群集:
[root@localhost /]# redis-cli -h 192.168.1.20 -p 6379 -c
192.168.1.20:6379> set zhangsan 123123 # 创建一个值
-> Redirected to slot [12767] located at 192.168.1.30:6379 # 发现他跑另一个服务器上了
OK
192.168.1.30:6379> get zhangsan # 也是可以查到
"123123"
[root@localhost src]# ./redis-trib.rb check 192.168.1.10:6379 # 查看群集状态
>>> Performing Cluster Check (using node 192.168.1.10:6379)
M: 4234dad1a041a91401d6e635c800581172e850dc 192.168.1.10:6379
slots:0-5460 (5461 slots) master
1 additional replica(s)
M: c1d6d14364e8c5db2ae1ea3ee07360a8b17127d8 192.168.1.30:6379
slots:10923-16383 (5461 slots) master
1 additional replica(s)
M: b386e4089c6f45a59d371549cda306669dd6938f 192.168.1.20:6379
slots:5461-10922 (5462 slots) master
1 additional replica(s)
S: f0a387bf5f366de0e25c575588349bd424a0ff90 192.168.1.50:6379
slots: (0 slots) slave
replicates b386e4089c6f45a59d371549cda306669dd6938f
S: e772a17543efb1e11cd05d792c11319b0fbfee5f 192.168.1.40:6379
slots: (0 slots) slave
replicates 4234dad1a041a91401d6e635c800581172e850dc
S: abc2fef19988e6626243feff831bced36b83b642 192.168.1.60:6379
slots: (0 slots) slave
replicates c1d6d14364e8c5db2ae1ea3ee07360a8b17127d8
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
redis-3.x.x和redis-5.x.x创建群集的区别:
使用命令不一样,redis-3.x.x使用redis-trib.rb命令,语法如下:
[root@localhost ~]#redis-trib.rb create --replicas 1 192.168.1.1:6379 ..192.168.1.6:6379
#redis-3.x.x创建群集。
[root@localhost src]# redis-trib.rb check 192.168.1.1:6379
#查看群集状态
# redis-trib.rb不可以直接使用,需要执行以下操作才可直接使用
[root@localhost src]# cd /usr/src/redis-5.0.5/src/
[root@localhost src]# cp redis-trib.rb /usr/local/bin/
#将该脚本复制到本地../bin下,以便直接使用。若不然,需要在目录下使用“./”执行该文件