3种缓存读写策略都不了解?面试很难让你通过啊兄弟

简介: 看到很多小伙伴简历上写了“熟练使用缓存”,但是被我问到“缓存常用的 3 种读写策略”的时候却一脸懵逼。造成这个问题的原因是我们在学习 Redis 的时候,可能只是简单了写一些 Demo,并没有去关注缓存的读写策略,或者说压根不知道这回事。

看到很多小伙伴简历上写了“熟练使用缓存”,但是被我问到“缓存常用的 3 种读写策略”的时候却一脸懵逼。

造成这个问题的原因是我们在学习 Redis 的时候,可能只是简单了写一些 Demo,并没有去关注缓存的读写策略,或者说压根不知道这回事。

但是,搞懂3种常见的缓存读写策略对于实际工作中使用缓存以及面试中被问到缓存都是非常有帮助的!

下面我会简单介绍一下自己对于这 3 种缓存读写策略的理解。

另外,这 3 种缓存读写策略各有优劣,不存在最佳,需要我们根据具体的业务场景选择更适合的。

Cache Aside Pattern(旁路缓存模式)

Cache Aside Pattern 是我们平时使用比较多的一个缓存读写模式,比较适合读请求比较多的场景。

Cache Aside Pattern 中服务端需要同时维系 DB 和 cache,并且是以 DB 的结果为准。

下面我们来看一下这个策略模式下的缓存读写步骤。

先更新 DB

然后直接删除 cache 。

简单画了一张图帮助大家理解写的步骤。

:

从 cache 中读取数据,读取到就直接返回

cache 中读取不到的话,就从 DB 中读取数据返回

再把数据放到 cache 中。

简单画了一张图帮助大家理解读的步骤。

你仅仅了解了上面这些内容的话是远远不够的,我们还要搞懂其中的原理。

比如说面试官很可能会追问:“在写数据的过程中,可以先删除 cache ,后更新 DB 么?

答案: 那肯定是不行的!因为这样可能会造成数据库(DB)和缓存(Cache)数据不一致的问题。为什么呢?比如说请求 1 先写数据 A,请求 2 随后读数据 A 的话就很有可能产生数据不一致性的问题。这个过程可以简单描述为:

请求 1 先把 cache 中的 A 数据删除 -> 请求 2 从 DB 中读取数据->请求 1 再把 DB 中的 A 数据更新。

当你这样回答之后,面试官可能会紧接着就追问:“在写数据的过程中,先更新 DB,后删除 cache 就没有问题了么?

答案:理论上来说还是可能会出现数据不一致性的问题,不过概率非常小,因为缓存的写入速度是比数据库的写入速度快很多!

比如请求 1 先读数据 A,请求 2 随后写数据 A,并且数据 A 不在缓存中的话也有可能产生数据不一致性的问题。这个过程可以简单描述为:

请求 1 从 DB 读数据 A->请求 2 写更新数据 A 到数据库并把删除 cache 中的 A 数据->请求 1 将数据 A 写入 cache。

现在我们再来分析一下 Cache Aside Pattern 的缺陷。

缺陷 1:首次请求数据一定不存在 cache 的问题

解决办法:可以将热点数据可以提前放入 cache 中。

缺陷 2:写操作比较频繁的话导致 cache 中的数据会被频繁被删除,这样会影响缓存命中率 。

解决办法:

数据库和缓存数据强一致场景 :更新 DB 的时候同样更新 cache,不过我们需要加一个锁/分布式锁来保证更新 cache 的时候不存在线程安全问题。

可以短暂地允许数据库和缓存数据不一致的场景 :更新 DB 的时候同样更新 cache,但是给缓存加一个比较短的过期时间,这样的话就可以保证即使数据不一致的话影响也比较小。

Read/Write Through Pattern(读写穿透)

Read/Write Through Pattern 中服务端把 cache 视为主要数据存储,从中读取数据并将数据写入其中。cache 服务负责将此数据读取和写入 DB,从而减轻了应用程序的职责。

这种缓存读写策略小伙伴们应该也发现了在平时在开发过程中非常少见。抛去性能方面的影响,大概率是因为我们经常使用的分布式缓存 Redis 并没有提供 cache 将数据写入 DB 的功能。

写(Write Through):

先查 cache,cache 中不存在,直接更新 DB。

cache 中存在,则先更新 cache,然后 cache 服务自己更新 DB(同步更新 cache 和 DB)。

简单画了一张图帮助大家理解写的步骤。

读(Read Through):

从 cache 中读取数据,读取到就直接返回 。

读取不到的话,先从 DB 加载,写入到 cache 后返回响应。

简单画了一张图帮助大家理解读的步骤。

Read-Through Pattern 实际只是在 Cache-Aside Pattern 之上进行了封装。在 Cache-Aside Pattern 下,发生读请求的时候,如果 cache 中不存在对应的数据,是由客户端自己负责把数据写入 cache,而 Read Through Pattern 则是 cache 服务自己来写入缓存的,这对客户端是透明的。

和 Cache Aside Pattern 一样, Read-Through Pattern 也有首次请求数据一定不在 cache 的问题,对于热点数据可以提前放入缓存中。

Write Behind Pattern(异步缓存写入)

Write Behind Pattern 和 Read/Write Through Pattern 很相似,两者都是由 cache 服务来负责 cache 和 DB 的读写。

但是,两个又有很大的不同:Read/Write Through 是同步更新 cache 和 DB,而 Write Behind Caching 则是只更新缓存,不直接更新 DB,而是改为异步批量的方式来更新 DB。

很明显,这种方式对数据一致性带来了更大的挑战,比如 cache 数据可能还没异步更新 DB 的话,cache 服务可能就挂掉了。

这种策略在我们平时开发过程中也非常少见,但是不代表它的应用场景少,比如消息队列中消息的异步写入磁盘、MySQL 的 InnoDB Buffer Pool 机制都用到了这种策略。

Write Behind Pattern 下 DB 的写性能非常高,非常适合一些数据经常变化又对数据一致性要求没那么高的场景,比如浏览量、点赞量。

本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。

相关文章
|
2月前
|
缓存 Java
Java本地高性能缓存实践问题之Caffeine缓存库中基于时间设置驱逐策略的问题如何解决
Java本地高性能缓存实践问题之Caffeine缓存库中基于时间设置驱逐策略的问题如何解决
|
14天前
|
存储 缓存 Android开发
Android RecyclerView 缓存机制深度解析与面试题
本文首发于公众号“AntDream”,详细解析了 `RecyclerView` 的缓存机制,包括多级缓存的原理与流程,并提供了常见面试题及答案。通过本文,你将深入了解 `RecyclerView` 的高性能秘诀,提升列表和网格的开发技能。
38 8
|
8天前
|
机器学习/深度学习 缓存 NoSQL
深度学习在图像识别中的应用与挑战后端开发中的数据缓存策略
本文深入探讨了深度学习技术在图像识别领域的应用,包括卷积神经网络(CNN)的原理、常见模型如ResNet和VGG的介绍,以及这些模型在实际应用中的表现。同时,文章也讨论了数据增强、模型集成等改进性能的方法,并指出了当前面临的计算资源需求高、数据隐私等挑战。通过综合分析,本文旨在为深度学习在图像识别中的进一步研究和应用提供参考。 本文探讨了后端开发中数据缓存的重要性和实现方法,通过具体案例解析Redis在实际应用中的使用。首先介绍了缓存的基本概念及其在后端系统性能优化中的作用;接着详细讲解了Redis的常见数据类型和应用场景;最后通过一个实际项目展示了如何在Django框架中集成Redis,
|
21天前
|
缓存 JavaScript 中间件
优化Express.js应用程序性能:缓存策略、请求压缩和路由匹配
在开发Express.js应用时,采用合理的缓存策略、请求压缩及优化路由匹配可大幅提升性能。本文介绍如何利用`express.static`实现缓存、`compression`中间件压缩响应数据,并通过精确匹配、模块化路由及参数化路由提高路由处理效率,从而打造高效应用。
60 6
|
1月前
|
缓存 NoSQL Java
揭秘性能提升的超级武器:掌握Hibernate二级缓存策略!
【9月更文挑战第3天】在软件开发中,性能优化至关重要。使用Hibernate进行数据持久化的应用可通过二级缓存提升数据访问速度。一级缓存随Session生命周期变化,而二级缓存是SessionFactory级别的全局缓存,能显著减少数据库访问次数,提高性能。要启用二级缓存,需在映射文件或实体类上添加相应配置。然而,并非所有场景都适合使用二级缓存,需根据业务需求和数据变更频率决定。此外,还可与EhCache、Redis等第三方缓存集成,进一步增强缓存效果。合理运用二级缓存策略,有助于大幅提升应用性能。
53 5
|
1月前
|
存储 缓存 前端开发
缓存技术在软件开发中的应用与优化策略
缓存技术在软件开发中的应用与优化策略
|
2月前
|
存储 缓存 监控
系统设计:在搜索系统实现缓存的策略与思考
【8月更文挑战第26天】在构建高性能的搜索系统时,缓存策略是优化查询响应时间和减轻后端数据库压力的关键手段。随着数据量的激增和用户查询需求的多样化,如何设计并实现一套高效、可扩展且易于维护的缓存机制,成为了技术团队面临的重要挑战。本文将深入探讨搜索系统中缓存策略的设计思路与实践经验,旨在为读者提供一套系统性的解决方案。
42 1
|
2月前
|
缓存 算法 前端开发
深入理解缓存淘汰策略:LRU和LFU算法的解析与应用
【8月更文挑战第25天】在计算机科学领域,高效管理资源对于提升系统性能至关重要。内存缓存作为一种加速数据读取的有效方法,其管理策略直接影响整体性能。本文重点介绍两种常用的缓存淘汰算法:LRU(最近最少使用)和LFU(最不经常使用)。LRU算法依据数据最近是否被访问来进行淘汰决策;而LFU算法则根据数据的访问频率做出判断。这两种算法各有特点,适用于不同的应用场景。通过深入分析这两种算法的原理、实现方式及适用场景,本文旨在帮助开发者更好地理解缓存管理机制,从而在实际应用中作出更合理的选择,有效提升系统性能和用户体验。
81 1
|
2月前
|
缓存 NoSQL Redis
一天五道Java面试题----第九天(简述MySQL中索引类型对数据库的性能的影响--------->缓存雪崩、缓存穿透、缓存击穿)
这篇文章是关于Java面试中可能会遇到的五个问题,包括MySQL索引类型及其对数据库性能的影响、Redis的RDB和AOF持久化机制、Redis的过期键删除策略、Redis的单线程模型为何高效,以及缓存雪崩、缓存穿透和缓存击穿的概念及其解决方案。

相关实验场景

更多
下一篇
无影云桌面