43 | 如何使用缓存优化系统性能?
该思维导图由 AI 生成,仅供参考
前端缓存技术
1. 本地缓存
- 深入了解
- 翻译
- 解释
- 总结
本文深入介绍了如何使用缓存优化系统性能,从前端到服务端,系统了解了各个层级的缓存实现,并分别了解了各类缓存的优缺点以及应用场景。在前端缓存技术方面,介绍了本地缓存和网关缓存的实现原理和流程。在服务层缓存技术方面,分别介绍了进程缓存和分布式缓存的实现方式和适用场景。文章通过具体的实现代码和示例,帮助读者快速了解了缓存优化系统性能的重要性和实现方法。 此外,文章还深入探讨了数据库与缓存数据一致性问题,以及缓存穿透、缓存击穿、缓存雪崩等问题。针对这些问题,提出了解决方案,如使用线程安全队列缓存更新或删除的数据,以及使用布隆过滤算法来解决缓存穿透问题。同时,对于缓存击穿和缓存雪崩问题,也提出了相应的解决方案。 总的来说,本文全面介绍了缓存优化系统性能的重要性,以及在实际应用中可能遇到的问题和解决方案。读者可以从中了解到如何在前端和服务端合理应用缓存技术,以提高系统性能和降低后端压力。文章内容丰富,涵盖了技术实现细节和解决方案,对于想要深入了解缓存优化系统性能的读者来说,是一篇非常有价值的文章。
《Java 性能调优实战》,新⼈⾸单¥59
全部留言(31)
- 最新
- 精选
- QQ怪学到了很多,挺收益的,思考题:更新效率太低,代价很大,且不一定被访问的频率高,不高则没必要缓存,还不如直接删掉,而且还容易出现数据不一致问题
作者回复: 👍🏻 对的,两个并发写去更新还存在一致性的问题。不过,在删除缓存后,记得读取数据需要加锁或延时等待,防止读取脏数据。
2019-08-2923 - Loubobooo课后题:原因很简单 1. 很多时候,在复杂点的缓存场景,缓存不单单是数据库中直接取出来的值。比如可能更新了某个表的一个字段,然后其对应的缓存,是需要查询另外两个表的数据并进行运算,才能计算出缓存最新的值的。 另外更新缓存的代价有时候是很高的。每次修改数据库的时候,都一定要将其对应的缓存更新一份,这样做的代价较高。如果遇到复杂的缓存数据计算的场景,缓存频繁更新,但这个缓存到底会不会被频繁访问到?如果没有,这个缓存的效率就很低了
作者回复: 👍🏻 回答很全面
2019-08-29211 - giserway还有就是更新缓存代价大。如果缓存里的数据不是把数据库里的数据直接存下来,而是需要经过某种复杂的运算,那么这种不必要的更新会带来更大的浪费。
作者回复: 对的,这也是一种情况
2019-08-298 - yungoo基于redis集中缓存更新数据采用删除而不是直接更新缓存的原因之一:避免二类更新丢失问题。 分布式系统中当存在并发数据更新时,因无法保证更新操作顺序的时间一致性,从而导致旧值覆盖新值。 如: t1时间点,A进程发起更新key1为1的P1操作。 t1+x时间点,B进程发起更新key1为2的P2操作。 其中P1 -> P2,数据库中值为2。 而redis收到的指令,可能因网络抖动或者STW,实际为P2 -> P1,缓存的值为1,造成数据不一致。
作者回复: 👍🏻 存在并发更新时数据不一致问题
2019-08-2926 - Maxwell老师您说的:通常我们会在查询数据库时,使用排斥锁来实现有序地请求数据库,减少数据库的并发压力。这个通常哪些方案?
作者回复: 最常用的就是使用同步锁或Lock锁实现。
2019-08-2933 - 许童童直接更新缓存中的数据,因为请求到达的顺序无法保证,有可能后请求的数据覆盖前请求的数据。直接将数据删除,就是一种幂等的操作,删除后,再去数据库拉数据,就不会有覆写的问题。
作者回复: 对的,如果两个并发写去更新还存在一致性的问题,还不如直接删除,等下次读取的时候再次写入缓存中。不过,在删除缓存后,记得读取数据需要加锁或延时等待,防止读取脏数据。
2019-08-292 - ty_young老师您好,请问协商缓存和强制缓存没有关联么,不会先走强制缓存,然后在强制缓存的基础上走协商缓存
作者回复: 强制缓存只有两种情况,要么访问服务端,要么用本地缓存,所以加上协商缓存意义不大
2019-10-311 - Better me布隆过滤器为什么要经过n个hash函数散列,有什么特别的考虑吗
作者回复: 这是为了计算不同的位置,通过不同位置置1,得出一个数值。
2019-08-2931 - -W.LI-老师真棒,全能。 CDN的缓存策略是copy服务端的,协商缓存和强缓存?如果有些静态资源,服务端开发没做缓存策略,CDN还会缓存么?实际开发中用过一次CDN。是在资源路径前,拼接一段CDN路径。具体不知 课后习题,如果并发操作时,虽然redis是单线程的但是没法保证网络延时下,先更新数据库。也先更新缓存。个人感觉失效一个key比写一个key开销小。网络传输上看,update还得传一个value的值,redis更新还得写缓存感觉也是失效慢。并发情况写两次(除开正确性)有一次的写完全浪费。
作者回复: 通常我们是会指定一些静态资源文件上传到CDN上去,并且通过版本号来更新。例如,我们的js资源文件是 xxx001.js,如果我们更新了该资源文件,则将xxx002.js推送到CDN上,同时前端的访问路径也更新访问资源路径。
2019-08-291 - 💢 星星💢老师,我有个问题,分布式更新或者删除缓存的时候,为啥不对这个操作加锁呢,例如a线程更新或者删除缓存,并更新数据库,然后解锁。此时b线程在争夺锁。并且持有锁。是不是性能问题,所以不这样,还是我理解错了?
作者回复: 没有理解错,锁和我文中提到的队列都是解决redis缓存数据一致性问题的方案,这种解决方案会带来一定的性能损耗
2019-09-293