同志,别忘了成长
这一篇给大家介绍一下Redis的高可用方案有哪几种,各自都有什么优缺点,高可用都有哪些问题并且如何解决的,在实际业务中到底如何选择,保证让大家心里有底,脑中有概念
Redis的高可用主要有两种,一种是主从复制,一种是哨兵,一种是集群cluster
主从复制
工作原理:
- Slave从节点服务启动并连接到Master之后,它将主动发送一个SYNC命令。
- Master服务主节点收到同步命令后将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,
- 在后台进程执行完毕后,Master将传送整个数据库文件到Slave,以完成一次完全同步。
- Slave从节点服务在接收到数据库文件数据之后将其存盘并加载到内存中。
- 此后,Master主节点继续将所有已经收集到的修改命令,和新的修改命令依次传送给Slaves
- Slave将在本次执行这些数据修改命令,从而达到最终的数据同步
优点
这种模式都有哪些优点呢
- 同一个Master可以同步多个Slaves
- Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力
- Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求
- Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由Master来完成(读写分离)
- Master可以将数据保存操作交给Slaves完成,从而避免了在Master中要有独立的进程来完成此操作
当然也有缺点
缺点
- Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。
- 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
- Redis的主从复制采用全量复制,复制过程中主机会fork出一个子进程对内存做一份快照,并将子进程的内存快照保存为文件发送给从机,这一过程需要确保主机有足够多的空余内存。若快照文件较大,对集群的服务能力会产生较大的影响,而且复制过程是在从机新加入集群或者从机和主机网络断开重连时都会进行,也就是网络波动都会造成主机和从机间的一次全量的数据复制,这对实际的系统运营造成了不小的麻烦。
- Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费
所以说这种模式虽然简单,但是实际生产中很少使用,因为数据量大的时候或者对高可用要求高时,这种模式不稳定
哨兵模式
Sentinel(哨兵)进程是用于监控redis集群中Master主服务器工作的状态,在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用,架构图如下
Sentinel(哨兵)进程的作用
- 监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。
- 提醒(Notification):当被监控的某个Redis节点出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。
- 自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作,
- 将失效Master下线掉
- 选举其中一个Slave升级为新的Master, 并让其他Slave改为复制新的Master;
- 当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址。
- Master和Slave服务器切换后,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的内容都会发生相应的改变,
- 即:Master主服务器的redis.conf配置文件中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。
如何选举
客户端不会直接从redis中获取信息,而是从sentinel获取信息。
当多个sentinel发现master挂了,会内部选举出一个sentinel作为领导。
被选举出的sentinel领导会选出一个slave作为新的master,同时通知slave复制新的master,通知客户端新的master是谁。
如果老的master复活了,它会变成一个slave去复制新的master
sentinel有哪些定时任务,都有啥用
Redis Sentinel通过三个定时监控任务完成对各个节点发现和监控:
定时任务1
每隔10秒,每个Sentinel节点会向主节点和从节点发送info命令,用以获取最新的拓扑结构图
- 通过向主节点执行info命令,获取从节点信息(这也是为啥Sentinel节点不需要显示配置监控从节点);
- 当有新的从节点加入时,都可以立刻感知;
- 节点不可达或者故障转移后,可以通过Info命令实时更新节点拓扑结构。
定时任务2
sentinel相互之间是有感知的,每2s交换一次信息,作用有两点
- 发现新的Sentinel节点
- Sentinel节点之间交换主节点的状态,可作为后面客观下线以及领导者选举的依据。
定时任务3
每隔1秒,每个Sentinel节点会向主节点、从节点其余Sentinel节点发送一条ping命令做一次心跳检测,来确认这些节点当前是否可达。这个定时任务是节点失败判定的重要依据。
问题来了,那失败了怎么办?
- 如果Redis Sentinel的主节点挂了,Sentinel会自动选举出一个新的主节点,并将其他从节点切换到新的主节点上。
- 如果Sentinel节点之间的网络连接失败,Sentinel会等待一段时间后再次尝试发送ping命令。
- 如果领导者失效,Sentinel会向其他Sentinel节点发送failover命令,检查当前的领导者是否失效。如果领导者失效,Sentinel会开始选举新的领导者 。
- 如果都挂了,那就死翘翘了
优点
- 主从的优点我都有
- 可故障转移,系统可用性好
- 哨兵模式是主从模式的升级,系统更健壮,可用性更高
缺点
- 需要运维有一定经验
- 需要额外服务器
- 配置略微复杂
缺点问题不是很大吧
java中如何配置哨兵模式参考如下
#redis
spring.redis.sentinel.master=mymaster
spring.redis.sentinel.nodes=你的sentinel节点ip:26380,你的sentinel节点ip:26380,你的sentinel节点ip:26380
#spring.redis.host = 127.0.0.1
spring.redis.password = 你的密码
spring.redis.timeout = 5000
spring.redis.database = 1
#连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active = 30
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle = 30
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle = 2
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait = 8000
集群模式(cluster)
从redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。
特点
1、去中心架构(不存在哪个节点影响性能瓶颈),少了 proxy 层。
2、数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。
3、可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。
4、高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本
5、实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave到 Master 的角色提升。
缺点:
1、资源隔离性较差,容易出现相互影响的情况。
2、数据通过异步复制,不保证数据的强一致性
都有哪些问题
扩容命中率降低问题
现有的集群进行取模运算,在扩容时增加服务器导致缓存无法命中,服务器越多命中率越低(假如本来是在1服务器上,扩容后取模后从2获取了,自然获取不到,就会请求到数据库,在扩容后会有大量这种情况,对数据库压力很大)
解决方案1:在半夜人少的时候扩容,负载小对系统影响小;模拟请求逐渐预热
解决方案2:分布式缓存一致性Hash算法
一致性哈希算法使用取模的方法,但是取模算法是对服务器的数量进行取模,而一致性哈希算法是对 2^32 取模,具体步骤如下:
步骤一:一致性哈希算法将整个哈希值空间按照顺时针方向组织成一个虚拟的圆环,称为 Hash 环;
步骤二:接着将各个服务器使用 Hash 函数进行哈希,具体可以选择服务器的IP或主机名作为关键字进行哈希,从而确定每台机器在哈希环上的位置
步骤三:最后使用算法定位数据访问到相应服务器:将数据key使用相同的函数Hash计算出哈希值,并确定此数据在环上的位置,从此位置沿环顺时针寻找,第一台遇到的服务器就是其应该定位到的服务器
这篇文章就介绍到这里了,老司机导航一下其他好文章
Redis过期策略和持久化机制全面揭秘,教你如何合理配置_我是小酒的博客-CSDN博客
【深入浅出Redis 一】从版本特性到数据类型到线程模型,带你了解Redis的核心特性和应用场景!_我是小酒的博客-CSDN博客
关于一致性Hash这篇文章介绍的还不错,大家可以参考下,祝大家好运