Redis的几种高可用方案部署

一、主从复制

什么是主从复制模式

主从复制模式就是,部署多台redis节点,其中只有一台节点是主节点(master),其他的节点都是从节点(slave),也叫备份节点(replica)。只有master节点提供数据的事务性操作(增删改),slave节点只提供读操作。所有slave节点的数据都是从master节点同步过来的。该模式的架构图如下:

该图只是最简单的一种主从结构方式,所有的slave节点都挂在master节点上,这样做的好处是slave节点与master节点的数据延迟较小;缺点是如果slave节点数量很多,master同步一次数据的耗时就很长。针对这一问题,可以使用下图中的主从架构:

master下面只挂一个slave节点,其他的slave节点挂在这个slave节点下面,这样,master节点每次只需要把数据同步给它下面的那一个slave节点即可,后续slave节点的数据同步由这个slave节点完成。这样做虽然降低了master节点做数据同步的压力,但也导致slave节点与master节点数据不一致的延迟更高。

主从复制模式原理

从主从模式的架构图可以看出,主从模式的核心就是master节点与slave节点之间的数据同步。需要注意的是,Redis和大部分中间件的主从模式中的数据同步都是由slave节点主动发起的,原因是主从模式中只有一个master节点,剩余的全是slave节点,如果由master节点主动推送数据到各个slave节点,首先维护成本太大,master节点上要维护所有slave的地址信息,而且在增加slave节点的时候,也要同步维护到master上,这样master才能将数据同步到所有的slave上面;其次master性能受影响,节点之间同步数据肯定要通过网络传输数据,由master节点建立所有slave节点的连接会对master的性能产生较大影响。而由slave发起数据同步则避免了上述问题,只需在每个slave中维护一个master的地址即可。

Redis中主从节点数据同步有两种方式:全量数据同步和增量数据同步

全量数据同步

全量数据同步一般发生在slave节点初始化阶段,需要将master上的所有数据全部复制过来。全量同步的流程图如下:

  1. slave节点根据配置的master节点信息,连接上master节点,并向master节点发送SYNC命令;

  2. master节点收到SYNC命令后,执行BGSAVE命令异步将内存数据生成到rdb快照文件中,同时将生成rdb文件期间所有的写命令记录到一个缓冲区,保证数据同步的完整性;

  3. master节点的rdb快照文件生成完成后,将该rdb文件发送给slave节点;

  4. slave节点收到rdb快照文件后,丢弃所有内存中的旧数据,并将rdb文件中的数据载入到内存中;

  5. master节点将rdb快照文件发送完毕后,开始将缓冲区中的写命令发送给slave节点;

  6. slave节点完成rdb文件数据的载入后,开始执行接收到的写命令。

以上就是master-slave全量同步的原理,执行完上述动作后,slave节点就可以接受来自用户的读请求,同时,master节点与slave节点进入命令传播阶段,在该阶段master节点会将自己执行的写命令发送给slave节点,slave节点接受并执行写命令,从而保证master节点与slave节点的数据一致性。

增量数据同步

Redis2.8版本之前,是不支持增量数据同步的,只支持全量同步。增量数据同步是指slave节点初始化完成后,master节点执行的写命令同步到slave节点的过程。该过程比较简单,master节点每执行一个写命令后就会将该命令发送给slave节点执行,从而达到数据同步的目的。

但有一点需要注意,当增量复制过程中发生了异常导致同步失败时,是要支持断点续传的,也就是在异常恢复之后,是要支持从上次断掉的地方继续同步的,而不是全量数据同步。这就需要在master节点和slave节点分别维护一个复制偏移量(offset),代表master向slave节点同步的字节数。master节点每次向slave节点发送N个字节后,master节点的offset增加N;slave节点每次接收到master节点发送过来的N个字节后,slave节点的offset增加N。master节点和slave节点的这两个偏移量分别保存在master_repl_offset和slave_repl_offset这两个字段中。

谋朝篡位

slaveof no one

 

主机断开后,从机如果想要当主机,可以使用 slaveof no one 进行“谋朝篡位”,从而变成主机。

但此时其他节点还是很“忠心”,依然认定之前的主机为主机,这样变成的主机是没有从机的,是个“孤家寡人”。

主机如果恢复,可以“平息叛乱”,之前的从机依旧认定它为主机。

改朝换代

 

前面的操作在实际场景中并不适用,因为我们希望的是主机断开后有从机作为主机,依旧实现主从复制。

所以在从机“谋朝篡位”后,还需要让剩余的从机“认主”,让他们都“归顺”于新的主机。

这样原来的主机恢复后就变成了“孤家寡人”。

以上的配置十分繁琐,任何一个环节出错都可能导致失败。

下一章节将介绍更加智能也是工作中常用的哨兵模式

二、哨兵模式

概述

主从切换技术的操作是:当主机宕机后,需要手动把一台从机切换为主机。

这就需要人工干预,费事费力,还会造成一段时间内服务不可用。

这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式

Redis 从 2.8 开始正式提供了 Sentinel(哨兵) 架构来解决这个问题。

它是“谋朝篡位”的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从机转换为主机。

哨兵模式是一种特殊的模式,首先 Redis 提供了哨兵的命令,哨兵是一个独立的进程,它会独立运行。

Redis sentinel工作原理

在哨兵模式架构中,client端在首次访问Redis服务时,实际上访问的是哨兵(sentinel),sentinel会将自己监控的Redis实例的master节点信息返回给client端,client后续就会直接访问Redis的master节点,并不是每次都从哨兵处获取master节点的信息。

简单来说其原理是哨兵通过发送命令,等待 Redis 服务器响应,从而监控运行的多个 Redis 实例。

 

这里的哨兵有两个作用:

  • 通过发送命令,让 Redis 服务器返回监控其运行状态,包括主机和从机。

  • 当哨兵监测到 master 宕机,会自动将 slave 切换成 master,然后通过发布订阅模式通知其他的从机,修改配置文件,让它们切换主机。

然而一个哨兵进程对 Redis 服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。

各个哨兵之间还会进行监控,这样就形成了多哨兵模式(集群)

 

Redis sentinel是如何进行监控的

要实现Redis节点的监控,sentinel首先要得到所有的Redis节点的信息。sentinel通过在配置文件中配置 sentinel monitor 选项来指定要监控的redis master节点的地址,然后在启动sentinel时,会创建与redis master节点的连接并向master节点发送一个info命令,master节点在收到info命令后,会将自身节点的信息和自己下面所有的slave节点的信息返回给sentinel,sentinel收到反馈后,会与新的slave节点创建连接,接下来就会每隔10秒钟向所有的redis节点发送info命令来获取最新的redis主从结构信息。

有了redis实例的主从信息后,sentinel就会以每秒钟一次的频率向所有redis实例发送一个PING命令,而且如果sentinel是集群部署的话,每个sentinel还会以同样的频率向其他sentinel实例发送PING命令。当redis实例和sentinel实例收到PING命令后,会向sentinel返回一个有效的回复:+PONG 、-LOADING 或者 -MASTERDOWN,若返回其他的回复,或者在指定时间内(sentinel down-after-milliseconds 选项配置)没有回复,那么sentinel认为实例的回复无效。如果实例在 sentinel down-after-milliseconds 时间内未返回过一次有效的回复,那该实例就会被sentinel标记为主观下线(Subjectively Down,简称 SDOWN,指的是单个 sentinel 实例对服务节点做出的下线判断)。

当redis master节点被足够数量(sentinel monitor 选项配置,其中的quorum即为指定的sentinel数量,下面会详细介绍相关参数)的sentinel标记为主观下线后,那么master节点就会被标记为客观下线(Objectively Down,简称 ODOWN,指的是多个 sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断。【一个 sentinel 可以通过向另一个 sentinel 发送 SENTINEL is-master-down-by-addr 命令来询问对方是否认为给定的服务器已下线】)。客观下线条件只适用于主服务器: 对于任何其他类型的 Redis 实例,sentinel 在将它们判断为下线前不需要进行协商, 所以slave服务器或者其他 sentinel 永远不会达到客观下线条件。

当redis master被标记为客观下线时,每个sentinel向其他slave节点发送info命令的频率由之前的10秒钟一次变为1秒钟一次。并且会通过raft算法在sentinel中选出一个leader,由leader节点完成redis的故障转移工作。

哨兵监控总结:

假设主机宕机,哨兵 1 先检测到这个结果,系统并不会马上进行 failover(故障转移) 过程,仅仅是哨兵 1 主观的认为主机不可用,这个现象称为主观下线

当后面的哨兵也检测到主机不可用,并且数量达到一定值时,哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行 failover 操作。

切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从机实现切换主机,这个过程称为客观下线

Redis sentinel选举redis-master的规则

如何从众多slave节点中选出一个作为master节点呢?redis文档中是这样描述sentinel选择新master的规则的:

三、Redis集群

百度安全验证https://baijiahao.baidu.com/s?id=1730440988136689035

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
基于微信小程序的校医务室健康服务系统是一个为校园内师生提供便捷的医疗服务和健康管理的综合平台。该系统采用了当前流行的技术栈,包括SpringBoot作为后端服务框架,微信小程序用于前端用户交互,以及Vue.js用于管理系统的前端开发。 使用的技术详细介绍如下: 1. 微信小程序:作为系统的前端用户界面,微信小程序提供了一种无需下载安装即可使用的应用形态,使得师生能够快速访问健康服务系统。微信小程序具有良好的跨平台性能和用户体验,能够实现扫码即用,非常适合校园环境下的使用场景。 2. SpringBoot:作为后端服务的核心框架,SpringBoot简化了企业级应用的开发流程,提供了自动配置、依赖管理等特性,使得开发人员能够更加专注于业务逻辑的实现。SpringBoot还支持多种数据库连接和事务管理,为系统的稳定性和扩展性提供了保障。 3. Vue.js:在管理系统的前端开发中,Vue.js以其轻量级、高性能和组件化的特点被广泛采用。它能够帮助开发者构建灵活的用户界面,提高开发效率,并通过单文件组件(.vue)的形式组织代码,便于维护和迭代。 4. 服务器和数据库:系统可能使用了如MySQL或MongoDB等数据库来存储医疗数据、用户信息和预约记录等。同时,服务器可能部署在云平台上,如阿里云或腾讯云,确保了服务的高可用性和可扩展性。 5. 其他技术:为了提高系统的性能和安全性,可能还会涉及到诸如Redis缓存、JWT(JSON Web Tokens)身份验证、HTTPS安全通信协议等技术的使用。 功能方面,基于微信小程序的校医务室健康服务系统可能包含以下几个核心功能: 1. 在线咨询:用户可以通过小程序与医生进行实时交流,获取健康咨询服务。 2. 预约挂号:用户可以查看医生的排班信息,并进行在线预约挂号,节省排队时间。 3. 电子病历:用户的就诊历史和医疗信息可以电子化管理,方便查询和持续跟踪健康状况。 4. 健康资讯:系统提供健康相关的新闻、文章和教育资料,帮助用户了解健康知识。 5. 药品信息查询:用户可以查询药品说明、使用方法和库存情况。 6. 个人中心:用户可以管理个人信息,包括健康档案、预约记录和咨询历史等。 综上所述,该系统通过结合微信小程序的便捷性、SpringBoot的强大后端能力以及Vue.js的高效前端开发,为校园内的师生提供了一个全面、高效、便捷的健康服务和管理平台。
Seata的高可用模式是通过TC使用db模式共享全局事务会话信息,使用非file的seata支持的第三方注册中心和配置中心来共享全局配置的方式来实现的。 Seata支持的第三方注册中心有nacos 、eureka、redis、zk、consul、etcd3、sofa、custom,支持的第三方配置中心有nacos 、apollo、zk、consul、etcd3、custom。seata官方主推的应该是nacos(毕竟是一家的),但是由于本人平常使用的注册中心一直是zk,因此首先考虑通过zk作为注册中心来实现高可用模式。 环境准备 zk环境准备 本地已安装zk的可以忽略,如果本地未安装,先在本地安装zk,具体安装自行百度。 PS: 此处如果使用的是远程zk服务器,则本地可以只下载,不安装。 数据库环境准备 1、创建数据库seata 2、执行源码(version1.2.0)script -> server -> db 下面的mysql.sql文件,建立global_table,branch_table,lock_table表。 配置信息导入zk 1、打开本地seata源码(版本1.2.0) 2、编辑script -> config-center -> config.txt文件,修改store.mode=db,修改store.db相关的数据库连接信息,其它默认即可 3、进入script -> config-center ->zk,执行 sh zk-config.sh -h 127.0.0.1 -p 2181 -z /usr/local/zookeeper-3.4.14(-z 后面的参数为你本地zk目录) 上面命令会将config.txt中的配置信息写入zk的/seata节点下。 启动tc-server 1、编辑conf下面的registry.conf文件,修改registry.type=zk,修改config.type=zk,修改registry.zk及config.zk信息,如下: 注意:config的zk配置没有cluster属性。 2、启动server,在本地seata安装目录bin目录下执行./seata-server.sh -m db (此处也可以直接编译本地源码然后启动Server模块下的Server类)。 不出意外的话,启动会报错,错误信息是从zk读取配置的时候反序列化出问题。 错误原因:序列化问题,由于使用seata自带的zk-config.sh脚本向zk写入配置信息的时候,采用的序列化方式相当于String.getBytes(),而框架读取配置的时候使用的是org.101tec包中的Zkclient客户端,反序列化使用的是该包下面的SerializableSerializer序列化类,使用的ObjectOutputStream进行反序列化,和序列化方式不一致。 该问题在1.3.0版本中解决,解决方式是seata支持序列化方式配置,支持自定义序列化方式,同时提供默认序列化实现类DefaultZkSerializer,反序列化实现为new String()。 到此处,1.2.0版本无法进行下去,由于目前1.3.0正式版本还未出,只能拉取最新的开发分支源码,本地编译打包1.3.0-SNAPSHOT版本。 后续版本切为1.3.0-SNAPSHOT(20200701),删除原zk配置信息重新导入1.3版本的config.txt文件信息。 本地源码编译后直接Idea启动Server类。启动成功。 PS:启动日志里面会有一些getConfig失败的报错,这些不用管,这些新的配置参数是1.3版本新增的,由于当前是SNAPSHOT版本,还不完善。 PS: 如果遇到getServerCharset 空指针异常,这个主要是MySQL和MySQL驱动版本不一致引起的,看https://blog.csdn.net/zcs20082015/article/details/107087589 服务启动 配置修改 简单处理,这里不再建新的模块,直接使用zhengcs-seata-storage模块作为演示。 1、修改POM,引入zkclient,修改seata版本 2、修改application.yml,将注册和配置类型改为zk 另外需要注意的是seata.tx-service-group配置参数要和zk导入的配置信息相关参数保持一致,否则会找不到server集群 启动服务 1、引入全局事务 2、启动 测试 基本功能测试 单元测试用例: 手动插入异常 执行用例: 基本功能是没问题的,更详细全面的测试这里就不介绍了,大家自行尝试。 高可用测试 上面的单机版肯定无法满足高可用,tc-server一旦宕掉,整个全局事务会无法进行回滚,同时会在seata库下面的事务表里面留下事务记录(正常处理成功后会被删除)。 seata的高可用是通过多个tc-server实例组成的集群来实现的。 启动多个tc-server实例: 通过-p参数修改启动接口,同时勾选Allow parallel run,开启多个实例。 然后启动客服端服务: 从启动日志可以看出,客户端会同时向所有几点注册TM和RM。 执行测试用例: 那,如果在数据已提交,异常退出之前把对应的tc-server节点停掉,会怎么样呢?答案是:全局事务回滚。大家自行尝试一下。 还有一种情况,如果客户端在执行过程中中断了,会怎么样? 如果客户端是单节点部署,那么: 首先,seata库下面的事务处理表里面有遗留事务处理记录,然后你会发现tc-server端日志里面会持续刷上述日志,tc-server会持续的尝试回滚该事务。最遗憾的是:哪怕客户端服务重启,也不会回滚该事务!!! 不过还好的是,这种情况毕竟是特例,如果客户端服务是集群部署,那么seata是可以正常完成事务回滚的。 结语 从上面的情况来看,起码seata对于简单的分布式事务场景的高可用支撑是没问题的,但是seata毕竟还是一个新框架,在实际的复杂的业务场景下会否出现什么问题,其实应该说出现什么问题都是可能的,这个需要实践和时间才能出真知了。 另外,seata目前没有提供控制台,没有服务集群配套的HA机制,这个不知道什么时候会出,拭目以待,seata应该会是一个很不错的分布式事务解决方案。   参考资料 https://seata.io/zh-cn/docs/ https://github.com/seata/seata ———————————————— 版权声明:本文为CSDN博主「zhengcs已被占用」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/zcs20082015/article/details/107092936

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值