redis 集群的目的背景:
1、数据丢失问题:我们都知道,内存中的信息会随掉电而丢失,硬盘中的信息可以长久保存。当redis 服务停机之后,redis缓存当中的数据都会丢失,此时redis的 持久化机制,能够让我们在redis 停机或者宕机前做数据的备份,从而在redis 重新启动之后 完成缓存内容的恢复。
2、并发能力问题:单节点 redis 同时被多个请求过来执行读写操作,势必增加redis的性能压力和反应速度,而根据业务场景,如读多写少,那么就可以搭建主从集群,实现读写分离。
3、故障恢复能力: 当集群搭建完成,集群的管理或者高可用的问题的是重点,针对单主多从的场景下,只有主节点具备读写的能力,那么及时的发现尤其是主节点的故障,并且能很快的从 从节点当中提拔出主节点,保证业务不受影响就很关键。 redis 哨兵模式 就实现了这样的功能。
4、存储能力问题: 在单主多从的模式下,主节点的内存分配不宜过大,因为主从要保证数据同步,如果内存过大,那么就意味着数据同步涉及到的数据量过大,每次同步的代价包括性能和时间上消耗过大。 此时搭建分片集群,多主多从的模式,让多个主节点 均分之前单个主节点内存的大小,解决了之前单主节点储存内存不宜过大。
redis持久化
之前的博客当中已经总结过,利用RDB和AOF的机制,实现数据的持久化。
redis主从集群:
单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。
注意
:只有主节点 才具备读写的功能,而从节点只能 读。
数据同步原理
主从集群的特点,就是从节点需要被主节点实现数据同步,数据同步包括了,首次全量同步、过程中的增量同步等,下面给出原理分析。
1、全量同步
总结:上述已经给出全量同步的过程,首次同步 一定是全量同步的,当slave 给master 发出自己的replid 和偏移量offset,此时master 发现你的replid 与master的不一致,既首次同步,那么就会进行上述的全量同步。进行bgsave 生成rdb 并发送给slave。
在bgsave 过程中的和完成全量同步之后的redis内存修改,会通过repl_baklog同步给从节点。
2、增量同步
增量同步的场景是,从节点因为故障需要重启,那么在重启过程中,主节点会有缓存的增减需要同步过来,此时从节点启动之后,同样会把自己的replid 和offset 发送给主节点,因为replid 是master 给过来的,所以要实行增量同步,增量同步就是根据从节点给的offset,让主节点把自己的repl_baklog去掉offset后面的数据,即是需要增量同步的数据。
注意
:特殊情况,是repl_baklog 日志当中已经把从节点的没有同步的内容也给覆盖掉了(repl_baklog是循环写日志的,大小有限,超过大小就会覆盖之前的内容),此时就需要做全量同步。
优化
1、无磁盘复制:在网络环境比较好的情况下,可以把rdb文件的传输替换成把数据直接通过网络给从节点。
2、单节点内存过大,就会导致全量同步 的rdb文件过大。
3、增量同步 变为全量同步就是因为 repl_baklog 的文件太小,导致在从节点宕机的过程中,把从节点未同步的内容覆盖掉了。
4、如果要设置很多从节点,可以让部分从节点成为另外从节点的主节点,减轻master的同步压力。
总结巩固
redis哨兵
首先抛出一个问题
之前讲到了从节点宕机,在重启之后可以找主节点同步,那么如果主节点宕机,虽然它能够根据rdb、aof文件做缓存恢复,但是如果 宕机到重启不及时,客户端无法执行写操作,导致redis 可用性下降。
此时,需要监控节点的状态,监控master的状态,当监测到master,立马选举出新的master,而让旧的master重启之后成为slave ,同时对于集群当中的从节点监测到其宕机也会让其立马重启,就实现了主从切换,保证了集群的高可用性。
1、下图给出了哨兵机制的结构和作用。
2、对节点的监控分为主观下线和客观下线,首先哨兵模式是集群的,其次哨兵中单个节点监测到某个节点下线,可能是因为网络抖动等问题导致,只有当哨兵集群中,一半以上给出主观下线才会认为其真的下线,为客观下线。
3、当给出一个master 客观下线的判断,就会进行新的master的选举,其依据如下
4、选举出新的master之后,要对新旧、以及节点当中的其他从节点发出命令,如下:
总结与巩固
5、RedisTemplate的哨兵模式
(1)首先让RedisTemplate 与哨兵集群建立连接
(2)实现主从分离的配置,设置读的来源是从节点。
注
:写的操作不需要设置,因为只有主节点才有写的功能。
redis分片集群
主从和哨兵 是实现了高可用和高并发的,但是高并发写和大数据量的存储没有解决(大数据量不利于主从复制)。
1、散列插槽
分片集群会把固定的0~16383共16384个插槽,映射到所有的主节点上,例如一共有三个master,那么每个master会被分配大概16384/3个插槽
(1)、根据下面的问题,巩固一下插槽的知识,其中第二个问题,可以根据上图的规则:key中包含"{}",且“{}”中至少包含1个字符,“{}”中的部分是有效部分。
也就是让其的key 设置相同的 有效部分,就能保证这类数据能在一个master 节点上存在。
同时也能说明一个插槽能存储多个值,而不是覆盖关系,如key a和key{a}num 是在同一个插槽,但是不会发生覆盖
2、集群伸缩
(1)添加节点到集群 可以根据上图的方式,分配插槽写出可以手动分配的命令。
3、故障转移
是集群自动实现的该过程
4、数据迁移
发现某个master 性能不太好,想让其他节点替代master的作用。
RedisTemplate访问分片集群
这里的三个步骤,其中 1 和 3 的部分都和哨兵模式相同的设置,就是字配置分片集群的地址,要把集群当中的每一个节点信息都写入。