redis的三种集群方案(主从复制、哨兵模式、集群模式)
redis的三种集群方案(主从复制、哨兵模式、集群模式)
单个redis的读写能力是有限的(虽然已经很强了),并且存在不稳定性。当唯一的redis服务宕机了,就没有可用的redis服务了,另外当硬件出现问题,单机的数据便无法恢复。redis集群的出现解决了单节点故障的问题,同时强化了redis的读写能力(负载均衡)
主从复制
主从复制是指一台redis服务器的数据复制到其他的redis服务器,前者为主节点(master),后者为从节点(slave)。数据的复制是单向的,只能由主节点到从节点。
默认情况下,每台redis服务器都是主节点,一个主节点可以有0或者多个从节点,但从节点只能有一个主节点。
主节点提供读写服务,从节点提供读服务,多个从节点分担读负载,提高了redis的并发量。
主从复制原理
全量复制:当从节点
(slave)启动成功并连接到主节点
(master)后,会向主节点发送sync
命令,请求数据同步。主节点
接收到命令后会启动一个子进程,将数据写入数据文件中(RDB操作),待数据写入完毕后,会将数据文件
传送给从节点
,从节点接收到文件后保存到磁盘上,并将数据加载到内存中,完成一次全量复制。
增量复制:在完成一次全量复制后,如果主节点
收到写操作的命令时,会以异步方式将命令复制给从节点
(在全量复制期间,如果主节点接收到了新的写操作命令,会先存入缓存,待从节点完成数据同步后,将新的写操作命令复制给从节点)
主从复制的优缺点
优点:
-
实现了读写分离,缓解了主节点读操作的压力,提高了可用性,解决了单机故障问题
-
主从复制期间主节点与从节点都是非阻塞的方式,仍然可用
缺点:
- 如果主节点发生宕机,需要手动切换主节点
- 如果RDB文件过大,同步过程比较耗时
部署redis主从复制
这里采用的是同一台服务器不同端口号的部署方式(因为没有多余服务器= =)
1.准备环境
准备三个redis,修改相应的redis配置参数,端口号分别为6379,6380,6381,之后启动三个redis服务
2.配置从节点
默认情况下,每台redis服务都是主节点,可以通过info replication命令可以查询
登陆redis客户端之后查询节点状态
[root@localhost test]# ./redis-node3/src/redis-cli -p 6381
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
通过slaveof命令可以配置主节点信息
127.0.0.1:6381> slaveof 127.0.0.1 6379
OK
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0
slave_repl_offset:71
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
通过slaveof no one 命令让该节点不再复制,该节点更改为主节点
127.0.0.1:6381> slaveof 127.0.0.1 6379
OK
除了命令的形式(命令形式只是暂时的,redis服务重启后从节点就会恢复为主节点)也可以在配置文件中写死,这样在服务重启时也会配置主节点的信息
主节点不需要配置,之后主节点写操作命令会增量复制到从节点上,相应key的数值也能获取到。主节点可以进行读写操作,从节点可以进行读操作
,如果从节点执行写操作会报错
注意:我这里部署的是redis5.0之前的版本,redis5.0之后的版本推荐用
replicaof
命令来替代slaveof
命令(当然此命令也支持),并且5.0之后的配置文件REPLICATION中的slaveof参数也更换为了replicaof
哨兵模式
对于主从复制,当主节点服务宕机后,就需要手动把一个从节点切换为主节点,需要人工干预,redis从2.8版本正式提供的
哨兵模式(Sentinel)
解决了这个问题,保证了服务的可用性
哨兵模式原理
哨兵的核心功能是在主从复制的基础上,哨兵引入了主节点的自动故障转移
1.哨兵的作用
- 哨兵是一个独立的进程,通过发送命令,让redis服务返回主从节点的状态信息,哨兵之间也相互监控,本身没有主从节点之分
- 当哨兵检测到主节点宕机时,会先对从节点进行竞选,将最佳的从节点切换为主节点,之后通过
发布订阅模式
通知其他从节点服务,修改配置,更换为复制新的主节点数据,旧的主节点也会变为从节点(即使服务恢复,也作为新的主节点的从节点)
2.服务下线
哨兵默认每隔1秒向redis服务发送PING命令,如果在规定的时间内(down-after-milliseconds参数配置,默认30秒)没有收到回复,则该哨兵会将该节点redis服务标记为下线(主观下线
)
此时哨兵会询问其他节点的哨兵,确认该节点是否下线,如果多数哨兵认为主节点下线(部署多个哨兵建议为奇数个),则主节点真正确认为下线(客观下线
),需要重新选出主节点(客观下线是主节点才有的概念,如果从节点或者单个哨兵发生故障,被哨兵主观下线后就结束了)
3.故障转移(failvoer)
- 在哨兵集群中选出一个Leader
- 由领头哨兵从节点中选出一个优先级最高的从节点,如果优先级相同,则从复制命令偏移量(同步的数据量)越大越优先,最后再比较进程ID越小越优先
- 选出新的主节点后,通过slaveof no one 命令使其成为独立节点,向其他节点发送slaveof masterip masterport命令让其他节点成为子节点
哨兵模式的优缺点
优点:
- 哨兵模式基于主从模式,具备主从复制的优点
- 具备了自动主从切换和故障转移,有了更高的可用性
缺点:
- 只有主节点可以进行写操作,写操作收单机影响
- 在线扩容比较复杂
哨兵模式的配置参数
与redis服务类似,哨兵也有自己的启动服务与配置文件
进入redis根目录执行命令
./src/redis-sentinel ./sentinel.conf
即可启动哨兵服务,前提是需要把配置文件中的配置参数改好
通过vi ./sentinel.conf来编辑配置参数,以下是常用的配置参数
protected-mode no : 保护模式,yes开启,no关闭,建议关闭
port 26379 : 监听端口号,默认为26379
daemonize yes : 是否为后台启动, yes后台启动,no在终端运行,建议后台启动
dir /tmp : 哨兵的工作目录,默认为/tmp
pidfile /var/run/redis-sentinel.pid :
输出进程id(pid)的信息路径,默认为/var/run/redis-sentinel.pid
logfile "" : 日志存放路径,默认为空
sentinel monitor mymaster 127.0.0.1 6379 2 :
指定哨兵监控名为mymaster的主节点,ip为127.0.0.1,端口号为6379, 2表示当主节点宕机,至少需要两个哨兵主观认为下线才能进行故障转移
sentinel auth-pass <master-name> <password> :
当主节点设置了密码就需要密码认证,需要输入主机名和密码
sentinel down-after-milliseconds mymaster 30000 :
判断主节点掉线的时间,单位为毫秒,当超过指定的时间则哨兵主观上认为主节点下线,默认间隔时间为30秒
sentinel failover-timeout mymaster 180000 :
故障转移的超时时间,单位毫秒,默认为 180秒
部署哨兵模式
由于哨兵模式是在主从复制基础上进行的改进,因此redis节点服务的部署方式与主从复制一致(从节点在配置文件的REPLICATION项的配置参数中设置主节点信息)
1.准备环境
按主从复制,搭建三个redis节点,端口号分别为6380,6381,6382,其中6380为主节点
2.修改各个节点的哨兵配置文件
vi ./sentinel.conf来编辑配置参数,相关参数修改如下
protected-mode no
port 26380
daemonize yes
pidfile “/opt/shen/redis-test1/redis-master/sentinel/redis-sentinel.pid” 路径需要写绝对路径
logfile "/opt/shen/redis-test1/redis-master/sentinel/sentinel.log"
dir "/opt/shen/redis-test1/redis-master/sentinel"
sentinel monitor mymaster 127.0.0.1 6380 2
sentinel auth-pass mymaster 123456
3.运行哨兵
./src/redis-sentinel ./sentinel.conf
通过哨兵日志查看 tail -400f ./sentinel/sentinel.log
通过redis客户端登陆哨兵端口查看信息
4.模拟故障
通过客户端停掉主节点服务
redis-master]# ./src/redis-cli -p 6380
127.0.0.1:6380> auth 123456
OK
127.0.0.1:6380> shutdown
(0.92s)
not connected>
查看日志可以发现,之前的主节点客观下线,更换端口6382的为主节点,即时之前主节点恢复也会变成从节点
集群模式
集群,即redis cluster,redis3.0正式推出的分布式存储方案,它是
去中心化
的,客户端可以连接任意一个可用节点
采用多主多从(官方建议是至少3个主节点,最好是3主3从六个节点的集群模式),每一个分区都是由一个节点多个从节点组成,节点与节点之间两两交互,共享数据分片(分区),节点状态信息,主节点负责读写请求与集群信息维护,从节点只进行主节点数据与状态信息的复制
集群模式的原理
数据分区
是集群中最核心的功能
redis创建了16384个虚拟哈希槽
(slot),编号(0-16383),集群中每一个主节点负责一部分的哈希槽,每一个key通过CRC16算法校验后对16384取余(%16384)来决定放在那个哈希槽,通过哈希槽值找到对应的节点,跳转到该节点进行数据的存取操作
集群将数据分散到多个节点,一方面突破了redis单机内存大小的限制,存储容量大大增加,另一方面每一个主节点提供读写操作,缓解了之前集群方案的写操作的压力。
高可用(主从切换)
是集群的第二核心功能
当集群只有三个主节点时,当主节点B挂了,那么整个集群会因为缺少编号5461-10922的哈希槽而不可用,当我们为三个主节点提供了从节点后,主节点挂了,从节点会成为主节点提供服务
主从切换流程如下(与哨兵模式类似)
- 从节点发现自己的主节点下线
- 广播FAILOVER_AUTH_REQUEST信息(请求故障转移)
- 其他节点收到消息,只有主节点响应,判断是否真的下线,发送FAILOVER_AUTH_ACK
- 发起故障转移的从节点收集确认信息,超过半数同意则切换为新的主节点
- 广播通知其他节点
集群模式的优缺点
优点:
- 集群完全去中心化,多主多从(客户端不需要关注数据在存储在哪个节点,只关注集合整体)
- 数据通过虚拟哈希槽分布到多个节点,可动态调整数据分布
- 可以线性扩展(官方推荐不超过1000个)
- 高可用,可以进行主从切换
缺点:
- 客户端实现复杂(客户端在本地维护一份slot-node的映射关系,不需要重定向),需要实现smart client
- 数据通过异步复制,不保证数据的强一致性
- 多个业务使用同一套集群,无法根据统计区分冷热数据,资源隔离性较差
集群模式的配置参数
redis-cluster的配置信息包含在redis.conf的REDIS CLUSTER中,以下是常用配置参数
cluster-enabled yes : 是否开启集群模式 yes为开启
cluster-config-file nodes-6379.conf
集群配置信息文件,由redis自行更新,不用手动配置,每一个节点都有对应的集群配置文件,需保证命名不冲突,默认配置文件名为nodes-6379.conf
cluster-node-timeout 15000 :节点互联超时时间,单位毫秒,默认为15秒
cluster-require-full-coverage no : 所有哈希槽都正常才对外提供服务,建议设置为no
cluster-migration-barrier 1 : 主节点的从节点数量大于该值时,从节点才能迁移到其他单个的主节点上
部署集群模式
我这里只部署了三个主节点,建议是三主三从
1.准备环境
搭建三个redis主节点,端口号分别为6379,6380,6381
2.修改redis.conf配置文件
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
cluster-require-full-coverage no
cluster-migration-barrier 1
3.运行redis服务并构建集群
运行三个redis服务
之后通过redis客户端创建(注意此命令是redis5.0之后才支持的)
redis-cli --cluster create 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 --cluster-replicas 0 -a 123456
-a xxx 表示输入密码授权因为我之前设置了密码
redis-cli --cluster 表示群集操作
--cluster create 表示创建集群
--cluster-replicas n 表示一个主节点有n个从节点
如果节点数够多,则主从分配为:假设总共有m个节点数,master节点有m/(1+n)个,则前m/(1+n)个是主节点,其他是从节点,随机分配给主节点
4.运行后的集群状态
5.获取key值需要对应slot编号在对应节点的查找
参考网址
https://blog.csdn.net/weixin_45596022/article/details/113281023
https://blog.csdn.net/weixin_47062656/article/details/123187627