缓存的今生今世

news/2025/2/3 17:01:33 标签: 缓存, spring, java

缓存是什么

了解缓存,首先要了解内存概念,毕竟缓存离不开内存。

内存又称内部存储器和主存储器(RAM),内存条由内存芯片、电路板、金手指等部分组成。它与CPU之间的连通是通过总线完成,是CPU与外存的连通桥梁。计算机里所有的运算都是有内存的来完成的,即使CPU再快,内存的容量不够和读写速度不行,计算机的性能也大大折扣。
在这里插入图片描述
在这里插入图片描述

缓存就是存储数据副本或计算结果的组件,以便后续可以更快地访问

缓存的作用

  • 快:减少延时,提升响应时间,提升用户体验
  • 缓解CPU压力
  • 缓解I/O压力

缓存的应用场景

  • 读多写少

    比如基础数据(省份、国家等)

  • 在一定程度容忍弱一致性、数据丢失

    比如电商商品展示,前100个商品信息;短信验证码、…

  • 实时性要求低

  • 访问频率高

    高并发调用、登录页面

常见的缓存

硬件

CPU缓存

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

缓存行(Cache Line)

缓存基本上来说就是把后面的数据加载到离自己最近的地方,对于 CPU 来说,它是不会一个字节一个字节的加载的

  • Tag: 每条 Cache Line 前都会有一个独立分配的 24 bits来存的 tag,其就是内存地址的前24bits;
  • Index: 内存地址后续的6个bits则是在这一Way的是Cache Line 索引,2^6 = 64 刚好可以索引64条Cache Line;
  • Offset: 再往后的6bits用于表示在Cache Line 里的偏移量
    在这里插入图片描述
路(Way)

缓存需要把数据放到缓存行里,但要容忍一定的hash冲突,也就出现了 N-Way 关联。也就是把连续的 N 个 Cache Line 绑成一组

缓存一致性协议

MESI协议中每个缓存行都有四个状态,分别是:

E(exclusive)独占

缓存行只在当前缓存中,但是是干净的(clean)-- 缓存数据与主存数据相同。
当别的缓存读取它时,状态变为共享(S);
当前写数据时,变为已修改状态(M)。

M(modified)已修改

缓存行是脏的(dirty),与主存的值不同。如果别的CPU内核要读主存这块数据,该缓存行必须回写到主存,状态变为共享(S)。

S(shared)共享

缓存行也存在于其它缓存中且是干净的。

I(invalid)无效

缓存行是无效的

伪共享

由于不同的数据会存在同一个CacheLine,那么只要这个缓存行的某个数据变化了,那么就是导致这个缓存行的数据失效,这个时候其他CPU Core就会存在Cache miss的情况,需要重新到主存加载新数据,这就是所谓的false share(伪共享)。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

GPU缓存

​ GPU 缓存节点直接将缓存的数据路由到系统显卡,以处理、忽略 Maya 依存关系图求值.

数字信号处理器(DSP)缓存

软件

客户端缓存

页面缓存

页面缓存到本地,下次请求不会重复请求相同的资源文件。比如H5通过Mainfest文件来支持离线缓存

APP缓存

将内容缓存到内存或本地数据库中,如图片、视频上次观看记录等

浏览器缓存

用户返回、回退操作后到内容,都可以通过浏览器缓存技术实现,从而减少页面加载时间和网络带宽的使用。从HTTP1.0到HTTP2.0,其引进了状态缓存、强缓存、协商缓存都是Http缓存机制。Http1.1通过引入e-tag标签、expires、cache-control来支持浏览器缓存

  • 强制缓存缓存在有效期内,无需经过任何请求,一直存在。通过HTTP header实现:expires和cache-control参数控制。当输入地址、链接跳转、前进后退等,均可生效,当用户主动刷新页面(F5)时会自动消失。
  • 协商缓存:一种基于变化检测的缓存机制。通过HTTP header实现:基于最后修改时间Last-modified是否变化和资源唯一标识Etag是否变化来实现的。当输入地址、链接跳转、前进后退及用户吧主动刷新页面(F5)也会生效,当用户强制刷新页面(CTRL+F5)会自动消失。

网络缓存

正向代理
  • 含义:即客户端的代理,有自己去配置代理服务器地址,去请求目标服务器,客户端能感知到目标服务器的存在。

  • 常用场景:翻墙、VPN、静态资源缓存
    在这里插入图片描述

反向代理
  • 含义: 和正向代理相反,是服务端的代理,只为目标服务器服务,客户端只知道代理服务器地址,并不知道目标服务器集群的存在。

  • 常用场景:动态内容提供缓存服务、客户端隐藏服务器(集群)的IP地址、Web攻击防护(DoS、DDos)、负载均衡、内容压缩节省网络带宽、Http网络认证;
    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

CDN
  • 含义:Content Delivery Network,内容分发网络

  • 常用场景:1. 将图片等静态资源文件放到CDN上

    ​ 2. 站点加速、点播、直播等场景

  • 解析过程:路由解析 -> 内容分发 -> 负载均衡

    • 无CDN参与时,DNS解析过程(dig www.cc.com +trace命令可查看)
      在这里插入图片描述

    • 有CDN参与时,DNS解析过程
      在这里插入图片描述

    • 命令行

      orjrs@localhost ~ % dig www.baidu.com +trace
      ; <<>> DiG 9.10.6 <<>> www.baidu.com +trace
      ;; global options: +cmd
      .			440076	IN	NS	h.root-servers.net.
      .			440076	IN	NS	k.root-servers.net.
      .			440076	IN	NS	b.root-servers.net.
      .			440076	IN	NS	l.root-servers.net.
      .			440076	IN	NS	e.root-servers.net.
      .			440076	IN	NS	a.root-servers.net.
      .			440076	IN	NS	g.root-servers.net.
      .			440076	IN	NS	f.root-servers.net.
      .			440076	IN	NS	j.root-servers.net.
      .			440076	IN	NS	i.root-servers.net.
      .			440076	IN	NS	m.root-servers.net.
      .			440076	IN	NS	d.root-servers.net.
      .			440076	IN	NS	c.root-servers.net.
      ;; Received 228 bytes from 192.168.1.1#53(192.168.1.1) in 12 ms
      
      com.			172800	IN	NS	a.gtld-servers.net.
      com.			172800	IN	NS	b.gtld-servers.net.
      com.			172800	IN	NS	c.gtld-servers.net.
      com.			172800	IN	NS	d.gtld-servers.net.
      com.			172800	IN	NS	e.gtld-servers.net.
      com.			172800	IN	NS	f.gtld-servers.net.
      com.			172800	IN	NS	g.gtld-servers.net.
      com.			172800	IN	NS	h.gtld-servers.net.
      com.			172800	IN	NS	i.gtld-servers.net.
      com.			172800	IN	NS	j.gtld-servers.net.
      com.			172800	IN	NS	k.gtld-servers.net.
      com.			172800	IN	NS	l.gtld-servers.net.
      com.			172800	IN	NS	m.gtld-servers.net.
      com.			86400	IN	DS	30909 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CF C41A5766
      com.			86400	IN	RRSIG	DS 8 1 86400 20220522050000 20220509040000 47671 . k2Vb08gFGfFhUWeBxoVSwjD5iJ85jhbu0D8ScFZvxbsRGRNWbOo5I6/F FGNKmH7rxcsOWU5rRoC+G46QuE5JhoB74I73dZEBASYD4diRz9VNgyWN nTs/Oqi/KVXmIoiPTdwF2akaad1Nv3/oQmdx1fdr/0tQAXtCQmm7LK+e tn3IIAD1ibQCyDp0i41NZVlj+xEITjGZV7TiovQwTdQsAenfFhlzvp9J 6tETOjjBzqY4oZDLRl1TZd+kw+RHVNa/IsdzUZkJitUWWD2Abw7S5jMW kenLhMl9RhpRZeivprS8ghtk9Mks7Zx7ZN+r+B14ZOapHB7xRHS2xb6i ADtz7g==
      ;; Received 1173 bytes from 192.58.128.30#53(j.root-servers.net) in 41 ms
      
      baidu.com.		172800	IN	NS	ns2.baidu.com.
      baidu.com.		172800	IN	NS	ns3.baidu.com.
      baidu.com.		172800	IN	NS	ns4.baidu.com.
      baidu.com.		172800	IN	NS	ns1.baidu.com.
      baidu.com.		172800	IN	NS	ns7.baidu.com.
      CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - CK0Q1GIN43N1ARRC9OSM6QPQR81H5M9A  NS SOA RRSIG DNSKEY NSEC3PARAM
      CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20220515042345 20220508031345 37269 com. G85af9yVUZB2hay2bsvLuxHRzhsPSr2ScZLnDEQq3mZ9EDgIHcvekTAb xQHTJ7Szcan/pzg7SKApdn53zCYbTRZ685WBp3i50CAwjORwnXXf6Uwc kgEPiq7/dhi6X5/0HV3ceNfZ5P9N8xWWJF0O2ekuOvXzMu97+xwa9RON KLsZ9GSk64hm+XJ4HKDQni6gLoPBrV8eMuNCdc7MJmr6MA==
      HPVUVSGH5TFIA7CM6SS6SMPOS87OE0CE.com. 86400 IN NSEC3 1 1 0 - HPVV8SARM2LDLRBTVC5EP1CUB1EF7LOP  NS DS RRSIG
      HPVUVSGH5TFIA7CM6SS6SMPOS87OE0CE.com. 86400 IN RRSIG NSEC3 8 2 86400 20220515054330 20220508043330 37269 com. CXkfM8s4RkGi2pX2HSqLUtMDnxRiAg3NyoU1ZESE62bPCyF8y+U9zf4u GvuQUTmVXe9vXwClTWb6FK3WhtsGyOcBYv3Wi9UB3iG6pOXwMyz2rfyr xFFuwD/BSFgLDQqsnk4a4kiTtr6mBOHP5WiTVKCNHIOgugzy+W1t06na OWBCmK5bZYmy2h9wOv7qkF6efc/GqH17ryrj0+I5U161MA==
      ;; Received 817 bytes from 192.31.80.30#53(d.gtld-servers.net) in 199 ms
      
      www.baidu.com.		1200	IN	CNAME	www.a.shifen.com.
      ;; Received 72 bytes from 112.80.248.64#53(ns3.baidu.com) in 41 ms
      orjrs@localhost ~ % 
      

服务端缓存

LocalCache

具体参考《本地缓存

分布式缓存

如redis

操作系统缓存

  • 操作系统内核负责管理磁盘缓存,比较典型的就有主存中的页面缓存技术(PageCache)

缓存淘汰策略

  • noeviction 无淘汰机制
  • volatile-ttl 设置存活时间。当内存不足的时候,在过期时间的键空间中,优先移除过期时间最早的key
  • volatile-random 当内存不足的时候,在过期时间的键空间中,随机淘汰数据。由于无法把冷数据筛选出来,会造成缓存污染
  • volatile-lru 当内存不足的时候,在过期时间的键空间中,溢出最近最少访问的key。但对于只访问一次的数据,无法全部筛选出来
  • volatile-lfu LFU策略在LRU策略基础上进行了优化,筛选数据是优先筛选并淘汰访问次数少的数据
  • allkeys-random 当内存不足的时候,在键空间中,随机淘汰数据。
  • allkeys-lru 当内存不足的时候,在键空间中,溢出最近最少访问的key。
  • allkeys-lfu 当内存不足的时候,在键空间中,优先筛选并淘汰访问次数少的数据。

缓存常见问题

缓存击穿

缓存击穿是一个失效的key被大量请求的集中访问(并量访问),导致请求全部打在数据库上。
在这里插入图片描述

原因:

  • 热点数据key突然失效,且大量的请求同时发生

解决方案:

  • 互斥锁或阻塞队列

    Java的Sychronized、lock,mechache的add,Redis的setnx都可以实现,其本质利用tryLock重入锁

  • 热点key不失效

缓存穿透

缓存穿透访问一个key时,其value为null,导致直接穿透缓存去访问DB。
在这里插入图片描述

原因

  • 黑客攻击,利用空数据查询,比如用不存在的商品信息、用户信息来查询
  • 缓存污染,利用网络爬虫技术,不断查询或更新冷数据,导致缓存存在大量冷数据,而热数据被驱逐

解决方案:

  • 缓存空值,即把为null值的key也存在缓存

  • 用布隆过滤器,如Google的BloomFilter

    布隆过滤器优缺点

    优点:1. 查找快,时间复杂度是O(K),其中K是hash函数的个数

    ​ 2. 使用bitMap方式实现,使用数组

缓存雪崩

缓存雪崩时大量key在同一时间失效,同时大量并发访问,cache miss后直接访问数据库,导致数据库负荷而拒绝连接或宕机。
在这里插入图片描述

原因:

解决方案:

  • 分散缓存失效时间

    Key的TTL加上随机数

  • 使用多级缓存

  • 熔断机制

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

以下为Redis高可用方案

在这里插入图片描述


http://www.niftyadmin.cn/n/5840929.html

相关文章

线程的状态转换和调度

新建状态New&#xff1a;新创建了一个线程对象 可运行状态Runnable&#xff1a;线程对象创建后&#xff0c;其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中&#xff0c;变得可运行&#xff0c;等待获取CPU的使用权。 运行状态Running&#xff1a;可运行…

unity学习26:用Input接口去监测: 鼠标,键盘,虚拟轴,虚拟按键

目录 1 用Input接口去监测&#xff1a;鼠标&#xff0c;键盘&#xff0c;虚拟轴&#xff0c;虚拟按键 2 鼠标 MouseButton 事件 2.1 鼠标的基本操作 2.2 测试代码 2.3 测试情况 3 键盘Key事件 3.1 键盘的枚举方式 3.2 测试代码同上 3.3 测试代码同上 3.4 测试结果 4…

29.Word:公司本财年的年度报告【13】

目录 NO1.2.3.4 NO5.6.7​ NO8.9.10​ NO1.2.3.4 另存为F12&#xff1a;考生文件夹&#xff1a;Word.docx选中绿色标记的标题文本→样式对话框→单击右键→点击样式对话框→单击右键→修改→所有脚本→颜色/字体/名称→边框&#xff1a;0.5磅、黑色、单线条&#xff1a;点…

C#,shell32 + 调用控制面板项(.Cpl)实现“新建快捷方式对话框”(全网首发)

Made By 于子轩&#xff0c;2025.2.2 不管是使用System.IO命名空间下的File类来创建快捷方式文件&#xff0c;或是使用Windows Script Host对象创建快捷方式&#xff0c;亦或是使用Shell32对象创建快捷方式&#xff0c;都对用户很不友好&#xff0c;今天小编为大家带来一种全新…

012-51单片机CLD1602显示万年历+闹钟+农历+整点报时

1. 硬件设计 硬件是我自己设计的一个通用的51单片机开发平台&#xff0c;可以根据需要自行焊接模块&#xff0c;这是用立创EDA画的一个双层PCB板&#xff0c;所以模块都是插针式&#xff0c;不是表贴的。电路原理图在文末的链接里&#xff0c;PCB图暂时不选择开源。 B站上传的…

使用Z-score进行数据特征标准化

数据标准化是数据处理过程中非常重要的一步,尤其在构建机器学习模型时尤为关键。标准化的目的是将不同量纲的变量转换到相同的尺度,以避免由于量纲差异导致的模型偏差。Z-score标准化是一种常见且简单的标准化方法,它通过计算数据点与平均值的差异,并将其按标准差进行缩放,…

实现Ajax请求、实现深拷贝

文章目录 1 实现Ajax请求2 实现深拷贝2.1 方法1&#xff1a;JSON.stringify()2.2 方法2&#xff1a;函数库lodash的_.cloneDeep方法2.3 方法3&#xff1a;手写实现深拷贝函数 1 实现Ajax请求 Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;&#xff0c;是指通过…

#define,源文件与头文件,赋值表达式

1.#define 1.1定义 #define 是一个预处理指令&#xff0c;用于定义宏 宏&#xff0c;是预处理阶段&#xff08;在编译之前&#xff09;由预处理器处理的代码片段 1.2使用 1.2.1 #define 可以定义常量 #define PI 3.14159 1.2.2 #define 可以定义宏函数 #define SQUARE(x) ((…