【Redis】Redis 缓存更新方案分析

前言

在业务环境中,频繁访问数据库获取数据的做法是不可取的,为了提升数据请求的效率,目前比较流行的做法就是使用 Redis 缓存服务,将频繁被请求的数据缓存起来,在下一次数据被请求时,根据设定的 key 返回相应的数据。但是,缓存系统的存在,就导致数据库和 Redis 之间需要我们考虑其数据同步的问题。由于两者的数据更新必然不是同时进行的,因此当其中一方出现数据更新时,正在进行的访问就有可能从另一方获取到“肮脏”的数据。接下来,我们就分析一下可能存在的几种方案以及他们各自的优缺点。

方案一:懒加载

服务运行时,Redis 缓存中没有数据,直至接收到数据请求之后,才会去访问数据库获取数据进行返回,并将数据同步到缓存。

这里的缓存更新是由用户请求进行触发的,每一次出现对新数据的请求时,就要对数据库进行一次访问。因此,在并发请求的场景下,缓存数据不存在时,所有的并发请求就会直接打了数据库上,给数据库带来极大的负载,容易造成数据库宕机,影响其他依赖的服务。这种方案一般会伴随着分布式锁,保证一次只能有一个请求访问数据库,并更新缓存,其他请求只能等待该请求完成响应后,直接访问缓存数据。

方案二:手动触发更新,覆盖旧缓存,删除无效缓存

这里的手动触发,是指后台工作人员通过操作启动,亦或是设置定时任务运行更新任务。更新任务触发后,系统会从数据库查询最新的数据集合,覆盖原有的缓存数据,其余的缓存视为无效数据,直接删除。

这个方案保证了任意时刻缓存与数据库都能存在可用的数据,而且能够及时清除无效的缓存数据。但是,该方案的逻辑相对比较复杂,每次更新都需要筛选出不进行缓存覆盖的数据所对应的 key,才能删除无效缓存。这种更新机制与业务内容存在着强关联,无法通用。

方案三:手动触发更新,删除原缓存数据

后台工作人员主动启动缓存更新任务,从数据库批量获取最新的数据集合,然后删除当前缓存的数据,将新数据插入到缓存中。

该方案在更新过程中,缓存在某一段时间内存在没有特定缓存数据的情况,如果此时刚好有业务在进行查询,有可能会获取到数据删除前的旧数据或者空数据,影响业务进行。在业务过程中删除缓存数据的操作容易影响业务功能和用户体验,因此一般不推荐使用该方案。

方案四:缓存预加载

预加载的思想在于,在请求到达之前,Redis 预先将数据加载到缓存;当请求到来后,直接通过 key 从 Redis 中获取已经提前缓存好的数据,而不需要去访问数据库。

合理设计缓存关键字 key 可以有效解决上述三个方案存在的问题。通过在业务空闲时执行定时更新任务对缓存数据进行更新,这样就避免了更新缓存的操作影响了业务功能,同时自动化执行释放了工作人员的操作压力。再者,将 key 由数据关键字与当前时间戳进行组合,则可以用来标识数据及其写入缓存的时间,这个时间戳可以用作区分前后两次缓存的数据。当我们从数据库获取到新的数据时,新的 key 带了新的时间戳,将新数据写入缓存,此时新旧两份数据同时存在。在确保缓存更新完成后,再进行切换,使得外部请求能获取到最新的缓存,之后再对旧的缓存进行删除或者设置一个较短的过期时间,使之消失。

这个方案在大部分业务场景中都非常适用,唯一存在的不足时,它对 Redis 内存的要求较高,因为预加载需要提前完成缓存,由于不确定哪些数据是不会被访问到的,因而几乎所有数据都需要进行缓存,容易造成 Redis 内存的滥用。

    原文作者:千筠Wyman
    原文地址: https://blog.csdn.net/sinat_36645384/article/details/117744602
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞