正确地使用缓存可以减少系统响应的时间,降低数据库负载,反之可能带来相反的效果。因此,就必须了解有哪些缓存策略,以及如何根据实际使用场景选择合适的缓存策略。
缓存策略取决于数据和数据访问模式,即,数据是如何写入和读取的。本文将讲述两种读策略(Cache-Aside、Read-Through)和 三种写策略(Write-Through 、Write-Around、Write-Back/Write-Behind)。
目录
- Cache-Aside
- 基本原理
- 运行方式
- 适用场景及优缺点:
- Read-Through
- 基本原理
- 运行方式:
- 适用场景及优缺点
- Write-Through
- 基本原理
- 运行方式
- 适用场景及优缺点
- Write-Around
- 基本原理
- 运行方式
- 适用场景及优缺点
- Write-Back or Write-Behind
- 基本原理
- 运行方式:
- 适用场景及优缺点
- 总结
Cache-Aside
基本原理
应用程序同时和缓存、数据库通信,缓存和主数据库之间没有连接,缓存和数据库的所有操作均由应用程序处理。
运行方式
- 应用程序首先检查缓存。
- 如果在缓存中找到数据,则命中缓存,可以直接读取数据并返回给客户端。
- 如果缓存中找不到数据,明缓存未命中。此时应用程序必须做额外的工作:先查询数据库以读取数据,然后将其返回给客户端,并将数据存储在缓存中,以便后续请求直接命中缓存。
适用场景及优缺点:
适合读取密集型任务,读多写少
优点:可以应对缓存故障问题,缓存故障时依然可以直接访问数据库保证服务;缓存的数据模型可以和数据库数据模型不同。
缺点:当数据更新时,缓存和数据库可能不一致。解决方法有:1、设置缓存数据的TTL,在TTL到达之前,先提供旧数据; 2、可以删除缓存,下一次查询时查数据库然后更新缓存数据; 3、可以在更新数据库时,同时更新缓存。
Read-Through
基本原理
此策略将缓存串联在服务与数据库之间。服务不与数据库直接通信,而是经过缓存获取数据库的数据。
一般这种缓存是靠数据库本身实现的,例如,mysql的缓存功能、DynamoDB Accelerator (DAX)是直读/直写缓存
运行方式:
- 应用程序请求缓存
- 如果命中缓存,则直接返回结果
- 如果未命中缓存,则需要缓存负责读取数据库,然后填充缓存,并返回给应用程序
适用场景及优缺点
适合读多写少的场景。
优点:暂时看不出来有什么优点。。。。编不出来
缺点:与cache-aside类似,第一次查询总会查不到;也同样存在缓存与数据库不一致问题;存在单点故障,当缓存不可用时,会导致整个服务不可用。
Write-Through
基本原理
数据先写入缓存,然后写入数据库。缓存与数据库串联,写入操作始终通过缓存到达数据库。
运行方式
- 应用程序直接写入缓存
- 缓存负责更新数据库。
适用场景及优缺点
优点:能始终保持缓存和数据库的一致性。当与read though组合时,可以避免缓存失效问题。
缺点:写入的时候需要写两次,会有一定延时
Write-Around
基本原理
应用程序与数据库直接通信,也与缓存直接通信。
运行方式
应用程序直接将数据写入数据库,只有当读取时,才顺带更新缓存。
适用场景及优缺点
优点:Write-around 与 read-through 结合起来,在数据只写入一次而读取频率较低或从不读取的情况下提供良好的性能。例如,实时日志或聊天室消息。同样,该模式也可以与cache-aside结合使用。
缺点:可能存在数据库和缓存不一致的情况。
Write-Back or Write-Behind
基本原理
应用程序与缓存直接通信,缓存和数据库通信。
运行方式:
应用程序将数据写入缓存,缓存存储数据并立即向应用程序确认。然后,缓存将数据写回数据库。即先写缓存,然后异步同步数据库。
适用场景及优缺点
适用场景:适合写入密集型的业务
优点:高性能;与read-though 结合使用,可以保证最近更新和最近访问的数据 一直可用。 可以容忍数据库故障
缺点:如果缓存故障,可能数据永久丢失。
总结
在实际使用中,应当结合实际业务场景,选择合适缓存读、写策略或组合。
参考资料:
https://codeahoy.com/2017/08/11/caching-strategies-and-how-to-choose-the-right-one/