架构与思维:再聊缓存击穿,面试是一场博弈

架构,思维,再聊,缓存,击穿,面试,一场,博弈 · 浏览次数 : 3003

小编点评

## 缓存击穿和雪崩应对场景分析 **1. 缓存预热** * 可预见情况:在高峰期,缓存失效概率降低,可以使用缓存预热的方式提升性能。 * 缺点:仅能解决可预见问题,对于突发缓存失效情况无效。 **2. 非一致的缓存失效时间** * 当大部分缓存创建于高峰期时,失效时间接近高峰期,容易引起群起创建,导致击穿。 * 解决方案:采用3-4-3分布原则进行缓存创建,降低高峰期失效的概率。 **3. 消息聚合缓存** * 聚合相同用户的信息,可以降低信息修改率,避免频繁更新缓存,提高性能。 * 缺点:仅适用于信息修改率低的缓存,对于频繁修改的信息,聚合不友好。 **4. 削峰、加锁、限流** * 削峰引进消息队列,减少请求数量,提升性能。 * 加锁和限流,防止并发操作对数据库造成冲突,提升性能。 * 这些方法需要考虑性能和可用性,过高的配置可能会降低性能。 **5. 短暂降级** * 当主服务挂了,可选择降级去读备服务,避免数据库被打穿。 * 两种方法都有主备场景,需要根据具体情况选择。 **6. 短暂降级之备选** * 避免大量的请求直接上缓存服务,通过缓存预热等方式提升性能。 * 虽然可能造成部分用户拿不到正确的信息,但避免数据库被大量请求攻击。 **7. 短暂降级之空初始值** * 当缓存失效时,返回空值或默认值,而不是返回数据库中的错误值。 * 确保整个数据库系统不被拥堵的请求击穿。

正文

1 介绍

在之前的一篇文章《一次缓存雪崩的灾难复盘》中,我们比较清晰的描述了缓存雪崩、穿透、击穿的各自特征和解决方案,想详细了解的可以移步。
最近在配合HR筛选候选人,作为大厂的业务方向负责人,招人主要也是我们自己团队在用,而缓存是必不可少的面试选项之一。下面我们就来聊一聊在特定业务场景下缓存击穿和雪崩的应对场景!

2 问题背景

  • 一个核心的应用或者服务(比如微信、钉钉、百度APP),高峰QPS是百万甚至是千万

★ 分析:上述类型的应用具有很明显的峰值 高斯分布的特征,就是9~10点是用户早高峰。微信是,百度APP是,钉钉也是,钉钉一般给政企、教学等使用,通用是10点左右峰值期,每天的峰值如下:
image


  • 应用缓存了用户的基本信息,如(姓名、性别、职业、地址等),假设以为用户Id为Cache的key,那每个用户都有一个基础信息的缓存。
  • 因为不知名的原因,导致缓存都丢了(可能是缓存集体过期、故障导致缓存失效、程序bug导致缓存误删、服务器重启导致内存清理)。
  • 恰巧是访问高峰期(比如9点早高峰),千百万的请求狂奔而来,查不到缓存,透过缓存层直接投入数据库。
  • 基于磁盘的数据库的访问效率,性能,抗击打能力远逊于高速缓存,数据库很容易被打垮,造成服务雪崩。

4 候选人的各种答案(综合整理)

4.1 缓存预热

既然是可预见的峰值期,那么缓存预热是一个好办法,比如在9 ~ 10点是高峰期,在7 ~ 9点这两个小时中,可以均匀的把部分缓存做上。
image

缺点:这种仅仅只能解决可预见的缓存失效情况。如果是突发缓存失效情况,假设在10点高峰期因为某些原因(比如上面说的 故障导致缓存失效、程序bug导致缓存误删、服务器重启导致内存清理)是没有效果的。

4.2 非一致的过期时间

缓存既然大部分是在高峰期(9~10点)创建的(假设Cache的Expire Time都一样,比如8h),那很有可能失效时间会很接近。几乎同一时间一起失效,这样确实也会引起群起创建的情况,也会导致上面说的击穿的情况发生。
我们在创建同一类型的批次缓存的时候,会采用3-4-3 分布原则。比如一个缓存的Expire Time 是 10H,
那么就是3H + 4H * random() + 3h ,来进行错开!
image

缺点:同4.1类似,仅仅解决可预见的问题,对突发故障导致的无预期的缓存失效毫无办法。

4.3 消息聚合缓存

为什么每个用户的基本信息都独立存储一个缓存呢?可不可以按照用户类型分片,一类的用户合在一起不是只要查询一次,不会出现峰值期群起攻击数据库的情况。

说明:只有信息修改率非常低的缓存才适合聚合在一个缓存值中,大部分情况下不会这么做。比如你的缓存中聚合了1W个人的信息,Value非常大,但凡其中一个信息修改,那么这个缓存就要更新,不然应用读取到的信息就没有时效性,大Value的缓存频繁的存取是一个很不友好的事情。
用户信息还算修改频率比较低的,你的积分信息,购物车可是很高频变动的,这种的就不能这么干了。

4.4 削峰、加锁、限流

4.4.1 削峰

引进消息队列之类的中间件,将用户的请求放入队列,逐一执行,避免拥挤请求!

4.4.2 加锁

同一个用户的信息查询只让第一个请求进入,进入之后加锁,在获取到数据库信息并更新缓存之后释放锁,
这样单一个信息只请求一次!

4.4.3 限流

为了避免把服务端打挂,在上线前做一次无缓存压测,看数据库与服务端能支撑的最大值。并设置成限流的阈值,保证不会超过服务所能承载的压力,避免过载!

缺点:

  • 但凡用锁,排队之类的方案,无一例外的会大幅度降低服务的吞吐率,造成用户长时间等待,体验感下降,这在各大型APP(淘宝、微信、百度APP)上是完全不允许的,也不会这么干。
  • 限流也是一样的道理,限流一般是对服务的限流,而难以细粒度到只对某个信息类型的限流。而服务级别限流会误伤其他操作,比如获取排班、排课、获取购物车等非瓶颈的宽松的查询也被限了。当然,现在的限流也可以细粒度到某个或者某几个接口,所以可以将查询用户信息合在一个接口里做一下限流。但是限流也代表部分用户拿不到正确的信息,是一种降级的行为。

备注:数据库也有限流方案,细粒度到这个层级更好

4.5 短暂降级之备选缓存

你的缓存层存在主备场景,他们之间定时异步同步,所以存在短暂数据不一致。
当你的主服务挂了之后,降级去读备服务,数据时效性没那么高,但是也避免了数据库被打穿的情况发生。
image

4.6 短暂降级值客户端缓存(Redis 6.0)

参考Redis 6.0的 Client Side Cache,看我这篇《追求性能极致:客户端缓存带来的革命》。
类似4.5做法,客户端缓存时效性会差一点,毕竟存在订阅跟同步的过程,数据没那么新。但是避免大量的请求直接上缓存服务,又因无效的缓存服务有把压力转移给数据库。
image

4.7 短暂降级之空初始值

这是一种短暂降级的方式,大概流程如下:
image
可以看出,整个过程中我们牺牲了A、B、C、D的请求,他们拿回了一个空值或者默认值,但是这局部的降级却保证整个数据库系统不被拥堵的请求击穿。

5 总结

在不同的场景下各种方法都有各自的优缺点,我们要做的就是根据实际的应用场景来判断和抉择。

与架构与思维:再聊缓存击穿,面试是一场博弈相似的内容:

架构与思维:再聊缓存击穿,面试是一场博弈

1 介绍 在之前的一篇文章《一次缓存雪崩的灾难复盘》中,我们比较清晰的描述了缓存雪崩、穿透、击穿的各自特征和解决方案,想详细了解的可以移步。 最近在配合HR筛选候选人,作为大厂的业务方向负责人,招人主要也是我们自己团队在用,而缓存是必不可少的面试选项之一。下面我们就来聊一聊在特定业务场景下缓存击穿和

架构与思维:秒杀和竞拍的业务架构,永不过时的话题

1 互联网架构越来越复杂? 为啥感觉互联网架构越来越复杂了,早期我们的系统,可能也就那么少部分人使用,大都是一些后台管理系统。 所以不用考虑很多东西,比如: 流量少,无需考虑并发问题 数据少,不用考虑什么索引优化、分库分表 访问不集中,不用考虑缓存、过载保护 如果数据不重要,不用考虑安全策略,甚至不

架构与思维:微服务架构的思想本质

我们为什么需要微服务架构,它一定是为了解决我们某些问题才出现了。这篇文章我们讨论下微服务架构模式所解决的问题,带来的挑战,以及他的核心思想本质。 1 早期的服务架构 上图是一个典型的服务分层架构: Client: 调用方是browser web或者App 应用层: 实现计算层的业务逻辑,从上游数据层

架构与思维:了解Http 和 Https的区别(图文详解)

1 介绍 随着 HTTPS 的不断普及和使用成本的下降,现阶段大部分的系统都已经开始用上 HTTPS 协议。 HTTPS 与 HTTP 相比, 主打的就是安全概念,相关的知识如 SSL 、非对称加密、 CA证书、数据完整性保护 等,我们多多少少也都有听过。 本文重点从原理上讲解 HTTPS 的安全性

架构与思维:4大主流分布式算法介绍(图文并茂、算法拆解)

0 导读 之前的文章中,我们介绍过分布式事务的基础知识,也了解了分布式场景下常见一致性问题和解决方案,对分布式锁和CAS模式有一定的了解,有兴趣的同学可以通过下面链接到作者的两篇相关文章。 五种分布式事务解决方案(图文总结) 高并发下的数据一致性保障(图文全面总结) 1 介绍 本文聚焦高并发场景下分

架构与思维:熔断限流的一些使用场景

1 前言 在《微服务系列》中,我们讲过很多限流,熔断相关的知识。 老生长谈的一个话题,服务的能力终归是有限的,无论是内存、CPU、线程数都是,如果遇到突如其来的峰量请求,我们怎么友好的使用限流来进行落地,避免整个服务集群的雪崩。 峰量请求主要有两种场景: 1.1 突发高峰照成的服务雪崩 如果你的服务

实时数仓构建:Flink+OLAP查询的一些实践与思考

以Flink为主的计算引擎配合OLAP查询分析引擎组合进而构建实时数仓**,其技术方案的选择是我们在技术选型过程中最常见的问题之一。也是很多公司和业务支持过程中会实实在在遇到的问题。 很多人一提起实时数仓,就直接大谈特谈Hudi,Flink的流批一体等,但实际上,**实时数仓包括任何架构体系的构建如...

快速理解DDD领域驱动设计架构思想-基础篇

本文与大家一起学习并介绍领域驱动设计(Domain Drive Design) 简称DDD,以及为什么我们需要领域驱动设计,它有哪些优缺点,尽量用一些通俗易懂文字来描述讲解领域驱动设计

[转帖]浅谈系统稳定性与高可用保障的几种思路

https://segmentfault.com/u/dewujishu 一、前言 高并发、高可用、高性能被称为互联网三高架构,这三者都是工程师和架构师在系统架构设计中必须考虑的因素之一。今天我们就来聊一聊三H中的高可用,也是我们常说的系统稳定性。 本篇文章只聊思路,没有太多的深入细节。阅读全文大概

凭证管理揭秘:Cookie-Session 与 JWT 方案的对决

在软件架构中,关于凭证如何存储和传递,一直有两种不同的解决思路,两种不同的解决方式,实际上反映了两种不同的架构思路