缓存基础概念与原理

张开发
2026/4/21 1:28:49 15 分钟阅读

分享文章

缓存基础概念与原理
缓存基础概念与原理这是一个小白的学习记录边学边练把踩过的坑都记下来先说下我为什么要学这个公司项目最近要搞性能优化领导让我负责调研缓存方案。拿到手一看好家伙缓存这东西天天听但具体是啥原理我还真说不清楚。没办法只能从基础开始学起顺便把学习笔记整理出来。如果你也是新手希望这篇笔记能帮到你。什么是缓存我当时看到这个概念都懵了啥是缓存说人话就是缓存就像你买个手机手机自带个充电器。你每次要充电直接从抽屉里拿充电器就行不用每次都去商店买新的。技术上的解释缓存就是把经常访问的数据放在一个访问速度更快的地方。下次再访问同样的数据就不用去原来的地方比如数据库取了直接从缓存里拿。我的理解缓存 快速访问的数据副本核心思想 空间换时间目的 减少数据库压力提高访问速度为什么需要缓存我当时也困惑数据库不是挺快的吗为啥还要搞缓存后来查资料才明白主要是这几个原因1. 性能问题数据库查询慢啊特别是复杂查询、多表关联的时候。举个例子无缓存 用户请求 → 数据库查询100ms → 返回结果 有缓存 用户请求 → 缓存查询1ms → 返回结果好家伙100 倍的性能差距2. 数据库压力想象一下如果 1 万个人同时访问同一个商品详情每次都查数据库数据库不得崩溃就像排队结账无缓存1 万个人都去收银台结账收银员累死有缓存收银员把常见商品的价格贴在墙上大部分人直接看墙就行3. 成本问题数据库扩容贵啊加内存、加 CPU、加机器哪样不要钱缓存便宜多了用内存换性能划算缓存的工作原理这个我一开始也没搞懂后来一点点啃总算是明白了。基本流程有没有用户请求缓存中有吗直接从缓存返回查询数据库写入缓存返回结果说人话就是用户来要数据先去缓存里找找到了直接给命中缓存没找到去数据库查查完顺便放缓存里缓存未命中返回结果关键概念命中率公式命中率 命中缓存的次数 / 总请求次数 * 100%我的理解命中率越高缓存效果越好一般要达到 80% 以上才算合格100% 不可能总有一些冷门数据淘汰策略缓存空间有限满了怎么办得扔掉一些不用的数据。常见的淘汰策略策略说明适用场景LRU最近最少使用的先淘汰通用场景推荐LFU最不经常使用的先淘汰热点数据明显FIFO先进先出简单场景TTL过期时间到了就淘汰时效性数据我的感受LRU 最常用效果也最好LFU 适合热点数据明显的场景TTL 适合有过期时间的数据比如验证码缓存的优缺点这个我得说实话缓存不是万能的有优点也有缺点。优点性能提升访问速度快响应时间短数据库压力小减少数据库查询次数成本低比数据库扩容便宜可扩展性好可以水平扩展缺点数据一致性问题缓存和数据库数据可能不一致缓存穿透/击穿/雪崩搞不好会出大问题增加复杂度代码更难维护内存占用缓存要占内存我的感受缓存是把双刃剑用好了性能飞升用不好问题一堆一定要想清楚再用别为了用而用常见的缓存策略这个我一开始也懵什么 Cache-Aside、Read-Through啥跟啥啊后来才明白就是几种不同的缓存使用方式。1. Cache-Aside旁路缓存最常用的模式流程读操作 1. 先读缓存 2. 缓存没有读数据库 3. 把数据写入缓存 4. 返回结果 写操作 1. 先更新数据库 2. 再删除缓存代码示例// 读操作publicUsergetUser(Longid){// 1. 先读缓存Userusercache.get(id);if(user!null){returnuser;}// 2. 缓存没有读数据库useruserDao.findById(id);// 3. 写入缓存if(user!null){cache.put(id,user);}// 4. 返回结果returnuser;}// 写操作publicvoidupdateUser(Useruser){// 1. 先更新数据库userDao.update(user);// 2. 再删除缓存cache.delete(user.getId());}我的感受最简单最常用适合读多写少的场景我推荐新手就用这个2. Read-Through读穿透说人话就是缓存自己负责从数据库加载数据应用不用管。流程1. 应用读缓存 2. 缓存没有缓存自己从数据库加载 3. 返回结果代码示例// 使用 Caffeine 的 CacheLoaderCacheLong,UsercacheCaffeine.newBuilder().maximumSize(1000).expireAfterWrite(10,TimeUnit.MINUTES).build(newCacheLoaderLong,User(){OverridepublicUserload(Longid){// 缓存没有时自动从数据库加载returnuserDao.findById(id);}});// 应用只需要读缓存Userusercache.get(id);我的感受代码更简洁适合读多写少的场景需要缓存库支持比如 Caffeine3. Write-Through写穿透说人话就是应用只写缓存缓存自己负责同步到数据库。流程1. 应用写缓存 2. 缓存同步写数据库 3. 返回结果代码示例// 使用 Caffeine 的 CacheWriterCacheLong,UsercacheCaffeine.newBuilder().maximumSize(1000).expireAfterWrite(10,TimeUnit.MINUTES).writer(newCacheWriterLong,User(){Overridepublicvoidwrite(Longid,Useruser){// 写缓存时同步写数据库userDao.update(user);}});// 应用只需要写缓存cache.put(id,user);我的感受代码更简洁适合写多读少的场景需要缓存库支持4. Write-Behind写后置说人话就是先写缓存缓存异步写数据库。流程1. 应用写缓存 2. 缓存立即返回成功 3. 缓存异步写数据库我的感受性能最好风险也最大可能丢数据适合对数据一致性要求不高的场景缓存策略对比策略优点缺点适用场景Cache-Aside简单、灵活代码繁琐通用场景推荐Read-Through代码简洁需要缓存库支持读多写少Write-Through代码简洁、数据一致写性能差写多读少Write-Behind写性能最好可能丢数据对一致性要求不高我的建议新手就用 Cache-Aside最稳妥读多写少用 Read-Through写多读少用 Write-ThroughWrite-Behind 慎用除非你很清楚风险验证步骤1. 理解概念看完这篇你应该能回答什么是缓存为什么需要缓存缓存的工作原理是什么常见的缓存策略有哪些2. 画图理解自己画一下缓存的流程图加深理解。3. 思考场景想想你的项目中哪些地方适合用缓存总结我踩过的坑一开始不理解缓存策略后来画图才明白以为缓存越快越好其实要考虑一致性问题不知道选哪种策略新手就用 Cache-Aside核心要点缓存是什么快速访问的数据副本为什么用缓存提高性能减少数据库压力工作原理先查缓存没有再查数据库常见策略Cache-Aside推荐、Read-Through、Write-Through、Write-Behind最后说两句其实缓存基础也没多难就是多画图多思考。我刚开始也懵后来一点点试总算是搞定了。肯定有理解不对的地方欢迎大佬指正。如果你也遇到类似问题希望这篇笔记能帮到你。

更多文章