缓存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 ...
随机推荐
- JS设计模式之建造者模式
建造者模式(builder pattern)属于创建型模式的一种,提供一种创建复杂对象的方式.它将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 建造者模式是一步一步的创建 ...
- C/C++运行时确定字节顺序
字节顺序(英文:Endianness),多字节数据在内存中的存储顺序: 1.对于特定数据,内存空间有起始地址.结束地址: 2.对于数据本身,存在高位字节.地位字节:例如 int data = 0x01 ...
- xmake v2.6.1 发布,使用 Lua5.4 运行时,Rust 和 C++ 混合编译支持
xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能 ...
- acclaim
欲学acclaim,先学claim.即使学会claim,未必记住acclaim. [LDOCE] claim的词源是cry out, shoutverb:1. state that sth is tr ...
- windows磁盘扩容
要邻近的磁盘,才可以扩展.所以必须要先删除恢复分区. 删除恢复分区,参考如下: https://jingyan.baidu.com/article/574c5219598d5e6c8c9dc15e.h ...
- Java发HTTP POST请求(内容为xml格式)
Java发HTTP POST请求(内容为xml格式) 一.POST请求 服务器地址:http://5.0.217.50:17001/VideoSend 服务器提供的是xml格式的http接口,接口定义 ...
- centos7安装Docker详细步骤(无坑版教程)
一.安装前必读 在安装 Docker 之前,先说一下配置,我这里是Centos7 Linux 内核:官方建议 3.10 以上,3.8以上貌似也可. 注意:本文的命令使用的是 root 用户登录执行,不 ...
- OpenStack之九: 创建一个实例
官网地址 https://docs.openstack.org/install-guide/launch-instance-networks-provider.html #:导入变量 [root@co ...
- SpringMVC(3):AJAX
一,AJAX 简介 AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML) AJAX 不是新的编程语言,而是一种使用现有标准的新方法 ...
- Java对象的创建过程:类的初始化与实例化
一.Java对象创建时机 我们知道,一个对象在可以被使用之前必须要被正确地实例化.在Java代码中,有很多行为可以引起对象的创建,最为直观的一种就是使用new关键字来调用一个类的构造函数显式地创建对象 ...