【分布式缓存】

1. 缓存雪崩、缓存击穿与缓存穿透

1.1 缓存雪崩

缓存雪崩是指在缓存中的大量数据同时失效或过期,导致大量的请求直接打到数据库或后端系统,造成系统压力骤增,甚至导致系统崩溃。

原因

  • 缓存服务器宕机: 如果缓存服务器宕机,导致所有缓存失效,会造成大量请求直接打到数据库。
  • 缓存的 key 设置了相同的过期时间: 如果缓存中的大量数据的过期时间设置得太相近,当这些数- 据同时过期时,会导致大量的请求直接落到数据库上。
  • 大量热点数据的过期时间一致: 如果某些热点数据的过期时间设置得一致,一旦这些数据过期,会导致大量请求集中到数据库,造成雪崩效应。
  • 缓存数据量过大: 如果缓存的数据量非常庞大,当缓存同时失效时,会导致大量的请求直接落到数据库上,增加了数据库的压力。
  • 系统并发访问量激增: 当系统的并发访问量激增时,如果缓存中的数据失效过于集中,可能会导致缓存雪崩。

解决方法

  • 设置不同的过期时间: 为不同的缓存数据设置不同的过期时间,避免大量数据同时过期。
  • 使用缓存预热: 在系统启动或者缓存失效前,提前加载热点数据到缓存中,减少缓存雪崩的发生。
  • 使用多级缓存: 将缓存分为多级,如本地缓存、分布式缓存等,提高系统的稳定性和可靠性。
  • 限流降级: 对于并发访问量过大的情况,可以通过限流或者降级等策略,减少对数据库的访问压力。
  • 监控和报警: 设置监控系统,实时监控缓存的状态和访问量,及时发现问题并采取应对措施。
  • 分布式锁(有趣): 在缓存失效时,使用分布式锁来保证只有一个请求去加载数据到缓存中,避免同时有大量请求去访问数据库。

1.2 缓存击穿

一个存在的key,在缓存过期的一刻,同时有大量的请求,这些请求都会击穿到 DB ,造成瞬时DB请求量大、压力骤增。

缓存击穿指的是针对某个特定的key,由于缓存中没有该key的数据,所有的请求都直接落到了后端数据库,这样的请求可能会触发对数据库等存储系统的频繁查询,增加了系统的负载。

解决办法

  • 设置热点数据永不过期: 对于一些热点数据,可以设置其永不过期,这样即使缓存中的其他数据过期,热点数据仍然可以被命中,减少了对数据库的直接访问。
  • 使用互斥锁或分布式锁: 在缓存失效时,使用互斥锁或分布式锁来保证只有一个请求去加载数据到缓存中,避免同时有大量请求去访问数据库。
  • 缓存空对象: 在缓存中设置一个空对象来表示该key对应的数据不存在,这样即使缓存没有命中,也不会直接访问数据库。这种方法可以防止恶意攻击或者非法请求造成的缓存穿透问题。
  • 限流策略: 对于大量请求同时访问的情况,可以采用限流等策略,控制并发访问量,减少对数据库的压力。
  • 提前异步加载数据: 在缓存失效前,提前异步加载数据到缓存中,避免缓存失效时大量请求同时击穿到数据库

1.3 缓存穿透

查询一个不存在的数据,因为不存在则不会写到缓存中,所以每次都会去请求 DB,如果瞬间流量过大,穿透到 DB,导致宕机。

缓存穿透指的是恶意用户发送的请求,这些请求所查询的数据在缓存中不存在,也不会存在于后端数据库中,但是由于缓存无法命中,请求会直接访问数据库,这样的请求可能会导致数据库负载过高,甚至引起数据库宕机。

解决办法

  • 使用布隆过滤器(Bloom Filter): 布隆过滤器是一种高效的数据结构,可以用来快速判断一个元素是否存在于一个集合中。可以在缓存层前使用布隆过滤器,用来过滤掉一些不存在的请求,减少对数据库的直接访问。
  • 缓存空对象: 在缓存中设置一个空对象来表示该key对应的数据不存在,即使查询的数据在数据库中不存在,也可以在缓存中命中空对象,避免对数据库的直接访问。
  • 限制请求频率: 对于频繁查询不存在数据的请求,可以设置限制频率,减少对数据库的访问次数,从而降低数据库的负载。
  • 使用预加载: 在系统启动时或者定期更新时,可以预先加载一些热点数据到缓存中,避免因为热点数据缓存失效而导致的大量请求直接落到数据库。
  • 使用缓存穿透保护策略: 一些缓存系统提供了缓存穿透保护策略,可以通过设置异常数据缓存、黑名单过滤等方式来保护数据库免受缓存穿透的影响。

2. singleflight的实现

通过singleflight可以缓解缓存雪崩、缓存击穿与缓存穿透等现象

import "sync"// call 代表正在进行中,或已经结束的请求。使用 sync.WaitGroup 锁避免重入。
type call struct {wg  sync.WaitGroupval interface{}err error
}// 管理不同 key 的请求(call)
type Group struct {mu sync.Mutex // 保护m这个mapm  map[string]*call
}// 同一时间只有
// m中不存在key的情况下,先锁map,之后新建call,call信号量+1,将call加入到map中,之后解锁map,
// 此时即使再有请求,也会等待map解锁之后再进入map的查询,此时会命中g.m[key],不会请求远端数据库,而是等待返回。等待fn函数获取完之后,call信号量-1.此时并发的请求都能获得返回值
// 删除m中的key
func (g *Group) Do(key string, fn func() (interface{}, error)) (interface{}, error) {g.mu.Lock()if g.m == nil {g.m = make(map[string]*call)}// 如果可以在Group中查询到,代表该请求正在处理中或已经处理结束if c, ok := g.m[key]; ok {g.mu.Unlock()// 等待这个call请求完成c.wg.Wait()return c.val, c.err}// 还没有请求服务器,新建一个callc := new(call)c.wg.Add(1)g.m[key] = cg.mu.Unlock()// 通过fn函数来获取数据库的值c.val, c.err = fn()c.wg.Done() //表示获取完毕// 从map中删除对应的key\g.mu.Lock()delete(g.m, key)g.mu.Unlock()return c.val, c.err
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/806094.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

完全平方数(蓝桥杯,acwing,数论)

题目描述: 一个整数 a 是一个完全平方数,是指它是某一个整数的平方,即存在一个整数 b,使得 ab^2。 给定一个正整数 n,请找到最小的正整数 x,使得它们的乘积是一个完全平方数。 输入格式: 输…

[CUDA 学习笔记] 矩阵转置算子优化

矩阵转置算子优化 矩阵转置是一种基础的矩阵操作, 即将二维矩阵的行列进行反转. 本文主要围绕行主序的二维单精度矩阵的转置考虑相关的优化. 以下 kernel 笔者均是在 NVIDIA V100 (7.0 算力) 上进行测试的, 且选择矩阵的行列维度大小为 M2300 N1500. Version 0. 朴素实现 _…

处理慢查询时使用explain一般看哪些字段

explain之后会出现这些,一般就只看下面这几个字段 select_type就是查询类型,在我司的业务里基本上用的都是简单查询,在内存中处理逻辑,复杂查询的话排查问题比较麻烦,引起慢查询还会拖累数据库,数据库里还…

jvm运行情况预估

相关系统 jvm优化原则-CSDN博客 执行下面指令 jstat gc -pid 能计算出一些关键数据,有了这些数据,先给JVM参数一些的初始的,比堆内存大小、年轻代大小 、Eden和Srivivor的比例,老年代的大小,大对象的阈值,…

前端学习<四>JavaScript基础——05-变量的数据类型:基本数据类型和引用数据类型

数据分类 数据分为:静态数据、动态数据。 静态数据 静态数据是指一些永久性的数据。一般是以文件的形式存储在硬盘上,比如文档、照片、视频等文件。 电脑关闭后,静态数据仍然还在。只要不主动删掉数据或者硬盘没损坏,这些数据…

蓝桥杯c语言

蓝桥杯大赛是中国的一项全国性的IT竞赛,旨在激发大学生和中学生对计算机科学和技术的兴趣,提高他们的编程能力和创新思维。C语言是蓝桥杯大赛中的一个重要竞赛类别,通常包括程序设计、算法解决和数据结构实现等方面的内容。 ### 蓝桥杯C语言…

three.js尝试渲染gbl模型成功!(三)

参照教程:https://cloud.tencent.com/developer/article/2276766?areaSource102001.5&traceId88k805RaN_gYngNdKvALJ (作者:九仞山) 通过最近两天查three.js入门教程了解到 这玩应支持包括 .obj、.gltf等类型的模型结构。 g…

微服务-网关

在微服务架构中,每个服务都是一个可以独立开发和运行的组件,而一个完整的微服务架构由一系列独立运行的微服务组成。其中每个服务都只会完成特定领域的功能,比如订单服务提供与订单业务场景有关的功能、商品服务提供商品展示功能等。各个微服…

2.SpringBoot利用Thymeleaf实现页面的展示

什么是Thymeleaf? Thymeleaf是一个现代服务器端Java模板引擎,适用于Web和独立环境,能够处理HTML,XML,JavaScript,CSS甚至纯文本。 Thymeleaf的主要目标是提供一种优雅且高度可维护的模板创建方式。为实现这…

斐讯E1拆机焊接TTL救砖

从老家的柜子里翻出来一台斐讯E1,老家在用的是斐讯K2P,300M宽带,房间和大部分位置wifi5足够跑满了,一直懒得升级,也足够用了。 不过发现部分位置信号比较弱,都不到50M,考虑插上E1做个AP中继&…

CASL Tutorial Chinese

Attribute-based access control (ABAC) Role-based access control (RBAC) Policy-based access control (PBAC) Claims-based access control (CBAC) 通过研究CASL,设计一款VUE的认证和权限的产品 do - name of the action (e.g., read, update). Has an alia…

106. 跑步锻炼(结果填空)

public class Main { public static void main(String[] args) { int startYear 2000; int startMonth 1; int startDay 1; // 周六 int endYear 2020; int endMonth 10; int endDay 1; // 周四 int totalDistance 0; // 计算开始日期到结束日期之间的每一天 …

【LocalAI】(3):LocalAI本地使用Model gallery,对qwen模型进行配置,使用modescope源下载,本地运行速度快。特别简单!

1,关于localai LocalAI 是一个用于本地推理的,与 OpenAI API 规范兼容的 REST API。 它允许您在本地使用消费级硬件运行 LLM(不仅如此),支持与 ggml 格式兼容的多个模型系列。支持CPU硬件/GPU硬件。 模型启动方法&am…

Spring与SpringBoot的区别

Spring是一个开源的Java应用程序框架,旨在简化企业级Java应用程序的开发。它提供了一个轻量级的容器,用于管理应用程序中的各个组件(如依赖注入、AOP等),并提供了丰富的功能和模块,用于处理数据库访问、事务…

Acwing.4009 收集卡牌(期望dp)

题目 小林在玩一个抽卡游戏,其中有 n种不同的卡牌,编号为 1到 n。 每一次抽卡,她获得第 i种卡牌的概率为 pi。 如果这张卡牌之前已经获得过了,就会转化为一枚硬币。 可以用 k枚硬币交换一张没有获得过的卡。 小林会一直抽卡&…

【ZZULIOJ】1055: 兔子繁殖问题(Java)

目录 题目描述 输入 输出 样例输入 Copy 样例输出 Copy 提示 code 题目描述 这是一个有趣的古典数学问题,著名意大利数学家Fibonacci曾提出一个问题:有一对小兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又…

【2024】elasticsearch的安装及使用建议

为了方便本节将使用docker部署Elasticsearch,以下简称es。 Elasticsearch 1.基础理论部分1.1.简单介绍一下es1.2.es的基本概念和相关术语 2.elasticsearch安装部分3.elasticsearch配置及建议 1.基础理论部分 1.1.简单介绍一下es Elasticsearch是一个开源的、分布…

智能面试——录音及播放下载js-audio-recorder — post请求,formdata传参

录音插件 js-audio-recorder bug&#xff1a;本地调试调取不起来麦克风 浏览器配置安全域名 chrome://flags/Insecure origins treated as secure输入域名即可电脑需要连接上耳机 <template><div class"BaseRecorder"><div class"BaseRecorder-r…

C++递归递推混合

昆虫繁殖 题目描述&#xff1a;科学家在热带森林中发现了一种特殊的昆虫&#xff0c;这种昆虫的繁殖能力很强。每对成虫过x个月 产y对卵&#xff0c;每对卵要过两个月长成成虫。假设每个成虫不死&#xff0c;第一个月只有一对成虫&#xff0c;且卵 长成成虫后的第一个月不产卵…

【UE5 C++】各个头文件的含义

#pragma once 预处理程序指令 作用&#xff1a;保护同一个文件不会被多次包含&#xff0c;使得头文件只会被编译一次&#xff0c; #include “CoreMinimal.h” 包含了一套来自UE4的核心编程环境的普遍存在类型 #include “GameFramework/GameModeBase.h” 基于GameModeBas…