跳至主要內容

多级缓存架构

Hirsuntech大约 14 分钟

多级缓存架构

  1. Web 应用的客户端缓存
  2. 应用层的静态资源缓存
  3. 服务层的多级缓存

引言

缓存是架构设计中提升性能最直接的方法。

1734525394385.png

举例:假设应用程序将原始数据存放在 MySQL 数据库中。

  • MySQL 会将数据存储在硬盘上,以防止掉电丢失。
  • 硬盘的 IO 性能比内存差一个数量级。
  • 典型的读多写少场景,如淘宝、京东等电商应用,需要进行数据的读写分离, 读多写少。
  • 90% 的读取操作通过 Redis 进行数据提取,利用内存的高吞吐特性完成数据操作。

多级缓存架构

分为四层:客户端、应用层、服务层、数据层。

1734525461329.png
1734525461329.png

客户端缓存

1734525500582.png
1734525500582.png
  • 假设商城客户端是浏览器,主要缓存 HTML 中的图片、CSS、JS、字体等静态资源。
  • 例如:百度 logo 图片通过 HTTP 的 expires 响应头控制静态图片的有效期。
    • 过期时间为 2031 年 2 月 8 日 09:26:31。
    • 浏览器会将图片以文件形式保存到本地,再次访问时直接从本地读取,减少带宽损耗。

作为客户端缓存呢,只需要进行文件缓存就可以了。

应用层缓存

对于 expire 要在应用层,也就是 CDN 与 nginx 中来进行设置。

在 CDN 与 Nginx 中进行设置。

CDN(内容分发网络)

  • 主要技术手段是内容分发。
  • 例如:上海用户访问北京服务器资源,通过 CDN 将北京的静态文件缓存到上海服务器,降低网络延迟,提高系统可用性。
  • 智能 DNS 根据用户的 IP 自动就近访问 CDN 节点。
  • CDN 的核心是智能 DNS 服务。
  • 阿里云、腾讯云、华为云等提供 CDN 服务,可以租用,按年付费或流量付费。
  • 设置缓存属性:expires 响应头或 cache-control 响应头。
    • expires 指定具体时间点缓存到期。
    • cache-control 设置缓存时长。
    • 根据不同的业务场景使用不同的响应头。
1734525676003.png

Nginx

1734525735282.png
  • 开源的高性能 Web 服务器。
  • 作为 Web 应用架构中的常客,可以做负载均衡。
  • 适用于企业级应用,通过 Nginx 的静态资源缓存和压缩功能,满足大多数企业级应用场景。
  • 在配置文件 nginx.conf 中增加配置片段,对静态资源进行缓存。
1734525820367.png

服务层缓存

细化为进程内缓存和进程外缓存。

进程内缓存

进程内缓存即我们常说的分布式缓存,如 redis 等,进程内缓存的应用非常多,如mybatis的一级缓存等(为什么很多sql查第一次慢,后面就快了),如下图:

1734525936644.png
1734525936644.png
  • 在应用中开辟一段内存空间,数据在运行时载入内存,提高访问速度。
  • Java 框架中的应用:Hibernate、MyBatis 的一级缓存、二级缓存,Spring MVC 的页面缓存。
  • 开源实现:EHCache、Caffeine 等。

分布式缓存

1734525985199.png
  • 通过独立部署的缓存服务,常用 Redis。
  • 设计多级应用缓存:进程内缓存和分布式缓存相结合。
  • 访问顺序:进程内缓存 -> Redis -> 数据库。
  • 数据库查询成功后,对 Redis 和进程内缓存进行双写更新。

很多人在设计缓存的时候,认为只要加一个redis就行了,其实不是,我们在设计缓存的时候,一般要遵守如下:

  1. 先近后远
  2. 由快到慢
    两个规则来进行逐级访问。

即我们在设计相关的数据时要结合进程内缓存以及分布式缓存,如下图:

1734526096637.png

缓存数据一致性挑战

两级缓存设计后,我们必然遇到其他的问题,例如一致性的问题,如下图:

1734526142284.png
1734526142284.png

数据库写操作不会走缓存。

1734526219507.png
1734526219507.png

解决方法:引入 MQ 消息队列(如 RocketMQ、RabbitMQ、Kafka)。

  • 商品服务实例一对商品价格调整后,向 MQ Broker 发送变更消息。
  • Broker 将消息推送到其他实例和 Redis 集群。
  • 服务实例收到消息后,删除并重新创建缓存,保证数据一致。

由于以上问题又会产生中间件可靠性的问题

什么时候引入多级缓存?

  1. 缓存的数据是稳定的
    • 例如:邮政编码、地域区块、归档的历史数据。
  2. 瞬间可能产生极高并发的场景
    • 例如:12306 春运售票、双十一秒杀、股市开盘交易。
    • 解决方法:应用启动时对热点数据进行预热处理。
  3. 允许引入缓存后数据不一致
    • 例如:博客平台修改自我介绍等非关键性信息。
    • 解决方法:通过 T+1 的方式,采用 ETL 日终处理补全数据。

总结

  • 多级缓存提升性能,但也增加一致性问题和架构复杂度。

  • 需根据具体业务场景决定是否引入多级缓存。