由Redis的hGetAll函数所引发的一次服务宕机事件
昨晚通宵生产压测,终于算是将生产服务宕机的原因定位到了,心累。这篇博客,算作一个复盘和记录吧。。。
先来看看Redis的缓存淘汰算法思维导图:

说明:当实际占用的内存超过Redis配置的maxmemory时,Redis就会根据用户选择淘汰策略清除被选中的key。
业务场景:用户通过微信入口来访问一个页面;
测试场景:通过多线程模拟定量的并发来访问页面服务;
涉及架构:springsession+Redis集群,容器部署;
问题描述:固定并发数压测10分钟,压测开始后半小时,Redis连接数激增,连接耗尽,服务重启;
处理逻辑:
①、用户通过入口页面访问服务时,springsession给每个用户创建一个session,将key存储在Redis中;
②、Redis默认配置每隔半小时,利用hGetAll函数遍历session-key所在的集合,将最近一分钟内要过期的key全部delete,释放内存;
宕机原因:
①、Redis是单线程处理,由于高并发压测,产生了百万级的key存储在set集合中,当hGetAll函数遍历集合删除过期session的key时,大量用户连接失效;
②、失效瞬间,Redis需要创建大量连接,如果新建连接数超过了设置的最大连接数,则Redis服务容器健康检查不通过;
③、通过选举,Redis集群主从切换时需要将master的数据复制到salve;
④、主从复制时,Redis定位区域buffer(软链接)超时,最终导致服务宕机重启。
优化方案:
①、选择Redis默认淘汰策略,每秒钟选择10次,每次不超过25个,即每秒钟淘汰≤250个key;
缺点:内存耗用较高,需要通过横向扩展资源来应对该问题;
②、通过压测确定当前系统配置下的最大可处理阈值,通过网关限流、服务降级等措施来保障服务的稳定运行;
缺点:如果实际流量超过限流配置,则用户可能看到一些“友好界面”,用户体验不太好;
③、新建一个单独工程定期清理过期key,修改工程实例与Redis的消息订阅事件逻辑,降低OPS与client connect,Redis由哨兵改集群模式;
说明:方案③与方案②结合,可大大提高系统的可用性!!!
PS:在实际生产环境中,系统稳定性和可用性胜于一切!!!
相关参考:
以上就是此次问题复盘,虽然通宵带来的后遗症导致现在还有点迷糊,但从中学到了很多新的东西,值得思考与学习。。。
由Redis的hGetAll函数所引发的一次服务宕机事件的更多相关文章
- Redis的KEYS命令引起宕机事件
摘要: 使用 Redis 的开发者必看,吸取教训啊! 原文:Redis 的 KEYS 命令引起 RDS 数据库雪崩,RDS 发生两次宕机,造成几百万的资金损失 作者:陈浩翔 Fundebug经授权转载 ...
- 云计算之路-阿里云上:重启 manager 节点引发 docker swarm 集群宕机
为了迎接春节假期后的访问高峰,我们今天对 docker swarm 集群进行了变更操作,购买了1台阿里云4核8G的服务器作为 worker 节点,由原来的 3 manager nodes + 2 w ...
- 【故障公告】redis 服务器宕机引发博客站点故障
非常抱歉,今天下午 17:10~17:40 左右,由于博客系统所使用的 redis 服务器宕机,造成博客站点无法正常访问,由此给您带来很大的麻烦,请您谅解. 我们会针对这次故障改进 redis 服务器 ...
- Redis 日志篇:无畏宕机快速恢复的杀手锏
特立独行是对的,融入圈子也是对的,重点是要想清楚自己向往怎样的生活,为此愿意付出怎样的代价. 我们通常将 Redis 作为缓存使用,提高读取响应性能,一旦 Redis 宕机,内存中的数据全部丢失,假如 ...
- Redis宕机的问题
在主从模式下宕机要分为区分来看: slave从redis宕机 在Redis中从库重新启动后会自动加入到主从架构中,自动完成同步数据: 如果从数据库实现了持久化,只要重新假如到主从架构中会实现增 ...
- redis集群节点宕机
redis集群是有很多个redis一起工作,那么就需要这个集群不是那么容易挂掉,所以呢,理论上就应该给集群中的每个节点至少一个备用的redis服务.这个备用的redis称为从节点(slave). 1. ...
- redis宕机如何解决?如果是项目上线的宕机呢?
我们先来了解一下 bridge网络模式 他会创建一个docker0桥,看完这个我们就会知道redis哨兵机制的端口了. 之后继续研究redis宕机的解决办法! 宕机: 服务器停止服务 如果只有一台r ...
- 记一次共享内存/dev/shm 小于memory_target 引发的客户DB 宕机问题
1> 记一次共享内存/dev/shm 小于memory_target 引发的客户DB 宕机问题(处理心得)
- [转帖]Redis持久化--Redis宕机或者出现意外删库导致数据丢失--解决方案
Redis持久化--Redis宕机或者出现意外删库导致数据丢失--解决方案 https://www.cnblogs.com/xlecho/p/11834011.html echo编辑整理,欢迎转载,转 ...
随机推荐
- leetcode — remove-duplicates-from-sorted-list-ii
/** * Source : https://oj.leetcode.com/problems/remove-duplicates-from-sorted-list-ii/ * * * Given a ...
- Java开发知识之JavaIO操作缓存操作
目录 带缓存的输入/输出流 一丶简介 二丶BufferedInputStream 与 BufferedOutputString类. 2.BufferOutputStream类. 三丶BufferedR ...
- kernel pwn 入门环境搭建
刚开始上手kernel pwn,光环境就搭了好几天,应该是我太菜了.. 好下面进入正题,环境总共就由两部分构成,qemu和gdb.这两个最好都需要使用源码安装. 我使用的安装环境为 qemu:安装前要 ...
- 解决Mysql错误:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (111)
需要重启服务器:sudo /etc/init.d/mysql restart
- Mysql加锁过程详解(8)-理解innodb的锁(record,gap,Next-Key lock)
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- bisect模块(使用二分法将数据按顺序插入一个列表)
bisect模块功能:使用二分法将数据按顺序插入一个列表 该模块主要有两个函数: 1.insort_right ====>按从小到大顺序将数据插入一个列表 2.bisect_right ...
- Python并发编程之消息队列补充及如何创建线程池(六)
大家好,并发编程 进入第六篇. 在第四章,讲消息通信时,我们学到了Queue消息队列的一些基本使用.昨天我在准备如何创建线程池这一章节的时候,发现对Queue消息队列的讲解有一些遗漏的知识点,而这些知 ...
- C#生成随机数的三种方法
随机数的定义为:产生的所有数字毫无关系. 在实际应用中很多地方会用到随机数,比如需要生成唯一的订单号. 在C#中获取随机数有三种方法: 一.Random 类 Random类默认的无参构造函数可以根据当 ...
- [MySQL] timestamp和datetime的区别和大坑
1.timestamp占用4个字节;datetime占用8个字节2.timestamp范围1970-01-01 00:00:01.000000 到 2038-01-19 03:14:07.999999 ...
- PHP中的__get和__set理解
先来了解一下PHP类中的__get和__set函数 当我们试图获取一个不可达属性时(比如private),类会自动调用__get函数.当试图设置一个不可达属性时(比如private),类会自动调用__ ...