缓存系统稳定性 - 架构师峰会演讲实录

简介: 缓存系统稳定性 - 架构师峰会演讲实录

前言

大家好!我是万俊峰,go-zero 作者。感谢 ArchSummit 提供这么好的机会来跟大家分享一下 go-zero 的缓存最佳实践。

首先,大家可以想一想:我们在流量激增的情况下,服务端哪个部分最有可能会是第一个瓶颈?我相信大部分人遇到的都会是数据库首先扛不住,量一起来,数据库慢查询,甚至卡死。此时,上层服务有怎么强的治理能力都是无济于事的。

所以我们常说看一个系统架构设计的好不好,很多时候看看缓存设计的如何就知道了。我们曾经遇到过这样的问题,在我加入之前,我们的服务是没有缓存的,虽然当时流量还不算高,但是每天到流量高峰时间段,大家就会特别紧张,一周宕机好几回,数据库直接被打死,然后啥也干不了,只能重启;我当时还是顾问,看了看系统设计,只能救急,就让大家先加上了缓存,但是由于大家对缓存的认知不够以及老系统的混乱,每个业务开发人员都会按照自己的方式来手撕缓存。这样导致的问题就是缓存用了,但是数据七零八落,压根没有办法保证数据的一致性。这确实是一个比较痛苦的经历,应该能引起大家的共鸣和回忆。

然后我把整个系统推倒重新设计了,其中缓存部分的架构设计在其中作用非常明显,于是有了今天的分享。

我主要分为以下几个部分跟大家探讨:

  • 缓存系统常见问题
  • 单行查询的缓存与自动管理
  • 多行查询缓存机制
  • 分布式缓存系统设计
  • 缓存代码自动化实践

缓存系统涉及的问题和知识点是比较多的,我分为以下几个方面来讨论:

  • 稳定性
  • 正确性
  • 可观测性
  • 规范落地和工具建设

由于篇幅太长,本文作为系列文章第一篇,主要跟大家探讨『缓存系统稳定性』

缓存系统稳定性

缓存稳定性方面,网上基本所有的缓存相关文章和分享都会讲到三个重点:

  • 缓存穿透
  • 缓存击穿
  • 缓存雪崩

为什么首先讲缓存稳定性呢?大家可以回忆一下,我们何时会引入缓存?一般都是当DB有压力,甚至经常被打挂的情况下才会引入缓存,所以我们首先就是为了解决稳定性的问题而引入缓存系统的。

缓存穿透

缓存穿透存在的原因是请求不存在的数据,从图中我们可以看到对同一个数据的请求1会先去访问缓存,但是因为数据不存在,所以缓存里肯定没有,那么就落到DB去了,对同一个数据的请求2、请求3也同样会透过缓存落到DB去,这样当大量请求不存在的数据时DB压力就会特别大,尤其是可能会恶意请求打垮(不怀好意的人发现一个数据不存在,然后就大量发起对这个不存在数据的请求)。

go-zero 的解决方法是:对于不存在的数据的请求我们也会在缓存里短暂(比如一分钟)存放一个占位符,这样对同一个不存在数据的DB请求数就会跟实际请求数解耦了,当然在业务侧也可以在新增数据时删除该占位符以确保新增数据可以立刻查询到。

缓存击穿

缓存击穿的原因是热点数据的过期,因为是热点数据,所以一旦过期可能就会有大量对该热点数据的请求同时过来,这时如果所有请求在缓存里都找不到数据,如果同时落到DB去的话,那么DB就会瞬间承受巨大的压力,甚至直接卡死。

go-zero 的解决方法是:对于相同的数据我们可以借助于 core/syncx/SharedCalls 来确保同一时间只有一个请求落到DB,对同一个数据的其它请求等待第一个请求返回并共享结果或错误,根据不同的并发场景,我们可以选择使用进程内的锁(并发量不是非常高),或者分布式锁(并发量很高)。如果不是特别需要,我们一般推荐进程内的锁即可,毕竟引入分布式锁会增加复杂度和成本,借鉴奥卡姆剃刀理论:如非必要,勿增实体。

我们来一起看一下上图缓存击穿防护流程,我们用不同颜色表示不同请求:

  • 绿色请求首先到达,发现缓存里没有数据,就去DB查询
  • 粉色请求到达,请求相同数据,发现已有请求在处理中,等待绿色请求返回,singleflight模式
  • 绿色请求返回,粉色请求用绿色请求共享的结果返回
  • 后续请求,比如蓝色请求就可以直接从缓存里获取数据了

缓存雪崩

缓存雪崩的原因是大量同时加载的缓存有相同的过期时间,在过期时间到达的时候出现短时间内大量缓存过期,这样就会让很多请求同时落到DB去,从而使DB压力激增,甚至卡死。

比如疫情下在线教学场景,高中、初中、小学是分几个时间段同时开课的,那么这时就会有大量数据同时加载,并且设置了相同的过期时间,在过期时间到达的时候就会对等出现一个一个的DB请求波峰,这样的压力波峰会传递到下一个周期,甚至出现叠加。

go-zero 的解决方法是:

  • 使用分布式缓存,防止单点故障导致的缓存雪崩
  • 在过期时间上加上5%的标准偏差,5%是假设检验里P值的经验值(有兴趣的读者可以自行查阅)

我们做个实验,如果用1万个数据,过期时间设为1小时,标准偏差设为5%,那么过期时间会比较均匀的分布在3400~3800秒之间。如果我们的默认过期时间是7天,那么就会均匀分布在以7天为中心点的16小时内。这样就可以很好的防止了缓存的雪崩问题。

未完待续

本文跟大家一起讨论了缓存系统的常见稳定性问题,下一篇我来跟大家一起分析缓存的数据一致性问题。

所有这些问题的解决方法都已包含在 go-zero 微服务框架里,如果你想要更好的了解 go-zero 项目,欢迎前往官方网站上学习具体的示例。

视频回放地址

ArchSummit架构师峰会-海量并发下的缓存架构设计

项目地址

https://github.com/tal-tech/go-zero

相关文章
|
11天前
【YashanDB 知识库】如何排查 YMP 报错:”OCI 版本为空或 OCI 的架构和本地系统的架构不符“
**问题现象**:迁移预检查时,因OCI版本为空或架构不符报错。通过查看yasdts日志发现缺少libnsl.so.1依赖库。 **排查步骤**: 1. 查看日志确认缺少的依赖库。 2. 检查OCI客户端路径是否已加入LD_LIBRARY_PATH环境变量。 3. 使用`ldd`命令检查其他缺失的依赖库。 **解决方法**: 1. 下载并安装所需的动态库版本。 2. 若无法联网,查找本地是否有相应库。 3. 如本地有高版本库,创建软链接指向所需版本(如`ln -s /lib64/libnsl.so.2 libnsl.so.1`)。
|
12天前
【YashanDB 知识库】如何排查 YMP 报错:”OCI 版本为空或 OCI 的架构和本地系统的架构不符“
在迁移预检查的版本检查阶段报错“OCI 版本为空”,原因是 OCI 架构与本地系统不符或依赖库缺失。排查发现 `libdrv_oracle.so` 缺少 `libnsl.so.1` 库,尽管 OCI 客户端路径已正确加入 `LD_LIBRARY_PATH`。解决方法包括下载安装相应动态库版本,或通过软链接指向更高版本库(如 `libnsl.so.2`)。总结:确保动态库路径正确配置,并使用 `ldd` 查看依赖库,必要时创建软链接以解决问题。
|
23天前
|
安全 NoSQL MongoDB
XJ-Survey:这个让滴滴日均处理1.2亿次问卷请求的开源系统,今天终于公开了它的架构密码!
嗨,大家好,我是小华同学。今天为大家介绍一款由滴滴开源的高效调研系统——XJ-Survey。它功能强大,支持多类型数据采集、智能逻辑编排、精细权限管理和数据在线分析,适用于问卷、考试、测评等场景。采用 Vue3、NestJS 等先进技术栈,确保高性能与安全性。无论是企业还是个人,XJ-Survey 都是你不可错过的神器!项目地址:[https://github.com/didi/xiaoju-survey](https://github.com/didi/xiaoju-survey)
68 15
|
1月前
|
人工智能 JavaScript 安全
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
98 13
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
|
1月前
|
机器学习/深度学习 缓存 自然语言处理
DeepSeek背后的技术基石:DeepSeekMoE基于专家混合系统的大规模语言模型架构
DeepSeekMoE是一种创新的大规模语言模型架构,融合了专家混合系统(MoE)、多头潜在注意力机制(MLA)和RMSNorm归一化。通过专家共享、动态路由和潜在变量缓存技术,DeepSeekMoE在保持性能的同时,将计算开销降低了40%,显著提升了训练和推理效率。该模型在语言建模、机器翻译和长文本处理等任务中表现出色,具备广泛的应用前景,特别是在计算资源受限的场景下。
518 29
DeepSeek背后的技术基石:DeepSeekMoE基于专家混合系统的大规模语言模型架构
|
2月前
|
存储 缓存 关系型数据库
社交软件红包技术解密(六):微信红包系统的存储层架构演进实践
微信红包本质是小额资金在用户帐户流转,有发、抢、拆三大步骤。在这个过程中对事务有高要求,所以订单最终要基于传统的RDBMS,这方面是它的强项,最终订单的存储使用互联网行业最通用的MySQL数据库。支持事务、成熟稳定,我们的团队在MySQL上有长期技术积累。但是传统数据库的扩展性有局限,需要通过架构解决。
78 18
|
2月前
|
存储 缓存 NoSQL
分布式系统架构8:分布式缓存
本文介绍了分布式缓存的理论知识及Redis集群的应用,探讨了AP与CP的区别,Redis作为AP系统具备高性能和高可用性但不保证强一致性。文章还讲解了透明多级缓存(TMC)的概念及其优缺点,并详细分析了memcached和Redis的分布式实现方案。此外,针对缓存穿透、击穿、雪崩和污染等常见问题提供了应对策略,强调了Cache Aside模式在解决数据一致性方面的作用。最后指出,面试中关于缓存的问题多围绕Redis展开,建议深入学习相关知识点。
216 8
|
2月前
|
存储 缓存 安全
分布式系统架构7:本地缓存
这是小卷关于分布式系统架构学习的第10篇文章,主要介绍本地缓存的基础理论。文章分析了引入缓存的利弊,解释了缓存对CPU和I/O压力的缓解作用,并讨论了缓存的吞吐量、命中率、淘汰策略等属性。同时,对比了几种常见的本地缓存工具(如ConcurrentHashMap、Ehcache、Guava Cache和Caffeine),详细介绍了它们的访问控制、淘汰策略及扩展功能。
89 6
|
2月前
|
SQL 弹性计算 运维
云卓越架构:稳定性支柱整体解决方案综述
阿里云卓越架构聚焦于五大支柱,其中稳定性是关键。常见的云上稳定性风险包括架构单点、容灾设计不足和容量规划不合理等。为提升稳定性,需从架构设计时考虑容灾与容错、实施变更时遵循“三板斧”原则(灰度发布、可观测性和可回滚性),并确保快速响应和恢复能力。此外,通过客观度量、主观评估和巡检等方式识别风险,并进行专项治理。识货APP作为成功案例,通过优化容器化改造、统一发布体系、告警系统和扩缩容机制,实现了99.8%的高可用率,大幅提升了业务稳定性。
|
2月前
|
容灾 网络协议 数据库
云卓越架构:云上网络稳定性建设和应用稳定性治理最佳实践
本文介绍了云上网络稳定性体系建设的关键内容,包括面向失败的架构设计、可观测性与应急恢复、客户案例及阿里巴巴的核心电商架构演进。首先强调了网络稳定性的挑战及其应对策略,如责任共担模型和冗余设计。接着详细探讨了多可用区部署、弹性架构规划及跨地域容灾设计的最佳实践,特别是阿里云的产品和技术如何助力实现高可用性和快速故障恢复。最后通过具体案例展示了秒级故障转移的效果,以及同城多活架构下的实际应用。这些措施共同确保了业务在面对网络故障时的持续稳定运行。

热门文章

最新文章