高可用 Redis 服务架构分析与搭建

  • 时间:
  • 浏览:1

一般情形下,大伙 搭的当事人网站,可能平时做开发时,会起哪哪几个多单实例的Redis Server。调用方直接连接Redis服务即可,甚至Client和Redis一种就处在同一台服务器上。

Redis Sentinel可不后能 理解为哪哪几个多监控Redis Server服务是否是 正常的系统线程池池,你這個你這個一旦检测到不正常,可不后能 自动地将备份(slave)Redis Server启用,使得内部人员用户对Redis服务内部人员再次跳出的异常无感知。大伙 按照由简至繁的步骤,搭建哪哪几个多最小型的高可用的Redis服务。

然而,大伙 实现了Redis Server服务的主从切换时候,又引入了哪哪几个多新的哪些地方的什么的问题,即Redis Sentinel一种也是个单点服务,一旦Sentinel系统线程池池挂了,没能 客户端就没土方法链接Sentinel了。你這個你這個说,方案2的配置并无法实现高可用性。

为了实现高可用,除理方案1中所述的单点故障哪些地方的什么的问题,大伙 还要增加哪哪几个多备份服务,即在两台服务器上分别各启动哪哪几个多Redis Server系统线程池池,一般情形下由master提供服务,slave只负责同步和备份。

易用性:像使用单机版Redis一样使用Redis Sentinel

搭建任何哪哪几个多服务,做到“能用”虽然是非常简单的,就像大伙 运行哪哪几个多单机版的Redis。不过一旦要做到“高可用”,事情就会变得复杂起来。业务中使用了额外的两台服务器,六个Sentinel系统线程池池+哪哪几个多Slave系统线程池池,你這個你這個为了保证在那小概率的事故中依然做到服务可用。在实际业务中大伙 还启用了supervisor做系统线程池池监控,一旦系统线程池池意外退出,会自动尝试重新启动。

当然目前的第三方库一般都可能实现了你這個调用过程,不再还要大伙 手动去实现(累似 Nodejs的ioredis,PHP的predis,Golang的go-redis/redis,JAVA的jedis等)。

不过任何哪哪几个多基础服务的提供方,后会被调用方问起的哪哪几个多哪些地方的什么的问题是:你的服务是否是 具有高可用性?最好无须可能你的服务时不时 出哪些地方的什么的问题,原应我这边的业务跟着遭殃。最近我所在的项目中也当事人搭了一套小型的“高可用”Redis服务,在此做一下当事人的总结和思考。

你要学习Java高架构、分布式架构、高可扩展、高性能、高并发、性能优化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分布式项目实战学习架构师视频免费获取 架构群:835544715

方案3:主从同步Redis Server,双实例Sentinel

结语

首先大伙 要定义一下对于Redis服务来说咋样才是否是 高可用,即在各种再次跳出异常的情形下,依然可不后能 正常提供服务。可能宽松你這個,再次跳出异常的情形下,只经过很短暂的时间即可恢复正常服务。所谓异常,应该共要含晒 了以下几种可能:

【异常3】任意哪哪几个多节点服务器之间的通信中断了(累似 某临时工手残,把用于哪哪几个多机房通信的光缆挖断了)

虽然以上任意一种异常后会小概率事件,而做到高可用性的基本指导思想你這個你這個:多个小概率事件并肩处在的概率可不后能 忽略不计。我希望大伙 设计的系统可不后能 容忍短时间内的单点故障,即可实现高可用性。

在方案4中,一旦服务器1和你這個服务器的通信完全中断,没能 服务器2和3会将slave切换为master。对于客户端来说,在没能 一瞬间会有哪哪几个多master提供服务,你這個你這個一旦网络恢复了,没能 所有在中断期间落在服务器1上的新数据后会丢失。可能你要次责除理你這個哪些地方的什么的问题,可不后能 配置Redis Server系统线程池池,让其在检测到当事人网络哪些地方地方的什么的问题的时候,立即停止服务,除理在网络故障期间还有新数据进来(可不后能 参考Redis的min-slaves-to-write和min-slaves-max-lag这哪哪几个多配置项)。

说到这里,也给大伙 推荐哪哪几个多架构交流学习群:835544715,中间会分享你這個资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化哪些地方地方成为架构师必备的知识体系。还能领取免费的学习资源,相信对于可能工作和遇到技术瓶颈的码友,在你這個群里会都后会你还要的内容。

规模比较大的互联网公司,一般后会有专门的团队,将Redis存储以基础服务的形式提供给各个业务调用。

答案当然是肯定的。这可能就要引入虚拟IP(Virtual IP,VIP),如上图所示。大伙 可不后能 把虚拟IP指向Redis Server master所在的服务器,在处在Redis主从切换的时候,会触发哪哪几个多回调脚本,回调脚本中将VIP切换至slave所在的服务器。你這個你這個对于Client端来说,他仿佛在使用的依然是哪哪几个多单机版的高可用Redis服务。

【异常2】某台节点服务器down掉,共要你這個节点上所有系统线程池池都停了(累似 某运维手残,把哪哪几个多服务器的电源拔了;累似 你這個老旧机器再次跳出硬件故障)

对于搭建高可用Redis服务,网上已有了你這個你這個方案,累似 Keepalived,Codis,Twemproxy,Redis Sentinel。其中Codis和Twemproxy主你這個你這個用于大规模的Redis集群中,也是在Redis官方发布Redis Sentinel时候twitter和豌豆荚提供的开源除理方案。

方案2:主从同步Redis Server,单实例Sentinel

然而,愿景是美好的,现实却是很残酷的。没能 架构下,依然无法实现Redis服务的高可用。方案3示意图中,红线次责是两台服务器之间的通信,而大伙 所设想的异常场景(【异常2】)是,某台服务器整体down机,不妨假设服务器1停机,此时,只剩下服务器2中间的Redis Sentinel和slave Redis Server系统线程池池。

点击链接加入群聊【JAVA高级架构】:https://jq.qq.com/?_wv=1027&k=5dbERkY

作为服务的提供方,大伙 时不时 会讲到用户体验哪些地方的什么的问题。在上述方案当中始终有哪哪几个多让Client端用的后会没能 舒服的地方。对于单机版Redis,Client端直接连接Redis Server,大伙 只还要给哪哪几个多ip和port,Client就可不后能 使用大伙 的服务了。而改造成Sentinel模式时候,Client不得不采用你這個支持Sentinel模式的内部人员依赖包,你這個你這個还要修改当事人的Redis连接配置,这对于“矫情”的用户来讲显然是可不后能 了接收的。有没能 土方法还是像在使用单机版的Redis那样,只给Client哪哪几个多固定的ip和port就可不后能 提供服务呢?

方案4:主从同步Redis Server,三实例Sentinel

为了除理方案2的哪些地方的什么的问题,大伙 把Redis Sentinel系统线程池池也额外启动一份,哪哪几个多Sentinel系统线程池池并肩为客户端提供服务发现的功能。对于客户端来说,它可不后能 连接任何哪哪几个多Redis Sentinel服务,来获取当前Redis Server实例的基本信息。通常情形下,大伙 会在Client端配置多个Redis Sentinel的链接地址,Client一旦发现某个地址连接不上,会去试图连接你這個的Sentinel实例,这当然你這個你這個还要大伙 手动实现,各个开发语言中比较热门的redis连接库都帮大伙 实现了你這個功能。大伙 预期是:即使其中哪哪几个多Redis Sentinel挂掉了,还有另外哪哪几个多Sentinel可不后能 提供服务。

你這個搭配仅适合个学得习娱乐,毕竟你這個配置总会有单点故障的哪些地方的什么的问题无法除理。一旦Redis服务系统线程池池挂了,可能服务器1停机了,没能 服务就不可用了。你這個你這個可能没能 配置Redis数据持久化搞笑的话,Redis内部人员可能存储的数据也会丢失。

对于Redis服务的调用方来说,现在要连接的是Redis Sentinel服务,而后会Redis Server了。常见的调用过程是,client先连接Redis Sentinel并询问目前Redis Server中哪个服务是master,哪些地方是slave,你這個你這個再去连接相应的Redis Server进行操作。

实际上对于服务器2来说,服务器1直接down掉和服务器1网络连不通是一样的效果,反正后会时不时 就无法进行任何通信了。假设网络中断时大伙 允许服务器2的Sentinel把slave切换为master,结果就后会你现在拥有了哪哪几个多可不后能 对外提供服务的Redis Server。Client做任何的增完全操作,有可能落在服务器1的Redis上,后会可能落在服务器2的Redis上(取决于Client到底连通的是哪个Sentinel),造成数据混乱。即使中间服务器1和服务器2之间的网络又恢复了,你這個你這個们也无法把数据统一了(两份不一样的数据,到底该信任谁呢?),数据一致性完全被破坏。

这时,Sentinel虽然是不不将仅剩的slave切再加master继续服务的,也就原应Redis服务不可用,可能Redis的设定是可不后能 了当超过150%的Sentinel系统线程池池可不后能 连通并投票选折 新的master时,才会真正处在主从切换。本例中哪哪几个多Sentinel可不后能 了哪哪几个多可不后能 连通,等于150%无须在可不后能 主从切换的场景中。

至此,大伙 就用3台机器搭建了哪哪几个多高可用的Redis服务。虽然网上还有更加节省机器的土方法,你這個你這個把哪哪几个多Sentinel系统线程池池放进去Client机器上,而后会服务提供方的机器上。只不过在公司中间,一般服务的提供方和调用方无须来自同哪哪几个多团队。哪哪几个多团队并肩操作同哪哪几个多机器,很容易可能沟通哪些地方的什么的问题原应你這個误操作,你這個你這個出于你這個个为因素的考虑,大伙 还是采用了方案4的架构。你這個你這個可能服务器3中间只跑了哪哪几个多Sentinel系统线程池池,对服务器资源消耗无须多,还可不后能 用服务器3来跑你這個你這個的服务。

与此并肩,在额外启动哪哪几个多Sentinel系统线程池池,监控哪哪几个多Redis Server实例的可用性,以便在master挂掉的时候,及时把slave提升到master的角色继续提供服务,你這個你這個就实现了Redis Server的高可用。

你可能会问,为哪些地方Redis要有你這個150%的设定?假设大伙 允许小于等于150%的Sentinel连通的场景下里可不后能 进行主从切换。试想一下【异常3】,即服务器1和服务器2之间的网络中断,你這個你這個服务器一种是可不后能 运行的。如下图所示:

我的业务中数据量无须大,你這個你這個搞集群服务反你這個你這個浪费机器了。最终在Keepalived和Redis Sentinel之间做了个选折 ,选折 了官方的除理方案Redis Sentinel。

【异常1】某个节点服务器的某个系统线程池池时不时 down掉(累似 某开发手残,把一台服务器的redis-server系统线程池池kill了)

鉴于方案3并没能 土方法做到高可用,大伙 最终的版本你這個你這個上图所示的方案4了。实际上这你這個你這個大伙 最终搭建的架构。大伙 引入了服务器3,你這個你這個在3中间又搭建起哪哪几个多Redis Sentinel系统线程池池,现在由哪哪几个多Sentinel系统线程池池来管理哪哪几个多Redis Server实例。你這個场景下,不管是单一系统线程池池故障、还是单个机器故障、还是某哪哪几个多机器网络通信故障,都可不后能 继续对外提供Redis服务。

基于内存的Redis应该是目前各种web开发业务中最为常用的key-value数据库了,大伙 时不时 在业务中用其存储用户登陆态(Session存储),加速你這個热数据的查询(相比较mysql而言,下行速率 有数量级的提升),做简单的消息队列(LPUSH和BRPOP)、订阅发布(PUB/SUB)系统等等。

实际上,可能你的机器比较空闲,当然里可不后能 把服务器3中间也开启哪哪几个多Redis Server,形成1 master + 2 slave的架构,每个数据后会哪哪几个多备份,可用性会提升你這個。当然也并后会slave太久越好,毕竟主从同步也是还要时间成本的。

方案1:单机版Redis Server,无Sentinel

这基于哪哪几个多高可用服务设计的土方法,即单点故障一种你這個这哪哪几个小概率事件,而多个单点并肩故障(即master和slave并肩挂掉),可不后能 认为是(基本)可能处在的事件。