缓存击穿、缓存穿透、缓存雪崩是使用Redis的三个经典问题,上篇文章讲了缓存击穿,今天就讲下剩下的两个问题。

一、缓存穿透

定义:缓存穿透是指查询一个根本不存在的数据,缓存层和DB层都不会命中。这样缓存永远不会生效,这些请求最终都会访问数据库。引起DB的压力瞬间变大,导致服务不可用。

问题:试想一个场景,正常来说,某个直播间的相关信息都是会缓存到Redis或者服务器的本地缓存中(提一嘴,我们有些并发量极高的数据是直接缓存在服务器的本地缓存中的,而不是缓存在Redis,因为Redis对于服务器来说是属于第三方组件,连接是耗时的,无论如何也比不过本地缓存。当然服务器本地缓存数据就需要每一台机器都缓存一份数据,就是空间换时间的概念,这个根据实际业务来衡量来采取哪种方案),而此时假设前端有一个异常请求,请求一个不存在的直播ID,那么我们首先会去查缓存,然后缓存没有,我们就会去查DB。好了,问题来了,假设前端伪造了N个这样的请求,那是不是N个请求都要去查DB,那么DB怎么可能扛得住啊。我们之前线上就出现过这样的问题,被恶意攻击了,血泪教训啊。

解决方案

解决缓存穿透问题有几种方案:

1、布隆过滤器。通过在前端部署一个布隆过滤器,可以预先判断该键很可能不存在于数据库中,然后将其拦截,从而避免对数据库发起无效请求。但是这玩意维护成本太高了,对于我们的业务来说,这很明显是还用不上的。感兴趣的同学可以去了解下,这里我就不细讲了。

2、对明显有问题的前端传参进行过滤,比如,假设直播ID是64长度的字符串,那么后端可以对不满足64位的请求直接给过滤掉,不处理。当然,这种小把戏自然是挡不住黑客的,人家搞一堆64位的字符串长度的直播ID不分分钟的事吗

3、设置空缓存,比如,虽然数据库中没有直播ID为“xxxx”的数据,但是在Redis中对其进行缓存(key=xxxx, value=null),这样当请求到达Redis的时候就会直接返回一个null的值给客户端,避免了大量无法访问的数据直接打在DB上。不过得注意,设置这种空缓存的时间不能设置过长,不然有恶意请求的时候,这种空缓存也会引起Redis存储空间暴涨。这个就是我们常用来处理缓存穿透问题的有效方案。 demo样例如下:

	rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "123456",
DB: 0,
}) err := rdb.Set(ctx, "xxxx", "null", 5*60).Err()
if err != nil {
panic(err)
}

二、缓存雪崩

定义:当Redis中的大量key集体过期或失效,这时候如果有大量并发的请求来到,Redis就无法进行有效的响应,所有的查询都落在数据库上,就会出现缓存雪崩。

问题:假设一个场景,我们的直播Redis机器在晚高峰时候出现了宕机,然后进行了重启,那么此时大量的前端请求就会进来,都会去读Redis。但是我重启之后,所以key值都被干掉了啊,那么这时所有的请求查Redis都得不到响应(太惨了),都需要重建缓存。这时候就会触发传说中的缓存雪崩(机器崩,人也差不多崩了)。当然,这是比较极端的一种场景。还有另一种情况就是使用了主动缓存(通过脚本或者定时任务等去生成缓存),然后设置的时间很集中,出现同时过期的时候,也会出现缓存雪崩问题。

解决方案

解决缓存雪崩问题有几种方案:

1、给缓存失效时间设置一些随机值,让缓存尽量的打散,不要集中在一个时间失效。其实大部分业务场景缓存时间都是打散的了,我们只需要使用的时候多留意一下即可。

2、使用Redis集群,当一台宕机之后,还有备用节点,可以将请求打到正常工作的节点中。

总的来说,缓存穿透和缓存雪崩问题带来的最终结果都是灾难性的,但是个人认为这两个在正常业务中,都是比较可控的,除非一些异常场景,例如被恶意攻击等行为。

go高并发之路——缓存穿透、缓存雪崩的更多相关文章

  1. redis的缓存穿透 缓存并发 缓存失效

    我们在用缓存的时候,不管是Redis或者Memcached,基本上会通用遇到以下三个问题: 缓存穿透 缓存并发 缓存失效 一.缓存穿透 Paste_Image.png Paste_Image.png ...

  2. Redis中几个简单的概念:缓存穿透/击穿/雪崩,别再被吓唬了

    Redis中几个“看似”高大上的概念,经常有人提到,某些好事者喜欢死扣概念,实战没多少,嘴巴里冒出来的全是高大上的名词,个人一向鄙视概念党,呵呵! 其实这几个概念:缓存穿透/缓存击穿/缓存雪崩,有一个 ...

  3. Java Redis缓存穿透/缓存雪崩/缓存击穿,Redis分布式锁实现秒杀,限购等

    package com.example.redisdistlock.controller; import com.example.redisdistlock.util.RedisUtil; impor ...

  4. Redis 17 缓存穿透 缓存击穿 缓存雪崩

    参考源 https://www.bilibili.com/video/BV1S54y1R7SB?spm_id_from=333.999.0.0 版本 本文章基于 Redis 6.2.6 使用缓存的问题 ...

  5. 缓存穿透 & 缓存击穿 & 缓存雪崩

    参考文档: 缓存穿透和缓存失效的预防和解决:https://blog.csdn.net/qq_16681169/article/details/75138876 缓存穿透 缓存穿透是指查询一个一定不存 ...

  6. redis缓存穿透,缓存击穿,缓存雪崩

    缓存穿透 缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有.这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询).这样请求就会绕过 ...

  7. 缓存穿透、雪崩、热点与Redis

    (拼多多问:Redis雪崩解决办法) 导读:互联网系统中不可避免要大量用到缓存,在缓存的使用过程中,架构师需要注意哪些问题?本文以 Redis 为例,详细探讨了最关键的 3 个问题. 一.缓存穿透预防 ...

  8. 什么是redis缓存穿透, 缓存雪崩, 缓存击穿

    什么是redis? redis是一个非关系型数据库,相对于其他数据库而言,它的查询速度极快,且能承受的瞬时并发量非常的高.所以常常被用来存放网站的缓存,以减少主要数据库(如mysql)的服务器压力. ...

  9. Redis系列(八)--缓存穿透、雪崩、更新策略

    1.缓存更新策略 1.LRU/LFU/FIFO算法剔除:例如maxmemory-policy 2.超时剔除,过期时间expire,对于一些用户可以容忍延时更新的数据,例如文章简介内容改了几个字 3.主 ...

  10. 缓存穿透 & 缓存雪崩 & 缓存击穿

    一 缓存穿透 1. 行为 查询一个一定不存在的数据.存储层(姑且认为是db,下面都用db指代)查不到数据则不写入缓存,那么下次请求这个不存在的数据同样会到db层查询,失去了缓存的意义.流量大或人为恶意 ...

随机推荐

  1. C++ 编程必备:对象生命周期管理的最佳实践

    在C++中,对象的生命周期是指对象存在的时间段,从对象创建到对象销毁的整个过程.正确地管理对象的生命周期是编写高效.可靠C++代码的关键之一 对象的创建 在C++中,对象可以通过三种方式创建:静态分配 ...

  2. elasticsearch映射创建查询 和Spring Data ElasticSearch入门

    Elasticsearch核心概念 Elasticsearch是面向文档(document oriented)的,这意味着它可以存储整个对象或文档(document).然而它不仅 仅是存储,还会索引( ...

  3. 基于OT与CRDT协同算法的文档划词评论能力实现

    基于OT与CRDT协同算法的文档划词评论能力实现 当我们实现在线文档平台时,划词评论的功能是非常必要的,特别是在重文档管理流程的在线文档产品中,文档反馈是非常重要的一环,这样可以帮助文档维护者提高文档 ...

  4. 树模型-label boosting-GBDT

    GBDT GBDT是boosting系列算法的代表之一,其核心是 梯度+提升+决策树. GBDT回归问题 通俗的理解: 先来个通俗理解:假如有个人30岁,我们首先用20岁去拟合,发现损失有10岁,这时 ...

  5. [Violation] 'click' handler took 429ms

    问题 violation 意思为侵权,违背,违反,也就是说明click函数执行违反了某些规则 原因测试 当click事件中执行的程序耗时过长,超过160ms左右的时候就会显示该信息,测试最低155ms ...

  6. 使用ollama + AnythingLLM快速且简单的在本地部署llm3

    使用ollama + AnythingLLM快速且简单的在本地部署llm3 不多说,直接开始 一.安装ollama ollama官网:https://ollama.com/ 下载地址:https:// ...

  7. ORA-01555:snapshot too old: rollback segment number X with name "XXXX" too small

    ORA-01555:snapshot too old: rollback segment number X with name "XXXX" too small 在查询快照的时候 ...

  8. SysOM 案例解析:消失的内存都去哪了 !| 龙蜥技术

    简介: 这儿有一份"关于内存不足"排查实例,请查收. 文/系统运维 SIG 在<AK47 所向披靡,内存泄漏一网打尽>一文中,我们分享了slab 内存泄漏的排查方式和工 ...

  9. DDD as Code:如何用代码诠释领域驱动设计?

    简介: 相较于常规的MVC架构,DDD更抽象.更难以理解,各个开发者对DDD的解释也不尽相同.那么哪种设计方式才更好?在学习时如何知道哪种DDD更正统,没有被别人带歪?本文尝试使用"DDD ...

  10. CNCF TOC 委员张磊:不断演进的云原生给我们带来了什么?

    简介: 任何一种云原生技术,它不再是某种能力的弥补,而是更多地将云的能力以某种方式更简单.更高效地透出给我的应用去使用.无论是容器.K8s 还是 Service Mesh,他们都是在不同的环节帮助应用 ...