1. Envoy缓存基础:缓存架构与数据平面作用

1.1 Envoy缓存架构概述

Envoy的缓存层位于HTTP连接管理器(HCM)与上游集群之间,作为反向代理缓存实现。它遵循RFC 7234(HTTP缓存语义),在数据平面内提供可配置的缓存策略,无需依赖外部缓存系统(如Redis或Memcached)即可完成请求/响应的本地缓存。

Envoy缓存架构由以下核心组件构成:

组件 职责 配置入口
Cache Filter 拦截HTTP请求/响应,执行缓存查找与存储 envoy.filters.http.cache
Cache Config 定义缓存键(Cache Key)、Vary规则、TTL策略 HttpConnectionManager.routeConfig
Cache Storage 管理缓存条目在内存或磁盘上的存储与淘汰 envoy.cache.simple_http_cache
Cache Eviction 基于LRU或TTL淘汰过期条目 内置策略,自动触发
Cache Stats 记录命中/未命中/大小/延迟等指标 stats_prefix 自动生成
架构要点:Envoy缓存是无状态、可插拔的。每个Worker线程拥有独立的缓存实例,避免锁竞争;但这也意味着跨Worker的缓存一致性需要由上层负载均衡或外部缓存协调。
Envoy缓存架构分层图 Envoy缓存架构分层图 外部客户端 HTTP连接管理器 (HCM) Cache Filter (envoy.filters.http.cache) 缓存命中 → 直接响应 缓存未命中 → 转发上游 上游集群 (Upstream) 缓存存储:内存/磁盘,LRU淘汰

1.2 缓存层在数据平面中的作用

在Envoy数据平面中,缓存层承担以下四个关键角色:

  1. 请求拦截与缓存查找:当HTTP请求到达Cache Filter时,Envoy根据请求方法、URI、头部(受Vary控制)计算缓存键,在本地存储中查找匹配条目。
  2. 响应缓存与存储:对于可缓存的响应(状态码200/301/302/404等,且包含Cache-Control或Expires头部),Envoy将响应体、头部和元数据写入缓存存储。
  3. 缓存命中响应:若缓存命中且未过期,Envoy直接从缓存构造响应返回给客户端,不经过上游集群,大幅降低延迟和上游负载。
  4. 缓存失效与淘汰:基于TTL过期、LRU淘汰、或显式PURGE请求,Envoy移除过期或无效的缓存条目,保证数据新鲜度。
数据平面性能影响:缓存层位于请求处理的关键路径上。Envoy使用零拷贝(Zero-Copy)技术将缓存数据直接写入Socket缓冲区,避免额外的内存复制。在典型场景下,缓存命中可将P99延迟从50ms降低至2ms以内。

1.3 缓存命中与未命中的基本概念

缓存命中(Cache Hit)与缓存未命中(Cache Miss)是衡量缓存效率的核心指标。Envoy通过cache.hit和cache.miss统计计数器实时追踪这两种状态。

状态 定义 Envoy行为 典型原因
缓存命中 请求的缓存键在存储中存在且未过期 直接返回缓存响应,不转发上游 相同URI重复请求、TTL未过期
缓存未命中 缓存键不存在或已过期 转发请求到上游集群,缓存新响应 首次请求、TTL过期、Vary头部变化
缓存过期 条目存在但TTL已耗尽 视为未命中,转发上游;若上游返回304则刷新TTL Cache-Control: max-age 到期
缓存不可缓存 响应头部禁止缓存(如Cache-Control: no-store) 不存储,每次转发上游 动态API、敏感数据、Set-Cookie
常见误区:缓存命中率并非越高越好。过长的TTL可能导致客户端获取到过期数据;忽略Vary头部可能导致不同客户端(如移动端/桌面端)收到错误的缓存版本。Envoy的缓存策略需要结合业务场景精细调优。
缓存命中与未命中决策流程 缓存命中与未命中决策流程 收到HTTP请求 计算缓存键 (Cache Key) 缓存存在? 检查TTL是否过期 缓存命中 → 直接响应 缓存未命中 转发上游集群 缓存键组成 :method + :path + Vary头部 + Host

1.4 缓存键与Vary头部

Envoy的缓存键(Cache Key)默认由以下元素组成:

  • HTTP方法:GET/HEAD可缓存,POST/PUT/DELETE默认不缓存
  • 请求路径:完整的URI路径(不含查询参数,除非配置包含)
  • Host头部:区分不同虚拟主机的缓存
  • Vary头部:根据响应中的Vary字段,将请求头部的特定值纳入缓存键计算
Vary头部示例:若上游返回 Vary: Accept-Encoding,则Envoy会为 Accept-Encoding: gzip 和 Accept-Encoding: identity 分别存储不同的缓存条目。这确保了压缩版本和非压缩版本不会互相污染。

1.5 缓存配置示例

以下是一个基础的Envoy缓存过滤器配置片段,展示如何启用缓存并设置TTL策略:

http_filters:
- name: envoy.filters.http.cache
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.http.cache.v3.CacheConfig
    cache_service:
      name: envoy.cache.simple_http_cache
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.cache.simple_http_cache.v3.SimpleHttpCacheConfig
        max_size: 268435456  # 256 MB
    cache_key_config:
      allowed_vary_headers:
      - exact: "Accept-Encoding"
      - exact: "Authorization"
    cacheable_status_codes:
    - 200
    - 301
    - 302
    - 404
    default_ttl: 300s  # 默认5分钟
    max_ttl: 3600s     # 最大1小时

该配置启用256MB内存缓存,仅缓存GET/HEAD请求的200/301/302/404响应,默认TTL为5分钟,并允许Vary头部影响缓存键。