4. 缓存机制概述:为什么需要缓存?Envoy中的缓存类型
在云原生数据面中,缓存是提升性能、降低延迟、减少后端压力的核心手段。Envoy 作为高性能 L7 代理,其缓存机制直接影响 CNI 环境下的连接建立效率、DNS 解析延迟和路由决策速度。本章从“为什么需要缓存”出发,系统梳理 Envoy 的三大缓存类型及其在容器网络中的调优价值。
4.1 为什么需要缓存?
在 Kubernetes + CNI 的网络模型中,每个 Pod 的流量路径通常经过:Pod → CNI 网桥 → 节点路由 → Envoy sidecar → 上游服务。如果没有缓存,每次请求都会触发重复的 DNS 查询、TCP 连接建立和路由表查找,导致以下问题:
- DNS 解析延迟:每次请求都查询 DNS 服务器(如 CoreDNS),增加 2-10ms 延迟,且在高并发下容易触发限流。
- 连接建立开销:TCP 三次握手 + TLS 握手(如果启用)每次消耗 1-3 RTT,在容器频繁扩缩容场景下尤为严重。
- 路由计算重复:Envoy 每次请求都重新匹配路由规则,当路由表规模超过 1000 条时,CPU 消耗显著上升。
核心结论:缓存通过“空间换时间”策略,将重复操作的结果暂存于本地内存,使后续相同请求跳过昂贵步骤。在 CNI 环境中,缓存命中率每提升 10%,P99 延迟可降低 5-15%。
4.2 Envoy 中的三大缓存类型
Envoy 的缓存机制分布在数据面的不同层次,分别解决 DNS 解析、连接复用和路由匹配的效率问题。下表对比了三种缓存的核心差异:
| 缓存类型 | 缓存对象 | 默认大小 | 失效机制 | 主要收益 |
|---|---|---|---|---|
| DNS 缓存 | 域名 → IP 映射 | 无限制(按 TTL) | TTL 过期 / DNS 刷新 | 减少 DNS 查询延迟 |
| 连接池缓存 | 上游连接(HTTP/1.1、HTTP/2、TCP) | 每个上游集群 128-1024 连接 | 空闲超时 / 最大请求数 | 复用连接,减少握手 |
| 路由缓存 | 请求 → 路由条目匹配结果 | 取决于路由表大小 | 路由表变更 / 定时刷新 | 加速路由匹配决策 |
4.3 DNS 缓存
Envoy 的 DNS 缓存位于 Strict DNS 和 Logical DNS 集群类型中。当 Envoy 需要解析上游服务域名时,会先查询本地缓存,命中则直接返回 IP,未命中则发起 DNS 查询并缓存结果。
- 缓存粒度:按域名 + 端口组合缓存。
- TTL 控制:默认使用 DNS 响应中的 TTL,可通过
dns_refresh_rate覆盖。 - 典型配置:
clusters:
- name: upstream_service
type: STRICT_DNS
dns_lookup_family: V4_ONLY
dns_cache_config:
name: my_dns_cache
dns_cache_circuit_breaker: { max_pending: 256 }
connect_timeout: 0.25s
lb_policy: ROUND_ROBIN
调优要点:在容器频繁扩缩容场景下,建议将
dns_refresh_rate 设置为 5-10s,避免因 DNS 缓存过久而访问已销毁的 Pod IP。
4.4 连接池缓存
连接池是 Envoy 性能优化的核心机制。每个上游集群维护一个连接池,复用已建立的 TCP/HTTP 连接,避免重复握手。连接池缓存分为三个子层:
- HTTP/1.1 连接池:每个上游端点维护多个 keep-alive 连接,默认最大 128 个。
- HTTP/2 连接池:每个上游端点只维护一个多路复用连接,默认最大 100 个并发流。
- TCP 连接池:用于原始 TCP 代理,每个端点维护一个连接队列。
连接池缓存的关键参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
max_requests_per_connection |
无限制 | 单个连接最大请求数,超过后关闭重建 |
idle_timeout |
1 小时 | 空闲连接超时时间 |
max_connections |
1024 | 每个上游集群最大连接数 |
circuit_breakers |
无限制 | 熔断保护,防止连接池膨胀 |
4.5 路由缓存
Envoy 的路由缓存用于加速 HTTP 请求的路由匹配过程。当请求进入时,Envoy 根据 虚拟主机(Virtual Host) 和 路由规则(Route) 进行匹配。路由缓存存储最近匹配成功的路由条目,避免每次请求都遍历整个路由表。
- 缓存命中条件:请求的 Host、Path、Method 等属性与缓存条目完全匹配。
- 失效时机:路由表通过 xDS 更新时,缓存自动失效。
- 性能影响:在 5000+ 路由规则场景下,路由缓存可将匹配耗时从 50μs 降至 5μs。
注意:路由缓存默认启用,但不会缓存带有
regex 或 prefix_rewrite 的复杂路由。对于动态路由频繁变更的场景,建议配合 route_cache_max_entries 限制缓存大小,防止内存泄漏。
4.6 缓存协同与命中率关键指标
三种缓存并非独立工作,而是形成一条完整的缓存链:
- 路由缓存 决定请求发往哪个集群 → 连接池缓存 决定复用哪个连接 → DNS 缓存 决定连接的目标 IP。
- 任意一层缓存未命中,都会导致该层回源操作,增加延迟。
衡量缓存效率的核心指标:
| 指标 | 计算公式 | 健康阈值 |
|---|---|---|
| DNS 缓存命中率 | DNS 缓存命中次数 / 总 DNS 查询次数 | > 95% |
| 连接池复用率 | 复用连接请求数 / 总请求数 | > 90% |
| 路由缓存命中率 | 路由缓存命中次数 / 总路由匹配次数 | > 99% |
实践建议:在 CNI 环境中,优先关注 DNS 缓存命中率。因为 Pod IP 频繁变化,DNS 缓存过期是导致连接池重建和路由重匹配的根本原因。通过调整
dns_refresh_rate 和 dns_cache_circuit_breaker,可将 DNS 缓存命中率从 70% 提升至 95% 以上。