Redis缓存如何保证与数据的一致性
如何保证Redis与数据库数据一致
打开浏览器搜索 “如何保证Redis与数据库数据一致”
打开几个网页,看到几个单词 “Cache-Aside Pattern” “Cache-Aside” “Read-Through” “Write-Through” “Write-Behind” 一顿介绍,有点无厘头。又打开了几个网页,列举4~6个保证Redis与数据库一致方式并举例和贴图,看着是那么回事,但不成体系,下面梳理一下,并加入自己的理解。
先来看下 “Cache-Aside Pattern(缓存旁路模式)” 这个东东,我的理解是业界的一种通用的处理模式,它定义了一种使用缓存的实现方式,形成了一种约定俗称的模式。至于这个出处,没有找到,有知道的告诉我一下~
写在前面 “Cache-Aside(延迟加载)” “Read-Through(通读)” “Write-Through(直写)” “Write-Behind(后写)” 这 4 个是 “Cache-Aside Pattern(缓存旁路模式)” 的 缓存填充策略 。有的文章将它们搞混了这里注意。
什么是 Cache-Aside Pattern (缓存旁路模式)
有的文章将这个翻译成 缓存旁路模式 ,我觉得有点体现不出这个模式的用途,我这里翻译成 端缓存模式 觉得更容易理解。下面都使用 端缓存模式 替换 缓存旁路模式
端缓存模式也称为Lazy Loading(延迟加载),是一种在系统设计中用于高效管理数据并提升性能的缓存策略。当应用程序需要数据时,它首先会检查缓存。如果找到数据(缓存命中),则直接使用。如果未找到数据(缓存未命中),则应用程序会从主数据库中检索数据,将副本存储在缓存中以备将来使用,然后使用获取的数据。此模式可以减少数据库负载,加快数据访问速度,并广泛用于确保频繁访问的数据快速可用,从而提高应用程序的效率和可扩展性。
- 应用程序请求数据: 当应用程序需要数据时,它首先检查缓存中是否有数据。
- 缓存命中: 如果在缓存中找到数据,则立即返回给应用程序,确保快速访问。
- 缓存未命中: 如果在缓存中找不到数据,应用程序将从主数据库中检索数据。
- 缓存填充: 从数据库获取数据后,应用程序会将该数据的副本存储在缓存中以供将来的请求使用。
- 数据使用: 然后应用程序根据需要使用获取的数据。
它如何提高系统性能?
缓存侧模式利用内存缓存的速度和效率来减轻主数据库的负载并加快数据检索速度,从而提高系统性能。它提升性能的具体方式如下:
- 更快的数据访问: 从内存(缓存)访问数据比从磁盘存储(数据库)检索数据快得多。通过将频繁访问的数据存储在缓存中,该模式可确保对相同数据的后续请求能够得到快速处理,从而缩短响应时间,带来更流畅的用户体验。
- 降低数据库负载: 通过将大量读取请求转移到缓存,该模式减少了直接查询数据库的次数。数据库查询的减少降低了数据库的总体负载,使其能够更高效地运行,并降低出现瓶颈的风险,尤其是在高流量情况下。
- 可扩展性: 随着系统需求的增长,缓存可以处理大量的读取请求,而不会给数据库带来额外的压力。这使得系统更具可扩展性,因为它可以容纳更多用户和更高的数据请求速率,而不会降低性能。
- 提升吞吐量 : 通过将数据检索任务卸载到缓存,数据库可以释放资源来处理其他操作,例如写入请求或更复杂的查询。这提高了系统的整体吞吐量,使其能够在给定的时间内处理更多事务或操作。
- 降低延迟 : 该模式通过提供缓存数据,最大限度地减少数据检索相关的延迟。这对于低延迟至关重要的应用尤其有益,例如实时系统或高频交易平台。
加载策略
注意这里是缓存的加载策略,即数据如何存在在缓存。使用方式一直是:当应用程序需要数据时,它首先会检查缓存。如果找到数据(缓存命中),则直接使用。
四种缓存的加载策略分为两类,一类以数据库为主、一类以缓存为主。
- Cache-Aside(延迟加载)、Read-Through(通读)以数据库为主,通过数据库的值设置缓存的值。==缓存中没有数据在数据库中取出写入缓存==。
- Write-Through(直写)、Write-Behind(后写)以缓存为主,通过缓存的值设置数据库的值。==缓存中一直有数据存在==。
在系统设计中,缓存填充策略对于优化数据检索操作的性能和效率至关重要。这些策略决定了数据如何以及何时加载到缓存中。如下为 4 种加载策略的逐一介绍。
1.Cache-Aside(延迟加载)
Cache-Aside 策略(也称为延迟加载)是指仅在应用程序请求数据时才将其加载到缓存中。首先,应用程序会在缓存中查找所需数据,如果未找到(缓存未命中),则从数据库检索数据,将其存储在缓存中,然后返回给应用程序。这种方法通过仅存储实际需要的数据来确保高效利用缓存空间,尽管首次访问时可能会出现延迟。读取缓存、读取数据库和更新缓存的操作都在应用系统来完成
优点:
- 缓存中仅包含应用程序实际请求的数据,有助于保持缓存大小的成本效益。
- 实现简单,并且能获得性能提升。
缺点: 由于数据仅在缓存未命中后才加载到缓存中,因此初次调用的数据请求响应时间会增加一些开销,因为需要额外的缓存填充和数据库查询耗时。
2. Read-Through(通读)
直读策略将数据加载的责任转移到缓存本身。当应用程序请求数据时,缓存会检查数据是否存在。如果数据不在缓存中,缓存会从数据库中获取数据,存储起来,然后返回给应用程序。这简化了应用程序逻辑,因为缓存可以自行管理数据,从而确保访问模式的一致性,尽管由于缓存未命中处理,初始读取速度仍然可能较慢。写缓存数据的责任由缓存提供者完成
3. Write-Through(直写)
在直写策略中,每次写入操作都会同时更新缓存和数据库。当应用程序写入数据时,它会同时写入缓存和数据库,以确保两者保持同步。此策略保证缓存始终具有最新数据,从而无需进行缓存失效。但是,由于需要进行双重写入,这可能会降低写入操作的速度,并且会增加维护缓存和数据库一致性的复杂性。
这个策略颠倒了 Cache-Aside
填充缓存的顺序,并不是在缓存未命中后延迟加载到缓存,而是在数据先写缓存,接着由缓存组件将数据写到数据库。
优点:
- 缓存与数据库数据总是最新的;
- 查询性能最佳,因为要查询的数据有可能已经被写到缓存中了。
缺点: 不经常请求的数据也会写入缓存,从而导致缓存更大、成本更高。
4. Write-Behind(后写)
另一种策略是后写式(或回写式),即先将写入操作写入缓存,然后异步传播到数据库。这种方法可以通过减少应用程序感知到的延迟来提高写入性能,因为数据在缓存中可立即使用。然而,由于缓存更新和数据库更新之间存在时间滞后,这会增加确保数据一致性的复杂性,如果在写入完成之前缓存发生故障,可能会导致数据丢失。
看去似乎与 Write-Through
一样,其实不是的,区别在于最后一个箭头的箭头:它从实心变为线。 这意味着缓存系统将异步更新数据库数据,应用系统只与缓存系统交互。
这种策略下,缓存与数据库的一致性不强,对一致性高的系统不建议使用。
Redis下使用 Cache-Aside Pattern(端缓存模式)
Cache-Aside(延迟加载)
本身就是应用程序控制读取缓存、读取数据库和更新缓存,天然支持。
由于 Redis 不会帮助我们实现缓存部分的逻辑,所以没有 Read-Through(通读)
加载模式。同理Write-Through(直写)
、Write-Behind(后写)
也不是由缓存操作,而是需要应用程序控制。
因此在
参考文章
#mysql #缓存 #redis