Skip to content

缓存

Ingress 支持缓存以提高性能并减少后端服务的负载。您可以使用内存缓存或 Redis 进行分布式缓存。

两层含义: 顶层 cache 配置共享的 ctx.Cache() 引擎(匹配器、DNS 等)。可选的每条 backend.cache 在开启时把 HTTP 响应写入同一引擎——详见下文

缓存配置

内存缓存

默认情况下,Ingress 使用内存缓存:

yaml
cache:
  ttl: 30  # 缓存 TTL(秒)(默认:60)

这会在内存中缓存路由决策和其他数据。缓存是每个 Ingress 实例本地的。

Redis 缓存

要在多个 Ingress 实例之间进行分布式缓存,请使用 Redis:

yaml
cache:
  ttl: 30
  engine: redis
  host: 127.0.0.1
  port: 6379
  password: '123456'
  db: 2
  prefix: ingress:

配置字段

字段类型描述默认值
ttlint缓存 TTL(秒)60
enginestring缓存引擎:memoryredismemory
hoststringRedis 主机(用于 Redis 引擎)127.0.0.1
portintRedis 端口(用于 Redis 引擎)6379
passwordstringRedis 密码(用于 Redis 引擎)-
dbintRedis 数据库编号(用于 Redis 引擎)0
prefixstring缓存键前缀(用于 Redis 引擎)-

缓存 TTL

ttl(生存时间)确定缓存项保持有效的时间:

yaml
cache:
  ttl: 30  # 缓存项在 30 秒后过期
  • 较短的 TTL:数据更新,但后端请求更多
  • 较长的 TTL:后端请求更少,但数据可能过时

为您的用例选择在新鲜度和性能之间取得平衡的 TTL。

内存缓存

内存缓存是最简单的选项,适用于单实例部署:

yaml
cache:
  ttl: 60

优点:

  • 无外部依赖
  • 快速访问
  • 简单配置

缺点:

  • 不在实例之间共享
  • 重启时丢失
  • 受可用内存限制

Redis 缓存

Redis 缓存推荐用于多实例部署或需要持久缓存时:

yaml
cache:
  ttl: 60
  engine: redis
  host: redis.example.com
  port: 6379
  password: your-password
  db: 0
  prefix: ingress:

Redis 配置

  • host:Redis 服务器主机名或 IP 地址
  • port:Redis 服务器端口(默认:6379)
  • password:Redis 密码(可选,如果没有密码则省略)
  • db:Redis 数据库编号(0-15,默认:0)
  • prefix:所有缓存键的前缀(用于命名空间)

Redis 连接

Ingress 在启动时连接到 Redis。如果 Redis 不可用:

  • Ingress 将记录错误
  • 它可能会回退到内存缓存(取决于配置)
  • 健康检查可能会失败

Redis 键格式

使用前缀时,缓存键格式为:

{prefix}{key}

例如,使用 prefix: ingress:,主机路由键 match.host:v2:example.com 变为 ingress:match.host:v2:example.com。HTTP 响应缓存键形如 ingress:httpcache:v1:<摘要>。其中 v2 表示匹配器缓存值结构版本,后续版本可能调整。

缓存内容

Ingress 缓存:

  1. 路由决策:主机和路径匹配结果
  2. 服务配置:解析的服务配置
  3. DNS 解析:解析的后端服务地址
  4. HTTP 响应(可选):某条 backend.cache.enabled: true 时,满足条件的 GET/HEADservice / handler / redirect 响应可写入同一 ctx.Cache() 后端——见 HTTP 响应缓存(backend.cache

缓存路由决策在以下情况下特别有益:

  • 您有复杂的路由规则
  • DNS 解析很慢
  • 后端服务发现成本很高

HTTP 响应缓存(backend.cache

与顶层 cache 不同:根 cache 只选择 ctx.Cache()Redis 还是内存 及连接参数。backend.cache 写在 rules[].backendpaths[].backend 下,按路由生效。

cache.enabled: true 时:

  • service:在缓冲完整上游响应后,可对 客户端 GET 填充共享缓存键;HEAD 可命中同一条目。
  • handler:静态响应在通过存储规则(无 Vary、体量上限等)时可缓存。
  • redirect:URL 模板展开后,可缓存最终状态码与 Location(GET 存储路径)。

为何不存某些响应: 默认 不缓存带非空 Vary 的响应(未按 Vary 拆子键)。若 cache.skip_vary: true,则写入/命中时不保留不下发 Vary。另:在 skip_when_set_cookie: true(默认)时会跳过含 Set-Cookie 的响应。许多 httpbin 接口带 Vary: Origin;若可接受「单变体」共享缓存,可显式开启 skip_vary(见 配置说明)。

按路径规则(backend.cache.paths

配置了 paths 时,Ingress 按列表顺序匹配(先匹配先生效)。每条规则可对路径 cachebypass HTTP 响应缓存;未命中任何规则的路径遵循 defaultcachebypass;默认 cache)。规则上可选 ttlmax_body_bytes 覆盖 backend 默认值。省略 paths 时与旧行为一致:该 backend 下所有路径在 enabled: true 时参与缓存。

POST + JSON 缓存键(key_json

针对用 POST + JSON 做查询的遗留接口,应在 cache.paths 白名单路径上开启,不要在全局 cache.methods 写 POST:

  • 建议 default: bypass,仅列出的 API 走缓存。
  • 路径规则上配置 methods: [POST]key_json: [点分路径](如 product.id)。body 里多余的 timestamptraceId 等不参与指纹。
  • 顶层 cache.methods 不得包含 POST(校验报错)。
  • 配置了 key_json 时使用缓存键前缀 httpcache:v2:(仅 GET 的规则仍为 httpcache:v1:)。
  • 读取 body 算键后会 克隆并回放 给上游,不影响反代。
  • 以下情况 跳过缓存(直接回源):非 JSON、解析失败、任一 key_json 缺失或非标量、body 超过 key_body_max_bytes(配置 key_json 时默认 65536)、或 {} 且必填字段缺失。

service 在允许的方法(含 POST)下可按既有规则 写入 上游响应缓存;redirect 的填充仍仅 GET

字段、绕过规则与默认值见 配置参考 — backend.cache。可运行示例:examples/advanced/http-response-cache.yaml、Redis:examples/advanced/redis-cache.yaml、路径规则:examples/advanced/http-response-cache-paths.yaml、POST + JSON:examples/advanced/http-response-cache-post-json.yaml

缓存失效

缓存条目在以下情况下自动失效:

  1. TTL 过期:条目在配置的 TTL 后过期
  2. 配置重新加载Reload 会执行 prepare(),并清空已配置的缓存后端(与启动时一致),因此重载后会清除旧条目;若依赖外部缓存工具,仍建议结合 TTL 做渐进失效。
  3. 手动失效:某些缓存条目可能在特定事件上失效

缓存性能

监控缓存性能

您可以通过以下方式监控缓存性能:

  • 缓存命中率:从缓存提供服务的请求百分比
  • 缓存未命中率:需要后端查找的请求百分比
  • 缓存大小:缓存中的项目数(用于内存)

优化缓存性能

  1. 调整 TTL:在新鲜度和性能之间找到正确的平衡
  2. 多实例使用 Redis:在实例之间共享缓存
  3. 监控缓存使用:跟踪命中/未命中率
  4. 设置适当的前缀:使用前缀组织缓存键

最佳实践

  1. 选择正确的引擎:单实例使用内存,多实例使用 Redis
  2. 设置适当的 TTL:在新鲜度和性能之间取得平衡
  3. 使用 Redis 前缀:命名空间缓存键以避免冲突
  4. 监控 Redis:确保 Redis 可用且性能良好
  5. 保护 Redis:为 Redis 使用密码和网络安全
  6. 规划缓存未命中:设计系统以优雅地处理缓存未命中

故障排除

缓存不工作

  • 验证缓存配置是否正确
  • 检查 TTL 是否设置适当
  • 确保 Redis 可访问(如果使用 Redis)
  • 检查日志中的缓存相关错误

Redis 连接问题

  • 验证 Redis 主机和端口是否正确
  • 检查到 Redis 的网络连接
  • 验证 Redis 密码(如果需要)
  • 确保 Redis 正在运行且可访问

高缓存未命中率

  • 考虑增加 TTL
  • 检查路由规则是否过于动态
  • 验证缓存是否实际被使用
  • 审查缓存键模式

内存使用(内存缓存)

  • 监控内存使用
  • 如果内存受限,考虑减少 TTL
  • 切换到 Redis 以更好地管理内存
  • 审查缓存的内容

Released under the MIT License.