缓存的思索与总结

[复制链接]
发表于 2026-1-19 16:03:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
新技能或中心件的引入,肯定是办理了亟待办理的标题或是明显提拔了体系性能,而且这种改变所带来的增幅,可以让我们忽略引入新技能所带来的体系复杂性等负面影响。比如是CAP理论中对C和A的衡量。
  什么是缓存

从内存中读取数据,从文件体系通过IO读取磁盘数据,两者在时间上存在较大差别,毫无疑问,从内存中读取数据相较于磁盘会更快,于是便有了缓存,很范例的以空间换时间的运用。
假如数据都放在内存中自然是最好不外,也就没有缓存这么一说了。但如今来看,内存仍旧属于告急资源,须要有选择的将数据(读多写少)放入内存作为缓存来使用。
在缓存方面,大多数标题都可以归结到以下两个方面去讨论:


  • 缓存掷中率
  • 数据划一性
缓存掷中率

读取数据时,从缓存中是否读取到了数据。体系在计划添加缓存层时,一方面提拔体系相应速率,另一方面也能拦截部门查询哀求从而分担数据库压力。对于一些我们盼望在缓存层被拦截的哀求,假如缓存没有掷中,那么缓存层将失去意义。比如常说的几个概念:


  • 缓存穿透:查询缓存中不存在的键(非法的key),哀求到达DB层
  • 缓存击穿:查询缓存中不存在的键(尚未构建缓存),哀求到达DB层
  • 缓存雪崩:缓存大面积失效,哀求到达DB层
   你会发现,上述都是在形貌一个概念:缓存掷中率。只不外是差别场景下缓存未掷中的环境:
我们盼望哀求在缓存层被拦截,但由于未掷中缓存导致哀求到达DB层。以是上述场景的办理方案也都是围绕着:怎样进步缓存掷中率 来睁开的。
缓存击穿还涉及并发场景下缓存重修标题,须要通过加锁来克制。
  数据划一性

有了缓存,就意味着有了两份数据,DB层一份,内存一份,那就一定会涉及数据划一性的标题,而且由于是两份数据,数据同步期间一定会存在不划一环境,除非将数据的修改和缓存的修改作为一个原子操纵(单体应用)。以是,不但要计划数据怎样读取才华进步掷中率,还要计划数据更新时的战略来包管数据划一性。也就是说,参加缓存层后,要从读写两方面举行束缚,形成闭环,如许才华包管缓存和DB层的数据划一性。
常见的场景一定有成熟的办理方案,对于缓存的数据划一性标题,常见的计划有以下几种:


  • 旁路模式
  • 直写模式
  • 异步写模式
旁路模式 Cache aside

读取时先从缓存中读取数据。假如缓存中没有数据,则从数据库中读取,并将数据写入缓存。更新数据时,先更新数据库,然后再将缓存中的数据失效。
   旁路模式中,并发场景下,先更新数据后再删除缓存 和 先删除缓存再更新数据两者有所差别,纵然双删战略包管第二次删除后读取到的都是新数据。
保举使用先更新数据库再删除缓存的做法,长处是不存在使用旧数据重修缓存的环境,且数据不划一的窗口期不依靠于第二次删除,也就是说:更新数据后删除缓存前,并发读会读到旧缓存,但更新数据且删除缓存后,不划一窗口期便竣事了。假如设定的第二次删除的延时是1小时,先更新数据库再删除缓存这种方式会在删除缓存后竣事数据不划一;但先删除缓存再更新数据的方式则强依靠与第二次删除,会在1小时后才竣事数据不划一。
  双写模式

顾名思义,既写数据库,又写缓存。包罗直写和异步写(严酷的双写是指一份数据同时写入两种存储介质,这里的异步写归结到双写模式下便于影象)
直写模式 write through

读取时先从缓存中读取数据,在写入数据时,数据同时写入缓存和数据库
异步写 Write Behind

写入数据时,数据只更新缓存,并异步批量革新到数据库中
旁路和双写

为了方便明白和区分旁路和双写模式,最简单的区分就是:
旁路模式中,缓存更新(失效重修)是被动的,由后续的读操纵举行缓存重修;而双写模式则是主动更新缓存
   旁路模式和双写模式是包管缓存和DB数据划一性的常用做法。分布式体系中也存在一些在旁路和双写根本上举行改进加强的计划,比如旁路模式+TTL逾期时间,双写+赔偿机制等,用来处置惩罚缓存操纵失败时的场景,感爱好的可以继续研究。
  案例

写这篇偏总结性的文章,因由是之前写的一个IDEA插件 ,在第一版计划的时间,思量到之后插件记录的数据增多,于是通过署理模式预留了扩展。

这里通过署理模式添加缓存层,在署理对象中同一举行缓存的处置惩罚。

由于插件开发是单体应用且不思量多线程场景(多编辑器同时操纵一个源文件时,会提示并拒绝),以是这里我们使用旁路模式实现最简单的LRU缓存。详细怎么做呢?

  • 读操纵优先读缓存,缓存没有再读DB(这里是长期化文件)
  • 数据一旦发生修改,比方修改了高亮记录中的条记内容,则失效缓存,期待下一次读取时重新构建缓存即可。
    但是有个标题:这里使用的缓存key和value,key是源码文件名称,value是该文件全部的高亮条记。这里缓存的粒度很大,假如每次修改一条高亮条记就重修整个源码文件的数据,不是很公道。以是照旧双写模式更得当,克制牵一发动满身。每次更新条记,只更新缓存中条记列表内里雷同ID的缓存记录即可。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表