多级缓存架构

分布式多久缓存架构

概述

分布式缓存架构是一种用于提高应用程序性能和可伸缩性的计算机架构,它利用分布式计算资源和存储资源来管理和存储数据的缓存。这种架构的主要目标是减轻数据库或其他后端存储系统的负载,从而加快数据访问速度并提高系统的可伸缩性

架构图:

image-20230906104845098

一共分为四层:客户端层、应用层、服务层、数据层;

各层缓存

客户端层:

客户端层的缓存通常是通过浏览器进行管理,它使用响应头中的一些字段来控制缓存行为,将静态文件缓存在客户端本地。

这些字段包括:

  • Cache-Control: 这个响应头字段包含了各种指令,以告诉浏览器如何处理响应的缓存。
    • max-age:指定了资源在被认为过期之前可以被缓存的秒数。例如,max-age=3600表示资源可以在浏览器缓存中存储一个小时。
    • no-cache:表示缓存必须重新验证资源的有效性,但仍然可以缓存。
    • no-store:表示不允许缓存该资源。
    • public:表示该响应可以被任何缓存存储,包括中间代理服务器。
    • private:表示响应只能被单个用户的浏览器缓存,而不能被共享缓存。
  • Expires: 这个响应头字段包含了一个日期/时间值,表示资源的过期时间。
  • ETagLast-Modified: 这两个字段用于实现条件请求。
  • If-None-MatchIf-Modified-Since:这两个请求头字段用于条件请求,浏览器在发现缓存过期或需要重新验证资源时,会使用它们来告诉服务器缓存的版本信息。

应用层:

应用层的缓存通常是通过使用CDN(内容分发网络)来实现的。CDN是一组分布在全球不同位置的服务器群集,它们存储了大量的静态和动态内容(例如网页、图像、视频等),并在接收到用户请求时,根据用户的位置和其他因素,从最近的服务器提供内容。

image-20230906110043011

解决问题:

  • 带宽集中占用的问题
  • 数据分发问题

如果并不存在远距离的数据分发问题,可以使用Nginx的缓存管理(当然可以两者都使用):有静态资源缓存和压缩功能(在本地目录下缓存)。

特点:

  • 可以用于更精细地控制缓存内容(根据URL、HTTP头等条件来配置)

同时使用的理由:

  • 更精细的控制: Nginx允许您更精细地控制哪些内容需要缓存,缓存的时间以及其他缓存策略。
  • 应对CDN故障: 虽然CDN通常可靠,但仍然有可能出现故障或问题。
  • 自定义需求: 某些网站可能有特殊的缓存需求,不适用于CDN默认配置。

服务层:

服务层的缓存在分布式应用中非常重要,可以显著提高性能和减轻数据库负载。进程外缓存和进程内缓存是两种常见的缓存策略,它们有不同的特点和用途:

  1. 进程外缓存(Out-of-Process Cache)
    • 例子: Redis、Memcached等。
    • 特点:
      • 进程外缓存是独立于应用程序进程的,通常运行在单独的缓存服务器上。
      • 它可以在多个应用程序实例之间共享缓存数据,因为多个应用程序可以连接到同一个缓存服务器。
      • 进程外缓存通常具有高性能和低延迟,因为它们专门用于缓存,不受应用程序本身的负载影响。
      • 支持持久化,数据可以在重启后仍然可用。
    • 用途:
      • 存储频繁访问的数据,减轻数据库负载。
      • 缓存计算密集型操作的结果,提高响应速度。
      • 实现分布式锁、消息队列等功能。
  2. 进程内缓存(In-Process Cache)
    • 例子: 本地内存缓存、应用程序内部数据结构等。
    • 特点:
      • 进程内缓存存储在应用程序的内存中,是应用程序的一部分。
      • 它对于单个应用程序实例有效,不共享于多个应用程序实例之间。
      • 进程内缓存通常具有极低的延迟,因为数据可以直接从内存中读取。
      • 数据存储在应用程序的进程内,因此没有网络开销。
    • 用途:
      • 存储短期内需要频繁访问的数据,避免多次查询数据库。
      • 缓存应用程序内部状态和计算结果,以提高处理效率。
      • 在单个应用程序实例内实现临时性的数据共享。

这里需要引入消息队列来解决缓存一致性问题:

  • 当数据库中数据进行更新时需要将变更消息推送给本地缓存和redis缓存,进行双写更新。

当数据有以下特点是使用服务层缓存最好:

  • 缓存的数据是稳定的。
  • 瞬时可能会产生极高并发的场景。
  • 一定程度上允许数据不一致。