3. Envoy 缓存模块概述:HTTP 缓存过滤器、缓存配置结构、缓存键生成规则

在 Envoy 的七层代理架构中,HTTP 缓存过滤器(HTTP Cache Filter) 是实现灾备缓存命中巡检的核心组件。它位于 HTTP 连接管理器(HCM)的过滤器链中,负责拦截上游响应并将其缓存到后端存储,同时在下游请求到达时提供缓存命中服务。本章将深入剖析该过滤器的内部机制、配置结构以及缓存键的生成规则,为后续的性能调优奠定基础。

3.1 HTTP 缓存过滤器:架构定位与工作流

Envoy 的缓存过滤器遵循 RFC 7234(HTTP 缓存规范)标准,支持 GET 和 HEAD 方法的缓存,并严格遵循 Cache-Control、Expires、ETag 等头部指令。其核心工作流分为 请求路径 和 响应路径 两个阶段:

  • 请求路径(Lookup):下游请求到达时,过滤器根据缓存键查询后端存储。若命中且未过期,直接返回缓存响应(X-Cache: HIT);若未命中或过期,将请求转发给上游,并标记为 X-Cache: MISS。
  • 响应路径(Store):上游响应返回时,过滤器根据 Cache-Control 等头部判断是否可缓存。若可缓存,则将响应体与元数据写入后端存储,并设置 TTL。
关键指标:Envoy 的缓存过滤器在 Lookup 阶段支持 conditional request(条件请求),即当缓存过期时,可携带 If-None-Match 或 If-Modified-Since 向上游验证,若上游返回 304,则复用缓存并刷新 TTL。这一机制在灾备场景下可显著减少上游回源压力。
HTTP 缓存过滤器工作流(请求/响应路径) 下游请求 缓存查找(Lookup) 缓存命中(HIT) 缓存未命中(MISS) 转发上游请求 上游响应返回 缓存存储(Store) 返回响应 说明 虚线:过期/未命中 实线:正常流程 绿色:HIT 红色:MISS

3.2 缓存配置结构:从 Filter 到 Backend

Envoy 的缓存配置采用 分层结构,从 HTTP 连接管理器(HCM)的过滤器配置,到底层缓存后端存储的详细参数。以下是一个典型的缓存过滤器配置示例:

http_filters:
- name: envoy.filters.http.cache
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.http.cache.v3.CacheConfig
    cache_service:
      name: my_cache_service
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.cache.simple.v3.SimpleCacheConfig
        max_size: 268435456  # 256 MB
        default_ttl: 300s    # 默认 TTL 5 分钟
    allowed_vary_headers:
    - "Accept-Encoding"
    - "Authorization"
    cache_key_config:
      - host_and_path: true
        query_parameters: ["q", "lang"]
        headers: ["X-Custom-Key"]

配置结构的关键层级如下表所示:

配置层级 字段 说明 典型值
Filter 层 cache_service 指定缓存后端存储实现(如 SimpleCache、Redis、Memcached) envoy.extensions.cache.simple.v3.SimpleCacheConfig
Backend 层 max_size 缓存存储的最大容量(字节),超出后按 LRU 淘汰 268435456 (256 MB)
TTL 层 default_ttl 当上游响应未携带 Cache-Control: max-age 时的默认 TTL 300s
Vary 层 allowed_vary_headers 允许的 Vary 响应头部列表,用于区分缓存变体 Accept-Encoding, Authorization
Key 层 cache_key_config 自定义缓存键生成规则(见 3.3 节) host_and_path, query_parameters
性能陷阱:max_size 设置过小会导致频繁的 LRU 淘汰,降低缓存命中率;设置过大则可能耗尽内存,触发 OOM Killer。建议根据实际流量模型,通过 缓存命中率监控 动态调整,初始值可设为节点可用内存的 10%-20%。

3.3 缓存键生成规则:从 URL 到唯一标识

Envoy 的缓存键(Cache Key)是缓存查找和存储的唯一标识符。默认情况下,缓存键由 Scheme + Host + Path + Query Parameters 组成,但通过 cache_key_config 可以高度自定义。缓存键的生成规则直接影响缓存粒度和命中率:

  • 默认规则:http://example.com/api/v1/users?page=1 的缓存键为 http|example.com|/api/v1/users|page=1。
  • 自定义规则:通过 host_and_path、query_parameters、headers 三个子配置控制键的组成部分。

以下是一个缓存键生成的详细示例:

# 请求 URL: https://api.example.com/search?q=envoy&lang=zh&page=2
# 配置:
cache_key_config:
  - host_and_path: true
    query_parameters: ["q", "lang"]
    headers: ["X-Custom-Key"]

# 生成的缓存键:
# "https|api.example.com|/search|q=envoy&lang=zh|X-Custom-Key=value"

缓存键生成规则的关键参数对比:

参数 类型 作用 对命中率的影响
host_and_path bool 是否包含 Host 和 Path 开启后不同路径独立缓存,粒度更细
query_parameters string[] 指定参与键生成的查询参数列表 只包含关键参数可提升聚合命中率
headers string[] 指定参与键生成的请求头部列表 用于多租户或 A/B 测试场景
scheme bool (隐式) 是否包含 http/https 协议 默认包含,避免协议混用导致缓存失效
缓存键生成规则:从 URL 到唯一标识 输入 URL 解析 URL 组件 Scheme Host Path Query Params Headers 键拼接(| 分隔) 唯一缓存键 键组成 绿色:默认必选 橙色:可选配置 分隔符:|

3.4 缓存键优化策略:提升命中率的关键

在灾备缓存场景中,缓存键的粒度直接决定了命中率。以下是一些经过生产验证的优化策略:

  • 精简查询参数:只将影响响应内容的参数(如 q、lang)加入键,忽略 utm_source、session_id 等无关参数。可通过 query_parameters_exclude 配置排除。
  • 规范化路径:对路径进行大小写归一化、去除尾部斜杠,避免同一资源因路径格式不同导致缓存分裂。
  • 头部白名单:仅将必要的请求头部(如 Accept-Encoding)加入键,避免因 Cookie 或 User-Agent 等高频变化头部导致缓存碎片化。
  • 使用 Vary 头部:当上游响应携带 Vary: Accept-Encoding 时,Envoy 会自动为不同编码生成缓存变体,无需手动配置头部到键中。
实战案例:某电商平台在灾备切换后发现缓存命中率从 85% 骤降至 30%。经排查,原因是 session_id 被默认加入了缓存键。通过配置 query_parameters: ["product_id", "category"] 并排除 session_id,命中率恢复至 78%。这一优化在灾备场景下减少了 60% 的上游回源流量。