redis客户端实现高可用读写分离的方式详解


Posted in Redis onJuly 04, 2021

背景

(1) redis单机的读写性能轻松上大几万,不过线上环境不会只部署光秃秃的一个节点,还是会配合 sentinel 再部署一个 slave作为高可用节点的;
但是standby的slave节点是不对外提供服务端的,一定程度上造成了浪费资源

(2) 当业务不断发展,原来单节点缓存的数据(如,商品信息缓存、配置信息等)的查询qps不断升高(写qps增长不多),突破十几万、几十万的的时候,此时一个节点就扛不住了,我们就需要增加几个redis slaves节点来分担这些查询的压力 也就是读写分离

但是,常用的 redis 客户端jedis并不支持读写分离能力

实现方式

(1) 从配置中心获取 master 和 slaves 的连接信息,分别初始化好一个连接master的写连接池和一组slave的读连接池
(2) 将命令进行分类:执行写命令则从 master的连接池取连接然后执行,如果是读命令则从slave的连接池中取出连接执行
可能有多个slave节点,可以按照一定的策略进行负载均衡(权重、随机、轮询...etc) 从其中一个 slave节点的连接池获取连接

大概长这样:

redis客户端实现高可用读写分离的方式详解

高可用版本

前面的实现方式正常情况下是可以的

但是:
(1) 如果运行期间 master挂了怎么办? 如何自动 failover 切换?
(2) 如果流量突增,需要动态扩容一个或多个 slave节点,如何动态生效?

那就不能从配置文件取master和slaves的 ip+port 了,得从redis ha的组件去动态获取 当前master 和可用slave列表的节点信息 => sentinel

1.初始化

向 sentinel 发送命令获取master和slaves的节点信息

//获取当前masterName标识的当前master节点信息,哨兵可监控多个 mater ha,所以要用<masterName>区分
SENTINEL get-master-addr-by-name <masterName>
//获取可用的slaves列表信息
SENTINEL slaves <masterName>

redis客户端实现高可用读写分离的方式详解

拿到连接后,继续用开头的方式去创建连接池就行了

2. 动态failover、扩容

初始化完毕后,在运行期间master节点,和slaves还是可能变化的, 如
(1) master故障、网络分区,sentinel 提升一个slave为新的master
(2) 新增slave节点应对突增流量

我们如何能不重启客户端的情况下,动态切换?

sentinel 在进行master切换、slave变更等操作的时候都会向对应的 channel 发布事件,我们可以基于这些事件感知到相应的变化
参考: https://redis.io/topics/sentinel

2.1 failover切换 master

当 sentinel 进行master failover切换的时候,它会向channel: switch-master 发送通知,我们在客户端订阅这个channel,收到事件后,重新进行初始化的步骤即可

redis客户端实现高可用读写分离的方式详解

2.2 扩容slave

当新的 slave 节点加入, sentinel 感知到则会向channel: +slave 发布事件,我们监听到后,重新获取slaves节点信息重建slaves的连接池就可以了(这边不涉及master的变化)

redis客户端实现高可用读写分离的方式详解

总结

基于 sentienl 获取和动态感知 master、slaves节点信息的变化,我们的读写分离客户端就能具备高可用+动态扩容感知能力了;

到此这篇关于redis客户端实现高可用读写分离的文章就介绍到这了,更多相关redis读写分离内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Redis 相关文章推荐
Redis如何一键部署脚本
Apr 12 Redis
Redis高级数据类型Hyperloglog、Bitmap的使用
May 24 Redis
Redis性能监控的实现
Jul 09 Redis
解析redis hash应用场景和常用命令
Aug 04 Redis
详解Redis在SpringBoot工程中的综合应用
Oct 16 Redis
Redis 中使用 list,streams,pub/sub 几种方式实现消息队列的问题
Mar 16 Redis
Redis高可用集群redis-cluster详解
Mar 20 Redis
基于Redis6.2.6版本部署Redis Cluster集群的问题
Apr 01 Redis
浅谈Redis 中的过期删除策略和内存淘汰机制
Apr 03 Redis
Redis 限流器
May 15 Redis
Redis特殊数据类型Geospatial地理空间
Jun 01 Redis
Redis实现短信验证码登录的示例代码
Jun 14 Redis
使用Redis实现实时排行榜功能
Jul 02 #Redis
redis使用不当导致应用卡死bug的过程解析
Redis主从配置和底层实现原理解析(实战记录)
浅谈Redis中的RDB快照
聊一聊Redis与MySQL双写一致性如何保证
k8s部署redis cluster集群的实现
Jun 24 #Redis
浅析Redis Sentinel 与 Redis Cluster
You might like
一个PHP缓存类代码(附详细说明)
2011/06/09 PHP
解析PHP跨站刷票的实现代码
2013/06/18 PHP
PHP mysqli事务操作常用方法分析
2017/07/22 PHP
PhpStorm的使用教程(本地运行PHP+远程开发+快捷键)
2020/03/26 PHP
javascript的字符串按引用复制和传递,按值来比较介绍与应用
2012/12/28 Javascript
js判断FCKeditor内容是否为空的两种形式
2013/05/14 Javascript
js判断上传文件的类型和大小示例代码
2013/10/18 Javascript
IE8下String的Trim()方法失效的解决方法
2013/11/08 Javascript
JS实现的在线调色板实例(附demo源码下载)
2016/03/01 Javascript
早该知道的7个JavaScript技巧
2016/06/21 Javascript
基于JavaScript实现Tab选项卡切换效果
2016/11/24 Javascript
详解JavaScript中this的指向问题
2017/01/20 Javascript
前端分页功能的实现以及原理(jQuery)
2017/01/22 Javascript
详解vue-cli3多环境打包配置
2019/03/28 Javascript
对TypeScript库进行单元测试的方法
2019/07/18 Javascript
js实现AI五子棋人机大战
2020/05/28 Javascript
微信小程序canvas截取任意形状的实现代码
2020/01/13 Javascript
利用Psyco提升Python运行速度
2014/12/24 Python
Python基于hashlib模块的文件MD5一致性加密验证示例
2018/02/10 Python
Python自然语言处理 NLTK 库用法入门教程【经典】
2018/06/26 Python
Selenium+Python 自动化操控登录界面实例(有简单验证码图片校验)
2019/06/28 Python
Python字典中的值为列表或字典的构造实例
2019/12/16 Python
Django REST framwork的权限验证实例
2020/04/02 Python
浅析Python中字符串的intern机制
2020/10/03 Python
Html5页面点击遮罩层背景关闭遮罩层
2020/11/30 HTML / CSS
向全球直邮输送天然健康产品:iHerb.com
2020/05/03 全球购物
销售自荐信
2013/10/22 职场文书
车间统计员岗位职责
2014/01/05 职场文书
电子信息科学专业自荐信
2014/01/30 职场文书
2014年应急管理工作总结
2014/11/26 职场文书
2014年教研组工作总结
2014/11/26 职场文书
市场营销计划书范文
2015/01/16 职场文书
2015年医药代表工作总结
2015/04/25 职场文书
离婚承诺书格式范文
2015/05/04 职场文书
导游词之清晏园
2019/11/22 职场文书
golang定时器
2022/04/14 Golang