3. Envoy 缓存机制:本地缓存与分布式缓存原理、缓存过滤器配置

Envoy 的缓存能力并非内置在核心代理中,而是通过可插拔的 Cache Filter(缓存过滤器) 实现。该过滤器位于 HTTP 连接管理器(HCM)的过滤器链中,拦截请求与响应,依据可配置的规则决定是否缓存、是否命中。理解其底层存储模型——本地缓存与分布式缓存——是正确配置缓存过滤器、平衡命中率与 RPO 的前提。

3.1 缓存存储模型:本地 vs 分布式

维度 本地缓存(Local Cache) 分布式缓存(Distributed Cache)
存储位置 Envoy 进程内内存(共享内存区域) 外部缓存集群(如 Redis、Memcached)
数据一致性 单机强一致,无跨节点同步 依赖外部存储的一致性模型(通常为最终一致)
失效传播 仅影响当前 Envoy 实例 可通过发布/订阅或 TTL 全局失效
延迟 纳秒级(纯内存指针访问) 微秒到毫秒级(网络往返 + 序列化)
容量上限 受限于单机内存(通常 GB 级) 可水平扩展至 TB 级
适用场景 高频、小体量、对延迟极度敏感的资源 大规模共享、跨 Envoy 实例的全局缓存
RPO 风险 Envoy 重启/崩溃后缓存全部丢失 缓存集群故障可能导致大面积缓存击穿
工程决策要点: 在灾备场景下,本地缓存提供极致的性能但牺牲持久性;分布式缓存提供共享与持久化能力但引入网络依赖。联合优化通常采用 L1(本地)+ L2(分布式) 两级架构,L1 负责热数据快速响应,L2 负责冷数据回源与灾备恢复。

3.2 缓存过滤器(Cache Filter)架构

Envoy 的缓存过滤器遵循 外部缓存接口(External Cache Interface) 设计,将缓存逻辑与存储实现解耦。过滤器本身只负责请求匹配、响应拦截、缓存键生成;实际的存储操作委托给注册的缓存插件。

Envoy 缓存过滤器架构(L1 + L2 两级) HTTP 请求进入 Cache Filter(缓存过滤器) 请求拦截 · 缓存键生成 · 响应缓存决策 缓存键查找(Cache Key Lookup) L1 本地缓存命中 直接返回响应 L1 未命中 → 查询 L2 分布式缓存 L2 结果回填 L1 并返回响应 两级缓存架构:L1 本地缓存提供极低延迟,L2 分布式缓存提供灾备恢复与全局共享能力

3.3 缓存过滤器核心配置

缓存过滤器通过 envoy.filters.http.cache 过滤器名称在 HCM 中启用。以下是一个典型的 L1 + L2 联合配置示例:

http_filters:
- name: envoy.filters.http.cache
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.http.cache.v3.CacheConfig
    # 缓存键配置:基于 Host + Path + Query
    key_config:
      allowed_vary_headers:
      - exact: "accept-encoding"
      - exact: "authorization"
    # 缓存存储配置
    cache_storage:
      # L1:本地内存缓存(共享内存)
      local_cache:
        memory_size_bytes: 268435456  # 256 MB
        ttl: 300s                     # 默认 TTL 5 分钟
      # L2:外部分布式缓存(Redis 示例)
      distributed_cache:
        cluster_name: redis_cache_cluster
        timeout: 50ms
        max_entries: 100000
    # 缓存控制策略
    cache_rules:
    - match:
        prefix: "/api/v1/products"
      allowed_methods: ["GET", "HEAD"]
      cacheable_response_codes: [200, 301, 302]
      cache_key_strategy: INCLUDE_QUERY
    - match:
        prefix: "/static"
      allowed_methods: ["GET"]
      cacheable_response_codes: [200]
      cache_key_strategy: EXCLUDE_QUERY
    # 失效策略
    invalidation:
      purge_method: PURGE
      purge_headers:
      - exact: "x-cache-purge-key"
配置要点:
  • cache_storage:同时配置 local_cache 和 distributed_cache 即启用两级缓存;仅配置其一则退化为单级。
  • cache_rules:按路由前缀精细化控制缓存行为,避免敏感接口被缓存。
  • invalidation:通过 PURGE 方法或自定义 Header 实现主动失效,是控制 RPO 的关键手段。

3.4 缓存键生成与 Vary 处理

缓存键(Cache Key)的生成策略直接影响命中率。Envoy 默认使用 Host + Path + Query 作为缓存键,但可通过 key_config 中的 allowed_vary_headers 扩展键维度。

缓存键组件 说明 对命中率的影响
Host 请求的 Host Header 多域名场景下,相同资源因 Host 不同而缓存多份,降低命中率
Path URL 路径 路径规范化(如去除尾部斜杠)可提升命中率
Query URL 查询参数 INCLUDE_QUERY 策略下,参数顺序变化会导致缓存未命中
Vary Header 如 Accept-Encoding、Authorization 增加键维度,减少缓存共享,但保证响应正确性
RPO 风险提示: 缓存键粒度过粗(如忽略 Authorization Header)可能导致用户 A 看到用户 B 的私有数据,造成数据泄露。在灾备场景下,宁可降低命中率也要保证缓存键的正确隔离性。

3.5 缓存失效与 RPO 控制

缓存失效策略是 RPO 优化的核心。Envoy 支持三种失效机制:

  1. TTL 过期:基于响应中的 Cache-Control: max-age 或配置中的默认 TTL。这是最基础的失效方式,RPO 等于 TTL 值。
  2. 主动 PURGE:通过发送 HTTP PURGE 请求到 Envoy,指定缓存键进行立即失效。适用于数据变更后的即时清理。
  3. 基于 Header 的失效:通过配置 purge_headers,当上游响应携带特定 Header 时,自动触发相关缓存键的失效。
缓存失效策略与 RPO 关系 TTL 过期失效 RPO = TTL 值 被动失效,无需额外请求 适合容忍延迟更新的场景 主动 PURGE 失效 RPO ≈ 网络延迟 需外部触发 PURGE 请求 适合数据变更后即时清理 Header 驱动失效 RPO = 响应处理时间 上游响应携带失效指令 适合上游感知数据变更的场景 RPO 联合优化策略 • 热数据(高频访问):使用主动 PURGE + 短 TTL(如 60s),RPO 控制在秒级 • 温数据(中等频率):使用 TTL 过期 + Header 驱动失效,RPO 控制在分钟级 • 冷数据(低频访问):使用长 TTL(如 1h),RPO 可容忍小时级,降低 PURGE 开销 • 灾备恢复:L2 分布式缓存使用持久化存储,Envoy 重启后 L1 从 L2 预热,避免缓存雪崩

3.6 缓存过滤器性能调优参数

参数 默认值 调优建议
memory_size_bytes 128 MB 根据可用内存和缓存对象大小调整,避免 OOM
max_entries 无限制 设置上限防止缓存无限增长,触发 LRU 淘汰
timeout 100ms 分布式缓存超时,建议 20-50ms,避免阻塞请求路径
ttl 300s 根据业务容忍的 RPO 设置,灾备场景建议 60-120s
allowed_vary_headers 空 按需添加,过多会降低命中率
巡检关注点: 在灾备缓存命中巡检中,应重点检查 cache_storage 是否配置了 L2 分布式缓存、ttl 是否与 RPO 目标匹配、invalidation 策略是否覆盖了关键数据变更路径。Envoy 的 /stats 端点提供了 cache.filter.hit、cache.filter.miss、cache.filter.evict 等关键指标,用于持续监控缓存效率。