缓存Bigkey坚决不要用,拆分是王道
大家好,我是架构摆渡人。这是实践经验系列的第四篇文章,这个系列会给大家分享很多在实际工作中有用的经验,如果有收获,还请分享给更多的朋友。
背景介绍
在高并发的业务场景中,缓存是必须要上的,用来扛高并发。在某个业务场景中,增加了对一个配置信息的缓存,最开始是直接读取DB的,为了性能考虑在前面加了一层缓存。
加完后很长一段时间也没问题,DB的压力也减小了很多。不幸的是在某天的一个时间点内,流量增加了好几倍,RT直线上升,接口各种超时,就这样,一个线上故障诞生了。
整个过程持续了1分钟左右,监控告警稍微有点延迟,刚看完监控告警,准备介入处理时流量已经跌下来了,接口也恢复了正常。
事后,通过监控发现接口超时的原因是因为底层Redis超时了,说到这可能大家都抱着怀疑的态度,Redis这么快也能超时?是的,你没看错,就是Redis超时了。
而Redis超时的原因并不是说Redis性能不行,而是在同一时刻有大量的请求访问了同一个Key,这个Key缓存的内容很大,导致一瞬间就把网络带宽给占用完了,后续请求都进不来。
解决方案
扩容带宽
直接扩容是最简单有效的方式,如果有持续的高流量造成了影响,紧急扩容是必须要走的,先解决当前问题。
等流量平稳后再考虑代码层面的改造,因为带宽也不是无限的,程序不处理好,始终是个风险点。
拆分BigKey
数据量大了,我们会分库分表。耦合严重了,我们会拆新的模块或者独立的服务。小组人多了,我们会拆分成多个组。遇到BigKey,那就是拆它拆它拆它。
假设这是你的缓存内容,里面是一个很大的Json字符串,存储的是配置信息:
{
"a":"....",
"b":"....",
"c":"...."
.........
}
那么可以把对象中的每个Key再拆分一次,作为一个独立的Key,这样它的Value就小了很多。不同的key会在集群中的不同节点上,也就不会出现集中访问某个节点,带宽不够的场景。

当然我这边说的是String类型,如果你的是List, Set这种,其实原理是一样的,同样是拆分成多个小的List, Key的前缀或者后缀不一样即可。
本地缓存
本地缓存,也是应对热点Key的常用解决方案。大家想想,一个固定的Key存储在Redis中,然后存储的内容也很大,访问量也比较高,带宽很容易成为瓶颈,因为要远程访问获取缓存内容。
如果将缓存存储在本地,那么就可以不用远程访问,从而带宽也就不会成为瓶颈。

如果用了本地缓存,相信很多读者第一想法就是一致性怎么维护,这个无论是在实际应用中还是面试中都是一个高频的问题。
还是得从业务场景触发,用缓存的场景肯定就是没有强一致性的要求,能够容忍短暂的不一致。所以在Redis缓存失效或者数据有变更的时候,本地缓存也需要同步清除。
一般都会采用消息广播的方式进行通知本地缓存失效,因为服务是集群部署的,每个节点上都有一份缓存数据,所以需要广播通知。

BigKey的治理
最后要进行BigKey的治理,梳理出来目前已有的BigKey,根据业务场景进行优化。同时在后续使用缓存的场景对缓存内容严格把关,防止出现类似的问题。
缓存Bigkey坚决不要用,拆分是王道的更多相关文章
- Hibernate缓存集成IMDG
1 第三方缓存插件 除了Ehcache这种轻量级的缓存方案外,几乎所有IMDG产品都提供了对Hibernate二级缓存的直接支持,常用的有: Ø Hazelcast Ø GridGain Ø J ...
- 详解Nacos 配置中心客户端配置缓存动态更新的源码实现
Nacos 作为配置中心,当应用程序去访问Nacos动态获取配置源之后,会缓存到本地内存以及磁盘中. 由于Nacos作为动态配置中心,意味着后续配置变更之后需要让所有相关的客户端感知,并更新本地内存! ...
- iOS企业级开发
2015移动技术白皮书 Android篇 iOS篇 项目管理篇 综合篇 结束语 iOS项目框架设计 项目结构的设计 基类的设计 自定义生命周期 跳转器 自定义UV打点控件 图片缓存 iOS网络底层框架 ...
- iOS WKWebView详解
UIWebView就不用说了,这个过时了,现在iOS8以后建议都使用WKWebView. WKWebView 是现代 WebKit API 在 iOS 8 和 OS X Yosemite 应用中的核心 ...
- [iOS开发]WKWebView加载JS
最近项目要用webView加载js文件,挺同事说WKWebView比UIWebView更加好用,于是我今天就试试,百度一发,自己写了个demo. 先看我写的代码,然后再来看WKWebView跟UIWe ...
- MySQL优化之表结构优化的5大建议(数据类型选择讲的很好)
殊不知,在N年前被奉为"圣经"的数据库设计3范式早就已经不完全适用了.这里我整理了一些比较常见的数据库表结构设计方面的优化技巧,希望对大家有用. 由于MySQL数据库是基于行(Ro ...
- 构建高并发&高可用&安全的IT系统-高并发部分
什么是高并发? 狭义来讲就是你的网站/软件同一时间能承受的用户数量有多少 相关指标有 并发数:对网站/软件同时发起的请求数,一般也可代表实际的用户 每秒响应时间:常指一次请求到系统正确响的时间(以秒为 ...
- Kafka对Java程序员有多重要?连阿里都再用它处理亿万级数据统计
一.了解淘宝Kafka架构 在ActiveMQ.RabbitMQ.RocketMQ.Kafka消息中间件之间,我们为什么要选择Kafka?下面详细介绍一下,2012年9月份我在支付宝做余额宝研发,20 ...
- 连阿里都在用它处理亿万级数据统计,论其对Java程序员的重要性!
一.了解淘宝Kafka架构 在ActiveMQ.RabbitMQ.RocketMQ.Kafka消息中间件之间,我们为什么要选择Kafka?下面详细介绍一下,2012年9月份我在支付宝做余额宝研发,20 ...
随机推荐
- 解决mac电脑耳机/外放突然无声音
问题现象 mac电脑基本不会关机,近期发送隔一段时间出现网易云音乐可以播放但是耳机.外放均无声音的问题.此时,电脑本身的声音提示.远程会议声音均正常. 解决方法 网上搜了一圈解决方案,最后发现是输出设 ...
- Docker Nginx-Proxy 容器Nginx Proxy反向代理
Docker Nginx-Proxy 容器Nginx Proxy反向代理 简单介绍 Docker容器的自动Nginx反向代理 dockerhub地址 https://hub.docker.co ...
- Linux—ps -ef 命令输出信息的具体含义(显示所有正在运行的命令程序)
linux 中使用 ps -ef 输出参数的具体含义 功能:显示所有正在运行的命令程序 UID: 说明该程序被谁拥有PID:就是指该程序的 IDPPID: 就是指该程序父级程序的 IDC: 指的是 C ...
- Oracle-left join两表关联只取B表匹配到的第一条记录【over partition by(分组后对组内数据排序)】
背景: A表.B表两表关联,关联出来的结果里B表有不止一条,需求是只要B表结果中的某一条(按某字段排序) 经过百度,发现 row_number() over(partition by a order ...
- printf 的 转义词 -转
\n 换行 \r 回车键 \b 退后一格 \f 换页 \t 水平制表符 \v 垂直制表符 \a 发出鸣响 \? 插入问号 \" 插入双引号 \' ...
- 搭建简单的SpringCloud项目三:问题及解决
GitHub:https://github.com/ownzyuan/test-cloud 前篇:搭建简单的SpringCloud项目一:注册中心和公共层 搭建简单的SpringCloud项目二:服务 ...
- ssm框架整合 — 更新完毕
1.spring整合mybatis 数据表自行搭建 ,我的结构如下: 1).导入依赖 <!-- spring整合mybatis的依赖 --> <!-- 1.spring需要的依赖 - ...
- [云原生]Docker - 安装&卸载
目录 系统要求 卸载旧版本 安装Docker 方法一:通过repo安装 设置Repository 安装Docker Engine 升级Docker Engine 方法二:通过package安装 方法三 ...
- Go语言核心36讲(Go语言实战与应用二十三)--学习笔记
45 | 使用os包中的API (下) 我们在上一篇文章中.从"os.File类型都实现了哪些io包中的接口"这一问题出发,介绍了一系列的相关内容.今天我们继续围绕这一知识点进行扩 ...
- Maven打包及场景
场景一 对当前项目打包并指定主类. <build> <plugins> <plugin> <artifactId>maven-compiler-plug ...