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 相关文章推荐
为Java项目添加Redis缓存的方法
May 18 Redis
Redis缓存-序列化对象存储乱码问题的解决
Jun 21 Redis
Redis高并发防止秒杀超卖实战源码解决方案
Nov 01 Redis
Redis 哨兵机制及配置实现
Mar 25 Redis
Redis超详细讲解高可用主从复制基础与哨兵模式方案
Apr 07 Redis
Redis中key的过期删除策略和内存淘汰机制
Apr 12 Redis
Redis特殊数据类型Geospatial地理空间
Jun 01 Redis
浅谈Redis缓冲区机制
Jun 05 Redis
Redis实现短信验证码登录的示例代码
Jun 14 Redis
Redis实现分布式锁的五种方法详解
Jun 14 Redis
Redis实现主从复制方式(Master&Slave)
Jun 21 Redis
Redis+AOP+自定义注解实现限流
Jun 28 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大转盘中奖概率算法实例
2014/10/21 PHP
php防止网站被刷新的方法汇总
2014/12/01 PHP
PHP的mysqli_stat()函数讲解
2019/01/23 PHP
JavaScript 基于原型的对象(创建、调用)
2009/10/16 Javascript
基于jquery的气泡提示效果
2010/05/31 Javascript
招聘网站基于jQuery实现自动刷新简历
2015/05/10 Javascript
浅析AMD CMD CommonJS规范--javascript模块化加载学习心得总结
2016/03/16 Javascript
js阻止浏览器默认行为触发的通用方法(推荐)
2016/05/15 Javascript
JS 实现 ajax 异步浏览器兼容问题
2017/01/21 Javascript
Angular directive递归实现目录树结构代码实例
2017/05/05 Javascript
用JS实现简单的登录验证功能
2017/07/28 Javascript
原生JavaScript实现todolist功能
2018/03/02 Javascript
浅谈Koa2框架利用CORS完成跨域ajax请求
2018/03/06 Javascript
javascript实现手动点赞效果
2019/04/09 Javascript
vue.js基于v-for实现批量渲染 Json数组对象列表数据示例
2019/08/03 Javascript
[01:01:18]DOTA2上海特级锦标赛主赛事日 - 2 败者组第二轮#2COL VS LGD
2016/03/03 DOTA
WINDOWS 同时安装 python2 python3 后 pip 错误的解决方法
2017/03/16 Python
python实现装饰器、描述符
2018/02/28 Python
Python操作mongodb的9个步骤
2018/06/04 Python
django云端留言板实例详解
2019/07/22 Python
python多线程并发及测试框架案例
2019/10/15 Python
10个python3常用排序算法详细说明与实例(快速排序,冒泡排序,桶排序,基数排序,堆排序,希尔排序,归并排序,计数排序)
2020/03/17 Python
Python调用Redis的示例代码
2020/11/24 Python
利用python绘制正态分布曲线
2021/01/04 Python
用CSS3实现Win8风格的方格导航菜单效果
2013/04/10 HTML / CSS
大女孩胸罩:Big Girls Bras
2016/12/15 全球购物
个人简历自荐信
2013/12/05 职场文书
护士毕业生自我鉴定
2014/02/08 职场文书
实习护士自荐信
2014/06/21 职场文书
四风问题民主生活会对照检查材料思想汇报
2014/09/27 职场文书
2014年社区工作总结
2014/11/18 职场文书
离婚协议书怎么写的
2014/12/14 职场文书
工程部岗位职责范本
2015/04/11 职场文书
2015年服务员个人工作总结
2015/05/27 职场文书
MySQL 使用索引扫描进行排序
2021/06/20 MySQL
mysql使用FIND_IN_SET和group_concat两个方法查询上下级机构
2022/04/20 MySQL