1、redis单机模式及主从模式的问题
1.1、当master主库容量不够时
- 单机部署或主从模式等,在master容量不够时,是无法解决容量问题的,因为master只有一台
- 我们可以通过集群的方式,搭建多个master-slave(主从),从而进行扩容
1.2、并发写操作
- 当并发量大时,单台master是无法正确处理的(无论是单机模式还是主从模式,写操作只在master主库进行)
- 通过集群方式,master可以部署多台,分担单台master的写压力
另外:主从模式、薪火相传模式,当主机master宕机,导致IP地址发送变化,应用程序中配置需要修改对应的主机地址、端口等信息。
以上问题,之前可以通过代理主机来解决。
但是在redis3.0后,提供了"无中心化集群"配置
- 反向代理主机:
解释:
- 客户端访问后台系统,反向代理服务器的redis会根据对应的请求,转发到对应的redis中
- 每个服务的redis都是主从模式,防止master宕机后,redis无法使用
- 同样,转发服务的redis也是主从模式,防止转发服务的redis宕机后,整个系统崩溃
缺点:每一个子服务都需要部署主从模式,使用的服务器数量较高,加大了部署成本。
- 无中心化集群配置:
解释:
- 客户端请求可以从任何入口进入
- 当请求入库为订单时,若请求不是由该订单服务处理,会交给其他服务
2、什么是redis集群
- redis集群实现了对redis的水平扩容,即启动N个redis节点,将整个数据库分布式存储在这N个节点中,每个节点存储总数据的1/n(水平分片)。
- redis集群通过分区(partition)来提供一定程度的可用性(availability):即使集群中有一部分节点失效或者无法进行通讯,集群也可以继续处理命令请求。
3、搭建集群
由于电脑资源有限,我在1台Linux服务器中,开启6个redis服务(模拟6台服务器分别部署6个redis),搭建两个"1主2从"的集群
- 第一个1主2从的主从复制模式对应的redis端口为:
6379(master主)、6380(slave从1)、6381(slave从2)
- 第二个1主2从的主从复制模式对应的redis端口为:
6389(master主)、6390(slave从1)、6391(slave从2)
示例图如下:
1> 创建/myredis目录,复制redis.conf文件该目录
mkdir /myredis
我的redis在:/usr/local/redis
cp /usr/local/redis/redis-5.0.5/redis.conf /myredis/redis.conf
2>设置redis启动方式为守护进程方式(后台启动)
在/myredis/redis.conf中,找到:daemonize,改为yes,如下:
3>生成6个redis的启动配置文件
配置文件如下:
- redis6379.conf
- redis6380.conf
- redis6381.conf
- redis6389.conf
- redis6390.conf
- redis6391.conf
配置的内容如下(以redis6379服务器为例):
#表示引用redis.conf的配置(把redis.conf看作公共配置文件)
include /myredis/redis.conf
#指定redis服务启动的pid
pidfile /var/run/redis_6379.pid
#指定端口号
port 6379
#指定RDB持久化文件
dbfilename dump6379.rdb
#打开集群模式
cluster-enabled yes
#设定节点配置文件名
cluster-config-file modes-6379.conf
#设定节点失联时间(毫秒),超过该时间,集群自动进行主从切换
cluster-node-timeout 15000
注意:节点配置文件名应为:nodes开头(这样规范),而不是modes,这里我就不改了
如下:
接下来复制redis6379.conf为其他5个配置文件,如下:
执行完成后,目录下结构:
修改其他五个文件的端口,把文件中所有出现过6379的位置改为对应名称的端口,这里以redis6389.conf为例:
4>启动所有的redis服务
当所有的redis配置文件修改完成后,使用命令:
redis-server redis配置文件
如:
全部启动完成,查看redis后台进程:
ps -ef|grep redis
再查看当前目录结构,发现集群节点文件都已生成:
5>集群配置(合体)
进入到redis安装目录中的src下(我的redis安装在/usr/local/redis/redis-5.0.5):
cd /usr/local/redis/redis-5.0.5/src
把6台redis合为同一个集群,命令如下:
redis-cli --cluster create --cluster-replicas 1 192.168.221.128:6379 192.168.221.128:6380 192.168.221.128:6381 192.168.221.128:6389 192.168.221.128:6390 192.168.221.128:6391
解释:
- --cluster:表示集群
- create:集群的创建
- --cluster-replicas 1:每个主库下有1个从库
如下:
redis-cli --cluster create --cluster-replicas 1 192.168.221.128:6379 192.168.221.128:6380 192.168.221.128:6381 192.168.221.128:6389 192.168.221.128:6390 192.168.221.128:6391
6>连接集群
方式:
redis-cli -c -p 集群中的任意redis地址
4、集群的原理
1>slots
slot:插槽
一个redis集群包含16384个插槽(hashslot),数据库中的每个键(key)都属于这16384个插槽的其中一个
- 注意:一个插槽可以存储多个key
- 集群使用公式:CRC16(key)%16384来计算key属于哪个槽,其中CRC16(key)语句用于计算键key的CRC16校验和(了解即可,redis会自动算出该值,并在对应的主库中进行写操作,且只在该库中存储数据,其他的主库无法读取该数据)
2>查看集群状态
在任意节点中,执行:
cluster nodes
查看集群中的状态:
可以看到16384个插槽被分成了3段(分片):
- 端口为6379的master主库插槽为:0-5460
- 端口为6379的master主库插槽为:5461-10922
- 端口为6379的master主库插槽为:10923-16383
3>故障恢复
- 当集群中某一台主库宕机后,该主库下的从库会自动反客为主(集群自动整合了哨兵模式),升级为新的主库,当之前宕机的主库重新启动后,自动变为从库。
- 当集群中的一个主从模式下的redis都宕机后,集群能否正常运行,需要根据下面的redis.conf配置:
cluster-require-full-coverage
值:
- yes:当集群中一段插槽的主从都挂掉后,整个集群都挂掉
- no:当集群中一段插槽的主从都挂掉后,集群中的其他redis正常使用,但是集群中的本段插槽内的数据不能使用(包括读、写操作)