Redis相关的那些事(一)

news/2024/6/1 21:04:28 标签: redis, spring, mybatis

背景

目前工作所负责的工作主要是投放业务,属于读高并发场景,记录一下之前碰到的redis相关的问题。

热点大值Key&缓存击穿问题

问题表现

在某次流量峰值过程中,redis的CPU突然飙升,从监控看起来就是CPU飙升到一定程度,内存突然掉0,然后命中率掉0(实际上是主节点被打挂了,触发了主备切换)。流量和系统调用链路逻辑跟之前并无区别。

原因分析

先看一下计划发布流程和投放端读取计划配置的逻辑:
计划配置发布更新流程
具体逻辑:

  1. 配置端会生成一个全局的索引index_key,来存放坑位和所关联投放计划的关系(注意这里是一个大值key);
  2. 配置端每次更新完全局索引后,会在redis刷新一个全局的时间戳time_key,记录索引的最后更新时间;
  3. 投放端请求进来后,获取redis时间戳缓存(这里是一个热点key),会判断本地索引时间戳缓存是否和redis的时间戳一致,若时间戳不一致,会刷新本地全局index缓存,刷新成功后会刷新本地时间戳缓存;

好处:

  1. 只要时间戳更新,投放端就会获取最新的索引版本,能保证索引发布后,所有对于所有机器来说就马上生效;

弊端

  1. 时间戳redis值本来就是个热点key,投放端每次请求都会打到redis
  2. 全局索引会是大值key,当QPS很高的时候,每次发布新的索引之后,所有机器会同时触发刷新,若集群的机器数量很多的时候,瞬间会打到同一个redis分片

上面所说的问题就是由于在流量峰值期间,有运营发布了新计划,导致全局索引刷新,瞬间1000+qps打到同一个redis分片获取全局索引,导致分片被打崩。

解决办法:

  1. 最简单的解决办法就是把全局索引复制多个备份,key值加入后缀,使value分布到redis集群的每个分片中。比如复制20个备份,index_key_{random},投放端机器随机访问0-20后缀的全局索引分片,解决热点问题;
    弊端:需要保持多个备份的一致性,可能会存在一致性问题;
  2. 把全局索引根据业务划分为更小的颗粒度。比如在这个场景,可以把全局索引改为资源位-计划的索引,减少value的值大小,而且根据资源位进行索引后,value的分布也自然就打散了;
  3. 使用压缩工具,减少value的值。因为存放的value为json格式,json格式其实是有很大的压缩空间,使用压缩工具能够大大减少value的值;
  4. 增加时间戳本地缓存过期时间,使更新本地索引的请求不会同时触发,通过减少并发量解决问题。
    弊端:会导致计划发布之后,投放端会有延迟更新,因为本地缓存时间的存在,所以并不会马上去校验索引是否更新。
    增加本地缓存过期时间

总结

总结一下,解决热点大值key基本就几个思路:

  1. 通过预热的方式,把热点key打散,把压力分散到整个集群;
  2. 通过减小value的size,压缩、修改缓存颗粒度;
  3. 引入缓存过期时间对峰值尖刺进行削峰,减少并发量;

http://www.niftyadmin.cn/n/5284918.html

相关文章

[EFI]Gigabyte-Z790-Aorus-Elite-AX-13700K电脑 Hackintosh 黑苹果efi引导文件

硬件型号驱动情况主板 Gigabyte Z790 Aorus Elite ax DDR5 处理器I7 13700K已驱动内存8GB DDR3 (or something like that)已驱动硬盘WDC PC SN730 SDBQNTY-256G-1001已驱动显卡Gigabyte RX6600 EAGLE 8G已驱动声卡Realtek ALC285已驱动网卡 LucyRTL8125Ethernet 已驱动无线网卡…

python 解决手机拍的书籍图片发灰的问题

老师给发的作业经常是手机拍的,而不是扫描,背景发灰,如果二次打印就没有看了,象这样: 如果使用photoshop 处理,有些地方还是扣不干净,不如python 做的好,处理后如下: 具体…

Updating -- Linux小知识

没想到,10几年后又开始重拾这些曾经学习和使用过的知识,也许一切都是轮回,还好能捡起来。 1. 常用命令(参考 Linux 命令大全 | 菜鸟教程) #命令说明样例1whoami当前用户ID 2id当前用户ID 和 用户组IDid -un # 用户名 id -gn # 用户组…

深度学习中的Dropout

1 Dropout概述 1.1 什么是Dropout 在2012年,Hinton在其论文《Improving neural networks by preventing co-adaptation of feature detectors》中提出Dropout。当一个复杂的前馈神经网络被训练在小的数据集时,容易造成过拟合。为了防止过拟合&#xff…

NET中使用Identity+CodeFirst+Jwt实现登录、鉴权

目录 前言 一、创建上下文类 1.自定义MyContext上下文类继承IdentityDbContext 2.在Program中添加AddDbContext服务 二、使用Migration数据迁移 1.在控制台中 依次使用add-migration 、updatebase 命令 2.如何修改表名 3.如何自定义字段 三、使用Identity实现登录、修改密码 …

C#编程简单应用程序批量修改文件名

用C#编写的程序,可以将所在文件夹内的Photo1.png~Photo10.png十个文件,按照指定的顺序改名为不同的.jpg文件: 【程序代码如下】 using System; using System.IO;class Program {static void Main(string[] args){string folderPath "…

设计模式 建造者模式 与 Spring Bean建造者 BeanDefinitionBuilder 源码与应用

建造者模式 定义: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示主要作用: 在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象如何使用: 用户只需要给出指定复杂对象的类型和内容, 建造者模式负责按顺序创建复杂对象…

【Docker容器精解篇 】深入探索Docker技术的概念与容器思想

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《docker容器精解篇》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言一、Docker 的介绍1.1 Docker 的由来1.1.1 环境不一致1.1.2 隔离性1.1.3 弹性伸缩1.1.4 学习成本 1.2 Doc…