架构学习笔记——缓存篇

架构篇17:高性能缓存架构 本篇我们来分析下缓存的架构设计要点。 阅读详情

服务器缓存,是由计算机硬件系统中的缓存扩展而来,是一种大幅度提高读取速度的机制。在架构设计实践中,缓存往往用于在高并发场景下缓解数据库压力。


目录


1.缓存的应用场景

类似于硬件系统中的缓存,应用架构中的缓存的作用同样是加速读的速度。此外,缓存系统往往独立于数据库,因此缓存与数据库中的数据在到达下一个同步时间节点前,两者的数据可能会产生不一致的情况。综上两点,缓存的应用场景主要是以下两点:

  • 系统的读请求数量远大于写请求数量
  • 系统对实时数据一致性的要求不是非常高

2.缓存系统设计模式及其问题

根据不同缓存系统在设计时,面对读请求和写请求不同的数据访问、更新操作次序,分为三种模式:

  • Cache Aside Pattern
  • Read/Write Through Pattern
  • Write Behind Caching

2.1 Cache Aside Pattern

Cache Aside Pattern,即缓存旁路模式,是最常用的缓存设计模式。

2.1.1 Cache Aside Read

缓存旁路模式的读请求按照命中与否分为两种,如下图:

  • 缓存命中:直接从缓存中读取数据并返回
  • 缓存失效:从数据库中读取数据,放到缓存中并返回
Created with Raphaël 2.1.2 读请求 缓存命中 从缓存读 响应 从数据库读 写入缓存 yes no
2.1.2 Cache Aside Write

缓存旁路模式的写请求,是先更新数据库,再淘汰缓存,如下图:

Created with Raphaël 2.1.2 写请求 更新数据库 淘汰缓存 结束(或返回ACK)
2.1.3 缓存淘汰与更新的取舍

在缓存旁路模式的写请求中,进行的操作是淘汰缓存,那么为什么不是更新缓存呢?考虑并发写场景,如果是更新缓存的话,可能会发生以下情况:

Created with Raphaël 2.1.2 调用方 调用方 服务 服务 数据库 数据库 缓存 缓存 write_req A write_req B A.update_db B.update_db B.update_cache A.update_cache

两个写请求A和B并发执行,在更新数据库时,先执行了A更新后B更新,此时数据库内的数据为B更新后的结果;在更新缓存时,先执行了B更新,后执行了A更新,此时缓存内的数据为A更新后的结果,与数据库内的数据发生不一致。发生这个问题后,在一段时间内(缓存过期,或是下一个写请求到来),调用方获取到的数据全都是脏数据。

2.1.4 先淘汰缓存再更新数据库的问题

如果将缓存旁路模式的写请求的顺序交换,变成先淘汰缓存,再更新数据库会发生什么问题呢?考虑并发读写场景,先淘汰缓存再更新数据库,可能会发生以下情况:

Created with Raphaël 2.1.2 调用方 调用方 服务 服务 缓存 缓存 数据库 数据库 write_req A read_req B A.evict_cache B.read_cache(failed) B.read_db A.update_db B.write_cache

两个请求:写请求A和读请求B并发执行。写请求A先淘汰缓存,随后读请求B访问缓存必然读不到数据,需要从数据库读取数据。随后,读请求B先于写请求A从数据库中读到数据,并将数据放入缓存中,随后写请求B更新了数据库。此时,缓存中为写请求A更新前的数据,而数据库中是写请求A更新后的数据,两者发生数据不一致问题。同样的,在一段时间内,调用方获取到的数据全都是脏数据。

2.1.5 读写并发数据不一致

同样是并发读写的情况,缓存旁路模式似乎也会存在数据不一致问题:

Created with Raphaël 2.1.2 调用方 调用方 服务 服务 缓存 缓存 数据库 数据库 write_req A read_req B B.read_cache(failed) B.read_db A.update_db A.evict_cache B.write_cache

发生了数据不一致的问题,缓存里是读请求B从数据库中读到并写入的旧数据,数据库中是写请求A更新后的数据。

对于数据库而言,读请求(select操作)相较于写请求(update)快得多;在上述案例中,读请求必须先于写请求从数据库中读到数据,再晚于写请求淘汰缓存,同时发生的概率很低。可以通过设置一个较小的缓存过期时间,或是使用数据库日志订阅工具订阅binlog实现延时淘汰缓存,来减少会从缓存中读到脏数据的时间。

2.2 Read/Write Through Pattern

Read/Write Through Pattern,即读/写穿透模式。在读/写穿透模式中,缓存具有更多的“自主权”,服务仅从缓存中取数据而不访问数据库,由缓存自己负责更新、淘汰数据以维持数据一致性。

2.2.1 Read Through

读穿透按照命中与否分为两种,如下图:

  • 缓存命中:直接从缓存中读取数据并返回
  • 缓存失效:通知缓存从数据库取数据更新缓存,再从缓存中读取
Created with Raphaël 2.1.2 读请求 缓存命中 从缓存读 响应 缓存读数据库 开辟缓存块存数据 从缓存读 响应 yes no
2.2.2 Write Through

写穿透类似于读穿透,同样分为缓存命中和缓存失效两种情况,如下图:

  • 缓存命中:直接更新缓存,由缓存负责更新数据库
  • 缓存失效:直接更新数据库
Created with Raphaël 2.1.2 写请求 缓存命中 更新缓存 同步到数据库 结束(或返回ACK) 更新数据库 yes no

2.3 Write Behind Caching Pattern

Write Behind Caching Pattern,类似于linux内核中页缓存的write back机制,是由缓存保持数据,并批量异步更新到数据库中的模式。这种设计模式在设计上缓存与数据库在大部分时间都是不一致的,但是所有的请求只读缓存,所以对服务整体而言不会读到脏数据。

2.3.1Read
Created with Raphaël 2.1.2 读请求 缓存命中 响应 开辟缓存块 从数据库读 写入缓存块 响应 yes no
2.3.2 Write

写请求与读请求类似,同样要根据命中缓存与否开辟新的缓存块:

Created with Raphaël 2.1.2 写请求 缓存命中 更新缓存 结束(或返回ACK) 开辟缓存块 写入缓存 yes no
2.3.3 开辟缓存块

在开辟缓存块时,考虑到存在这种情况:缓存的空间已被用尽,需要淘汰掉部分缓存来缓存新的数据(如redis使用的是LRU算法)。此时,需要考虑被淘汰的数据是否已经在数据库中存在,需要进行一次判定:

Created with Raphaël 2.1.2 开辟缓存块 缓存块为空 开辟完成 原数据更新到数据库 yes no

3. 缓存系统常见问题

3.1 缓存穿透

缓存穿透是指,某一个本不存在的key被高并发访问,导致服务不断访问数据库,但由于返回空结果集而不放入到缓存中,使得缓存失去意义。

  • 缓存空对象:即服务器返回空结果集时依然放入缓存中,设置值为空标识符(可以是null(如果允许)、空字符串、空对象、空集合等)
  • 黑名单:使用黑名单机制过滤不存在的key,使得不存在的key直接被挡在服务外

3.2 并发缓存失效读请求

在服务并发较高的时候,如果一个key在失效以后被多次并发访问,会发生在数据库上出现一个高并发读的情况,如下图:

Created with Raphaël 2.1.2 调用方 调用方 服务 服务 缓存 缓存 数据库 数据库 read_req A A.read_cache(failed) A.read_db read_req B B.read_cache(failed) B.read_db read_req ... A.write_cache

可见,在第一个到达的读请求从数据库中读到数据并放入缓存之前,期间所有的读请求全部都会访问数据库获取数据,一方面使得数据库的压力陡然增加,另一方面大量消耗了服务的性能,使得服务对其他读请求的执行效率降低。

解决这一问题的主要方法是,缓存查询操作上锁,将后到的相同读请求阻塞,直到第一个读请求将数据库中的数据更新到缓存中,如下图:

Created with Raphaël 2.1.2 调用方 调用方 服务 服务 缓存 缓存 数据库 数据库 read_req A A.read_cache(failed) A.read_db read_req B locked read_req ... locked A.write_cache B.read_cache(succeeded) ....read_cache(succeeded)

锁虽然阻塞了后续一段时间内所有的读请求,但时间上总的时间并没有发生变化,因为后续所有的读请求都成功访问了缓存,可以直接从缓存中读取数据返回。

3.3 缓存雪崩

缓存雪崩是指很多key在同一时间过期,导致在高并发到来时缓存失效,所有的压力都压在数据库上。针对这一问题分两类情况讨论:可预期高并发和不可预期高并发。

  • 在可预期高并发场景下(如双十一的秒杀、游戏维护开服),既然高并发的到来使可预期的,那么就可以通过预先缓存的方式应对高并发。
  • 在不可预期的高并发场景下,优化的方向是避免大量的key在同一时间过期。可以通过添加随机变量的方式来避免集中过期的情况,即失效时间=基础失效时间+随机值,这样每一个缓存的过期时间就会相互错开,从而避免集中失效的情况发生。

3.4 数据库主从同步间隔导致数据不一致

在数据库主从、主库只负责写、从库只负责读的场景下,亦容易发生缓存数据不一致问题,场景如下:

Created with Raphaël 2.1.2 调用方 调用方 服务 服务 数据库_主 数据库_主 缓存 缓存 数据库_从 数据库_从 write_req A read_reqB A.update_db A.evict_cache B.read_cache(failed) B.read_db B.write_cache db.synchronize

两个并发请求:写请求A和读请求B,A更新数据库后淘汰缓存,此时B读取缓存失败,从从库中读到尚未同步的旧数据并写入缓存中,缓存与数据库发生不一致。

这个场景的优化方向是减少数据不一致情况存在的时间。使用数据库日志订阅工具订阅从库的binlog日志,当从库的日志更新时,使用订阅工具淘汰缓存中的数据。这样可以保证间隔大于主从数据库同步间隔的读请求一定不会读到脏数据,这个同步时间可以根据需求设置为一个很短的时间,MySQL的默认同步时间间隔是1分钟。

4. 总结

缓存本质上是一种为了提高访问效率而牺牲强一致性的设计,因此针对有强一致性要求的系统,使用缓存是不那么合适的;同样的,针对于频繁写的系统也是不适合使用缓存的。缓存的不一致性主要表现在并发读写的场景下,尤其是数据库层使用了主从读写分离的架构。

关于缓存的效果,一定是命中率越高越好,在缓存的key不是由运维人员根据请求分析后自主决定的情况下,决定缓存命中情况的主要是缓存的失效时间(过期时间)。失效时间太短,就可能导致每过一段时间同一个key就需要到数据库中查询一遍,使命中率降低;失效时间太长,就可能导致缓存中大量的key既不被访问又不失效,内存资源被大量浪费,同时新的key在缓存时需要使用LRU之类的算法重新分配内存空间,导致缓存性能的下降。


参考文献

  1. http://www.cnblogs.com/llzhang123/p/9037346.html
  2. https://mp.weixin.qq.com/s/4J3oM1j5hcLq4w4TdSEMPg
  3. https://blog.cdemi.io/design-patterns-cache-aside-pattern/
  4. https://www.jianshu.com/p/d96906140199
  5. https://docs.microsoft.com/en-us/azure/architecture/patterns/cache-aside
  6. http://www.cnblogs.com/llzhang123/p/9037346.html
  7. https://www.cnblogs.com/dinglang/p/6133501.html
  8. https://www.cnblogs.com/uglyliu/p/6223253.html
  9. https://www.jianshu.com/p/8a032aa3a8e9
常见缓存架构原理 互联网公司在缓存架构上是区分很大的,往往是根据企业的业务量来进行选择的,可以看如下图 在传统的小型互联网公司,采用网页静态化技术,freemarker来加快用户的体验速度,从来来提升响应,但是如果出现了缓存血崩,缓存击穿那么对数据库将会造成很大的压力,可能导致整个架构无法使用 一 缓存击穿   缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写... 阅读详情

相关推荐

【Telephony】APN配置及加载流程&项目实践(AOSP)

学习APN关键是学会明白apns-conf.xml文件各个参数的意思,然后熟悉TelephonyProvider是如何读取文件创建数据库的,譬如数据库表的约束、文件的读写顺序等,还有读取后的ApnSetting的二次定制以及显示(例如屏蔽xcap等)。虽然一般在项目中APN的需求很简单,就是按照客户提供的APN参数添加上配置,或者在显示屏蔽一些参数,但是项目维护的过程中APN的问题也是比较多的。

weixin_44513784的博客 5514

旁路缓存(Cache-aside)

1)什么是旁路缓存 旁路缓存策略以数据库(Hbase,redis)中的数据为准,缓存中的数据是按需加载的,它可以分为读策略和写策略。 读策略: 从缓存中读取数据;如果缓存命中,则直接返回数据;如果缓存不命中,则从数据库中查询数据;查询到数据后,将数据写入到缓存中,并且返回给用户。 写策略: 更新数据库中(HBASE,Redis)的记录;删除缓存记录。 2)缓存和数据库的数据一致性问题 错误一:先失效缓存,后更新数据库 1)请求A删除缓存数据 2)请求B查询缓存,未命中 3)请求B往数

Asunakiritolove的博客 1万+

ESXi 6.7升级17700523补丁全流程:从下载到验证的保姆级教程

本文提供ESXi 6.7升级17700523补丁的完整流程指南,涵盖从下载、上传到验证的详细步骤。通过SSH命令和vSphere Client操作,确保系统管理员能够安全高效地完成补丁升级,提升虚拟化环境的安全性和稳定性。

linux6sysadmin的博客 839

【架构师之路】深入了解架构中常见的4种缓存模式及其实现

Cache-Aside(旁路缓存)模式,又叫(懒加载)模式,在这种模式下,缓存的读取和写入由应用程序直接管理。应用程序首先尝试从缓存中读取数据,若缓存未命中,则从数据库中加载数据并将其存储在缓存中;对于更新操作,应用程序直接更新数据库,并更新或删除缓存中的相关数据。Read-Through 模式下,缓存层自动管理数据的读取。当应用程序请求数据时,缓存层会先检查缓存,如果缓存命中则直接返回数据;如果缓存未命中,则缓存层自动从数据库加载数据,并将数据存入缓存。Cache-Aside模式中,

代码时光 3963

java modbus通讯协议_Modbus通 讯 协 议

电磁流量计Modbus通 讯 协 议(版本号:9000-K V9.1.1)2020年01月01日通讯协议针对KFD电磁流量计工业应用设计,版本:9000-K V9.1.1,该版本主要用于实时数据采集、流量测量、流量累计控制及部分参数的修改。一、主机系统通讯部件要求1.国际标准RS-485通讯接口部件,不小于11Bytes 的通信缓冲区(FIFO),支持1200、2400、4800、96...

weixin_39956612的博客 1012

Paypal开发者中心获取“ClientId”和“ClientSecret”参数

正式环境设置 1、登录到 paypal开发者中心 网址:https://developer.paypal.com/developer/ 点击右上角登录按钮登录 2、左侧栏 - 我的应用程序和凭证 - 点击“创建新应用” 新注册的paypal账号,需要进行邮箱验证,验证通过后,需要等待一段时间(或重新登录),才会出现相关设置项位置 验证邮箱通过后,点击创建新应用 3、按提示填写,保存创建应用 4、点击刚创建的应用进入应用详情页 5、应用详情页获得网站开发人员所需要的“ClientId”和“Client

龚清林的博客 1万+

Redis之旁路缓存

Redis之旁路缓存Redis作为缓存中间件早已深入人心,但我们有没有想过Redis为什么能作为缓存呢?Redis到底怎样使用缓存呢?本篇文章详细聊聊。Redis为什么能作为缓存聊Redis为什么能作为缓存前先需要清楚缓存的作用,我们在很多场景都有接触过缓存就如Redis本身的输入输出缓存、复制缓冲区、复制积压缓存区等等,又如操作系统本身的LLC,page cache缓存等等,这些缓存的主要作用是什么呢?是在一个多层次系统中平衡上下级系统的速度差异。这里以操作系统为例说明,操作系统的存储结构一般为CPU、内

zzf1233的博客 2688

Unity 多线程编程笔记 _Task详解

士大夫

weixin_43405845的博客 4384

旁路缓存模式(Cache-Aside Pattern)如何保证一致性的问题

经典缓存模式:旁路缓存模式 (Cache-Aside Pattern)读缓存:接收用户读请求 --> 从缓存中查询数据 --> 命中缓存数据直接返回 --> 未命中则从数据库中查询数据。写缓存:接收用户写请求 --> 先写入数据库 --> 再写入缓存。读/写穿透模式 (Read/Write Through)将缓存操作(具体来说是数据读写操作)封装成一个缓存服务(Cache Provider),所有数据的读写操作都调用这个缓存服务。

AHAO的博客 3651

51单片机8×8LED点阵屏动态显示取模汉字+ Proteus仿真

51单片机8×8LED点阵屏动态显示取模汉字+ Proteus仿真 Proteus仿真 取模软件:pctolcd2002 程序代码 #include<reg52.h> unsigned char code taba[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//行选 unsigned char code tabb[]={0x08,0x49,0x49,0x7F,0x08,0x49,0x49,0x7F};//选列"出" unsigned cha

perseverance51博客 8057

【RT-DETR改进涨点】ResNet18、34、50、101等多个版本移植到ultralytics仓库(RT-DETR官方一比一移植)

本文是本专栏的第一篇改进,我将RT-DETR官方版本中的ResNet18、ResNet34、ResNet50、ResNet101移植到ultralytics仓库,网上很多改进机制是将基础版本的也就是2015年发布的ResNet移植到ultralytics仓库中,但是其实RT-DETR实验的ResNet和其是有很大区别的在其中有很多细节上的不同(文章中我也会列出举例)

Snu77的博客 7223

三种缓存模式

【代码】三种缓存模式。

weixin_44645022的博客 1199

芒果YOLOv8改进165:损失函数angleLoss:即插即用 | 独家首发原创新颖|公开数据集DOTA高效无损涨点0.5% | 旋转检测

YOLOv8改进:旋转检测Loss损失函数angleLoss:即插即用 | 独家首发原创新颖|公开数据集DOTA高效无损涨点0.5%

包括YOLOv5、YOLOv7、YOLOv8等模型改进 1154

全网推荐的《MySQL性能调优与架构设计》笔记,MySQL性能调优入门看这篇就够了

作为最为流行的开源数据库软件之一,MySQL 数据库软件已经是广为人知了,同时项目中几乎无处不在,面试时又100%会问到的技术点,非MySQL莫属了。因此在这里给大家准备了这篇《MySQL性能调优与架构设计》学习笔记。

weixin_51702416的博客 2万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

高性能web系统架构方案

第一部分 客户端篇 1.压缩js、css,将js的引入放在</html>之前; 2.合并一个页面下的js/css文件,压缩传输.(SquishIt)相关博文 3.ajax技术应用.ajax可以做到精准定量的请求,可以减少非必须资源的请求和重复请求. 4.页面压缩传输技术(将页面数据进行压缩.IIS支持gzip压缩) 5.统一将js/css 图片等放到一个单独的服务器上. ...

weixin_30355437的博客 131

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

六、企业级架构缓存篇之memcached

六、企业级架构缓存篇之memcached

weixin_61428407的博客 1936

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

《多级缓存架构设计与实现全解析》

本文全面介绍了多级缓存架构的设计与实现,通过JVM进程缓存(Caffeine)、Redis缓存、Nginx本地缓存和Tomcat缓存的四级架构,显著提升系统性能。详细讲解了Lua在OpenResty中的应用、Nginx业务逻辑开发、缓存预热策略及Canal实现数据库与缓存同步的方案。该系统能有效降低数据库压力,提高响应速度,保证数据最终一致性,适用于高并发场景。文章涵盖从理论到实践的完整实现过程,包括缓存分类比较、Caffeine API使用、Lua语法基础、负载均衡优化等关键技术点。

yh云想的博客 2597

Java 架构 19:缓存架构设计(本地缓存 + 分布式缓存)

本文探讨了Java应用中本地缓存与分布式缓存的协同架构设计。通过Caffeine实现高性能本地缓存(微秒级响应),结合Redis构建分布式共享缓存,形成多级缓存防御体系。文章详细介绍了: 缓存价值:降低数据库压力,提升系统吞吐(案例显示性能提升25倍) 架构设计:本地缓存(L1)处理80%请求,Redis(L2)处理19%,数据库仅1% 技术实现: Caffeine集成与智能淘汰策略 Redis部署与Spring Boot整合 完整商品缓存示例代码 监控优化:缓存命中率统计与性能调优建议 适用于中高级开发者

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

Redis 多级缓存架构学习笔记

本文系统介绍了多级缓存架构设计,包含浏览器、OpenResty本地缓存、Redis分布式缓存、JVM进程缓存和数据库五层结构。重点分析了请求全链路流程和数据更新机制,通过Canal监听binlog实现缓存同步更新,采用主动删除策略保证最终一致性。该架构通过分层缓存显著提升性能,有效拦截70%以上请求,同时具备高可用、高扩展性特点,能应对高并发场景并降低数据库压力。文章还详细阐述了各层缓存的特点、作用及协同机制,为构建高性能系统提供了完整解决方案。

人工智能专业学生 1213

多级缓存架构 | 黑马Redis高级篇

黑马Redis教程-多级缓存笔记。全是硬核知识,这期真的学到很多,Nginx+lua本地缓存+redis+jvm的Caffeine实现的多级缓存架构,用canal实现缓存同步。

weixin_54232666的博客 5565

缓存架构方案:Caffeine + Redis 双层缓存架构深度解析

Caffeine是一个基于 Java 8 的高性能本地缓存库,底层采用支持自动加载、刷新、过期。高并发读写性能优秀。适用于热点数据快速访问场景。Redis支持持久化、集群部署、Lua脚本等高级功能。提供丰富的数据结构(String、Hash、List、Set、Sorted Set)。适用于跨节点共享缓存数据的场景。Caffeine + Redis 的双层缓存架构是一种兼顾高性能与一致性的缓存解决方案,特别适合微服务架构下需要快速响应且数据共享的业务场景。

weixin_50236329的博客 1842

16、CPU缓存架构

CPU高速缓存可以分为一级缓存,二级缓存,部分高端CPU还具有三级缓存,每一级缓存中所储存的全部数据都是下一级缓存的一部分,这三种缓存的技术难度和制造成本是相对递减的,所以其容量也是相对递增的。缓存一致性协议会通过处理器之间的通信,确保在一个处理器修改了某个数据后,其他处理器缓存中的该数据会被更新或者失效,从而保证在多个处理器同时对同一个数据进行操作时,它们所看到的数据始终是一致的。当特定数据被多个缓存共享时,处理器修改了共享数据的值,更改必须传播到所有其他具有该数据副本的缓存中。

sproutBoy的博客 2712

Redis缓存架构实战

本文探讨了Redis在高并发场景下的应用策略,重点分析了缓存热点数据的关键技术要点。文章首先介绍了基础案例工程,展示了缓存与数据库的增改查操作。随后提出数据冷热分离策略,通过设置缓存过期时间+续期机制来自动筛选热点数据。针对缓存击穿问题,建议采用随机过期时间分散key过期压力。对于缓存穿透问题,推荐缓存空值来缓解恶意请求攻击。全文围绕高并发场景下的Redis优化展开,提供了从架构设计到具体实现的解决方案。

西岭千秋雪的博客 1254

三级缓存架构

三级缓存架构是一种通过分层缓存设计来优化系统性能、降低数据库负载、提高数据访问效率的解决方案,尤其适用于高并发、高吞吐量的业务场景(如电商、社交平台、实时推荐等)。其核心思想是通过多级缓存逐层过滤请求,减少对底层存储的直接访问。三级缓存架构通过分层设计平衡性能、一致性与复杂度,是应对高并发场景的经典方案。实际应用中需结合业务特点灵活调整各级缓存策略,并辅以监控工具(如Prometheus + Grafana)持续优化命中率和响应时间。3. 广播失效本地缓存(如MQ通知)2. 读取分布式缓存。

保持热爱。 1779

多级缓存架构设计

应用 Nginx 本地内存Redis 缓存JVM 内存DB接入层 Nginx:处理入口流量,用作流量分发应用层 Nginx:接近业务层,处理业务逻辑,用作热点缓存的读取Nginx 作为高性能的 Web 服务器,经常被作为反向代理服务器用作负载均衡,这里多增加了一层应用层 Nginx,用来处理热点缓存数据,相比于 Tomcat 集群的本地内存来说,可承接的流量更高。

qq_45260619的博客 1234
下一篇: 机器学习笔记(一)——模型评估方法与性能度量
zeroized
博客等级 码龄10年 3粉丝 2原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值