目次
一.缓存技术与Redis
Redis作为缓存的原因
二.缓存更新战略
场景示例
三.缓存题目
缓存穿透
办理方案:缓存空对象
办理方案:布隆过滤
缓存雪崩
办理方案
缓存击穿
办理方案:互斥锁
办理方案:逻辑过期
一.缓存技术与Redis
缓存是计算机中的一种技术,用于存储临时数据,以便在后续访问相同数据时能够更快地获取。在数据被缓存后,将会被存储在一个临时的快速存储介质中,比方计算机内存或专门的高速缓存存储器中。
缓存可以减少对慢速存储介质(如硬盘或网络)的访问次数,从而提高体系的响应速度和性能。当需要访问某个数据时,计算机首先会检查缓存中是否存在该数据。如果存在,就可以直接从缓存中获取,而无需访问慢速存储介质。如果缓存中不存在该数据,计算机则会从慢速存储介质中读取,并将数据存入缓存中,以便后续的访问。
Redis作为缓存的原因
对于Web开发来说,缓存的实现是必要的。首先,频仍的直接操作数据库是不好的,一是速度慢效率低,二是可能会带来很多隐形的题目。
为了办理这些题目,我们就可以通过Redis来实现对数据的缓存操作,我们知道Redis的读写操作是非常快的,根本上都在微秒级别,在数据请求和数据库之间,我们加上一层Redis的数据存储,将Redis作为数据的缓存地区,就可以大大提高体系整体的运行速度和性能。
将Redis作为缓存在Web体系中是已经是非常常见的做法,重要由以下几个原因:
- 性能高效:Redis是基于内存的数据库,读写速度非常快。它的数据结构计划和高效的持久化方式使得它在缓存场景下体现良好,能够快速地响应大量请求。
- 数据结构丰富:Redis支持多种数据结构,如字符串、哈希表、列表、聚集、有序聚集等,这使得它适用于各种不同的缓存需求。
- 持久化支持:虽然Redis是内存数据库,但它支持将内存中的数据定期或者实时地持久化到磁盘上,确保数据的安全性和可靠性。
- 高可用性:Redis支持主从复制和哨兵模式,可以构建高可用性的集群架构,提供数据的备份和故障转移功能,保证体系的稳定运行。
- 丰富的功能:除了作为缓存外,Redis还提供了许多其他功能,如发布订阅、事务、Lua脚本等,可以满足各种不同的业务需求。
二.缓存更新战略
当我们将数据放入缓存之后,我们就需要思量数据的存储战略,由于我们的缓存并不是无限大的,当我们不断的将新数据放入缓存,缓存所剩余的空间就会越来越小,面临如许的情况,我们有俩种办理方案:
- 增长缓存空间的巨细
- 合理规划数据的存储,合理更新缓存中的数据
第一种方案在肯定程度上确实可以缓解我们的压力,但是这是办理不了根本题目的,由于数据是无限的,我们不可能将数据库中的数据完全同步在缓存空间中,如许也会失去缓存空间本来的意义。因此,合理规划数据的存储就成了最正确的选择,也就是选择缓存更新战略。
常见的缓存更新战略包括:
- 缓存失效战略:当数据更新时,直接将缓存中对应的数据删除,下次访问时重新加载最新数据到缓存中。这种战略简单直接,但可能会导致缓存雪崩题目(大量缓存同时失效,导致数据库压力增大),因此可以思量在删除缓存时加上随机的失效时间,使得缓存失效的时间分散开来,减少雪崩的概率。
- 定期刷新战略:定期地(比方每隔一段时间)刷新缓存中的数据,保持缓存数据与数据库中的数据同步。这种战略能够肯定程度上减轻缓存失效带来的压力,但可能导致缓存中的数据不是最新的。
- 基于变乱驱动的主动更新战略:当数据更新时,发布一个变乱通知缓存体系,使得缓存体系能够及时更新对应的缓存数据。这种战略能够保证缓存数据的及时更新,但需要在体系中引入变乱机制。
- 读写分离战略:将缓存中的数据与数据库中的数据分开存储,读操作优先从缓存中获取数据,写操作则更新数据库并删除或者更新缓存中的数据。这种战略可以有用减轻数据库的压力,但需要保证缓存中的数据与数据库中的数据保持同等。
- 淘汰战略:当缓存空间不足时,根据肯定的战略淘汰一部分缓存数据,以腾出空间存储新的数据。常见的淘汰战略包括最近最少利用(LRU)和最少利用(LFU)等。
对于缓存更新战略的探索一直是企业发展中必须直视的难题,相关的技术和理论也在不断的发展,至于如何选择缓存更新战略,则需要根据具体的业务场景来定制。
比如在对同等性需求要求较低的业务场景下,我们就可以合理利用淘汰战略,当空间不足的时间淘汰掉一部分缓存数据,将新的缓存数据存入;而在对同等性需求要求较高的业务场景下,我们每每可以联合多种缓存更新战略,将他们组合起来利用,以得到更高效的运作方式。这些战略看似简单,但研究起来其中却大有门道。
场景示例
假如我们现在有一个查询关键数据的业务需要实验,对数据的同等性也有所要求。我们可以做出如下战略:在进行查询业务的时间,在修改数据库的数据的同时更新缓存,然后对于缓存的数据,我们也给出一个时间限制,当凌驾时间限制的时间,我们就让这块数据在缓存中失效,删除这块缓存数据。
对于如许的缓存更新战略,我们另有些许题目需要思量:
- 操作缓存是删除缓存还是更新缓存?
- 如何保证缓存和数据库中数据的同等性?
如果是每一次操作数据库的时间我们都对缓存中的数据进行更新,就会导致出现很多无重复操作,因此我们一般选择在更新数据库的时间让缓存失效,查询的时间再更新缓存。而我们为了保证缓存和数据库的同等性,每每需要引入事务机制,对于一些分布式的方案我们每每还需要诸如TCC如许的分布式办理方案。除了以上的题目,我们每每还得思量缓存和数据库操作的线程安全题目... ...
因此,根据具体的业务流程来具体定制并仔细推敲是我们在选择缓存更新战略前必须要实验的一步。
三.缓存题目
前面介绍了缓存在企业开发中的根本用法和战略,而对于缓存技术所带来的一些题目也同样成为了口试中的的高频题目,常见的缓存题目诸如缓存穿透,缓存雪崩,缓存击穿等。
缓存穿透
缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,如许的缓存永远都不会生效,而这些请求末了都会到数据库中,造成了性能的极大消耗。严重的乃至直接会导致体系的崩溃。
笔者这里给出图示:
办理方案:缓存空对象
当查询的数据在数据库中不存在时,我们将这个空结果作为一个空值(null)缓存到Redis中,对于这个空值(null),我们设置一段时间(TTL)后这个空值(null)失效过期。如许就可以大大的减轻数据库的压力,纵然有恶意请求发起不存在的查询,在Redis中也会查询到对应的空结果并返回,这个值虽然没故意义,但是却可以避免进一步向数据库发起请求。
对于如许的办理方案
- 长处:实现简单,维护方便
- 缺点:会造成额外的内存消耗,并且可能会造成短期的数据不同等
这里做出解释:假如空值(null)还没有过期的时间用户来查询这个值的,与此同时我们在数据库中插入了用户想要查询的值,用户就会从Redis中拿到这个空值(null),而非用户想要查询的值,也就是缺点中所说的短期的数据不同等。
办理方案:布隆过滤
在缓存查询之前,先利用布隆过滤器判断该查询是否有可能存在于数据库中。如果布隆过滤器认为查询不存在,直接返回,避免真正去查询数据库,从而减轻数据库压力。这里的布隆过滤器并不是说真的记录了全部的数据,它只是通过肯定的算法,对于数据库中的数据进行了哈希,使得它有本事去判断这个数据在数据库中是否存在。
对于如许的办理方案
- 长处:内存占用少,没有多余的key
- 缺点:实现复杂,存在误判可能
缓存雪崩
缓存雪崩是指在同一时间段,大量的缓存key同时失效或者Redis服务宕机,导致大量请求同时到达数据库,从而给数据库带来非常大的压力。
为了办理或者避免如许的题目,我们做出相对应的对策,既然大量key同时失效就会导致雪崩,那我们就可以对于key的失效时间做出干预,利用随机的TTL来限制key的失效时间,避免他们同一时间失效;或者增长Redis的集群服务;又或者给业务添加多级缓存... ...
办理方案
我们做出总结如下:
- 设置不同的缓存失效时间:可以在缓存失效时间上加上一个随机值,使得缓存失效的时间分散开来,避免大量缓存同时失效。
- 利用多级缓存:可以将缓存分为多级,如本地缓存、分布式缓存等,不同级别的缓存设置不同的失效时间,当一级缓存失效时,可以尽量从其他级别的缓存中获取数据,减少对数据库的直接访问。
- 缓存预热:在体系启动或者数据更新时,预先将热门数据加载到缓存中,避免在高并发时才去加载数据导致缓存失效。
- 利用限流措施:在缓存失效后,可以对数据库的访问进行限流,避免大量请求同时访问数据库,可以采用队列等方式进行列队处理。
- 利用集群模式:利用Redis集群的高可用性,通过哨兵模式在主机宕机后立即在从机中选择一台呆板来顶替主机的工作。
- 利用备份缓存:可以设置备份缓存,当主缓存失效时,可以从备份缓存中获取数据,保证体系的稳定性。
缓存击穿
缓存击穿是指针对某个热门数据,它的key失效了,由于缓存中没有该数据,导致大量的请求直接打到数据库上,造成数据库瞬时压力过大的征象。与缓存雪崩不同的是,缓存击穿是针对某个特定的缓存键(Key)失效导致的题目,而不是整个缓存层失效。
举个例子来说,前些天小米汽车发布了,对于发售那一刻,天下各地大量的请求数据同时来访问小米汽车这一个商品,而这里的小米汽车也就是我们所说的热门数据key。
缓存击穿通常发生在如了局景下:某个热门数据的缓存过期,此时有大量的请求同时访问这个热门数据,由于缓存中没有该数据,每个请求都直接访问数据库,造成数据库瞬时压力过大。
在前文中,我们有说到缓存的更新战略,对于缓存中不存在的数据,我们会查询数据库然后重新载入缓存。而如果这个流程发生在一个热门数据的情景下,就可能会发生缓存击穿的题目。笔者这里给出一个图示例子:
如上图所示,在短时间内就会有大量的请求同时访问数据库中的某个热门数据。
办理方案:互斥锁
互斥锁办理缓存击穿题目的理念是避免大量的请求同时重修缓存数据,在重修缓存数据之前,先加上一个锁,当线程来重修缓存数据的时间就会来获取这个锁,获取成功就说明当前还没有线程在重修缓存数据,那么该线程就来重修缓存数据;获取失败就说明当前已有别的线程正在重修缓存数据,那么该线程就进行阻塞等待。如许就可以避免大量数据同时请求数据库来重修缓存。
笔者这里还是给出图示:
对于互斥锁的办理方案有以下特性
- 长处:额外的内存消耗,可以保证数据的同等性,实现简单
- 缺点:线程需要等待导致性能受影响,且可能有死锁风险
办理方案:逻辑过期
在办理缓存穿透题目时,逻辑过期是一种常用的方法。逻辑过期指的是在缓存中设置一个较长的过期时间,但在获取缓存数据时,先辈行一次快速的检查,如果发现缓存数据应该已颠末期(比如根据某个规则判断数据是否存在),则立即返回一个默认值或者空值,同时异步更新缓存。如许可以避免恶意请求直接访问数据库,减轻数据库的压力。
逻辑过期的长处是可以避免频仍地查询数据库,减轻数据库的负载,并且能够在肯定程度上办理缓存穿透题目。但需要注意的是,逻辑过期只是一种应对战略,实际利用时需要根据具体情况综合思量,并且需要确保异步更新缓存的操作是可靠的。
笔者这里还是给出图示:
对于逻辑过期的办理方案,它有以下特性:
- 长处:线程无需等待,性能较好
- 缺点:不能保证数据的同等性,有额外的内存消耗,实现复杂
本次的分享就到此为止了,盼望我的分享能给您带来帮助,创作不易也欢迎大家三连支持,你们的点赞就是博主更新最大的动力!如有不同意见,欢迎评论区积极讨论交流,让我们一起学习进步!有相关题目也可以私信博主,评论区和私信都会认真检察的,我们下次再见
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |