单台Nginx缓存本地独占,集群节点默认不共享;可行方案有二:一是用Redis等集中式缓存替代proxy_cache,统一读写与键构造;二是构建CDN+Nginx+后端的多级缓存链,或通过一致性哈希路由使相同请求固定落至同一Nginx节点。

单台 Nginx 的缓存是本地独占的,集群中各节点默认互不共享缓存——请求打到不同机器,就得各自回源、各自建缓存,既浪费后端资源,又降低整体命中率。真正提升大规模访问响应速度,关键不是“堆机器”,而是让缓存协同起来。实际可行路径有两条:一种是绕过节点级缓存,用集中式缓存层统一承接;另一种是在架构设计上规避对节点缓存一致性的强依赖。
用 Redis 或 Memcached 替代 Nginx 本地 proxy_cache
这是最直接、最可控的共享方案。Nginx 本身不支持跨节点缓存同步,但可通过 ngx_http_redis_module 或 lua-resty-redis(配合 OpenResty)将缓存读写导向外部内存数据库:
- 所有 Nginx 实例都连接同一套 Redis 集群,缓存键统一按
$host$uri$is_args$args构造,内容存为序列化响应体 + 状态码 + 头部信息 - 请求进来时,先查 Redis;命中则组装响应头(如
Content-Type、Cache-Control)并直接返回;未命中则转发后端,再将结果写入 Redis - 适合缓存粒度较粗、更新不频繁的内容,比如 API 接口返回的 JSON、静态 HTML 页面、商品详情页等
分层缓存:Nginx 本地缓存 + CDN 边缘缓存
不追求“完全共享”,而是构建多级缓存链,让高频请求在更靠近用户的层级被拦截:
- 第一层:CDN(如 Cloudflare、阿里云 DCDN),配置 TTL 和缓存规则,覆盖 70%+ 的静态资源和部分动态 HTML
- 第二层:Nginx 节点启用
proxy_cache,但只缓存 CDN 回源失败或需特殊处理的请求(例如带特定 header 的管理接口) - 第三层:后端服务自身加一层本地缓存(如 Guava Cache)或分布式缓存(如 Caffeine + Redis 双写)
- 这种结构天然具备“共享”效果——CDN 节点全球分布,用户无论落到哪个边缘节点,只要 URL 相同,就可能命中同一份缓存
避免缓存共享依赖:无状态路由 + 内容哈希分发
如果业务允许,可从请求入口就控制缓存分布逻辑,让相同请求始终落在同一台 Nginx 上,变相实现“伪共享”:
- 在负载均衡器(如 LVS、HAProxy 或云厂商 SLB)启用一致性哈希(
hash $request_uri consistent),使相同 URI 始终调度到固定后端 Nginx - 配合 Nginx 的
proxy_cache_lock on和proxy_cache_lock_age,防止缓存穿透时多个请求同时回源 - 适用于 URL 具有强规律性、且缓存 key 稳定的场景,比如图片服务
/img/{hash}.jpg、前端资源/static/v1.2.3/app.js
注意哪些内容不适合走共享缓存
共享缓存一旦误存敏感或个性化内容,后果比单机更严重:
- 含
Set-Cookie、Authorization、Cookie: session_id=...的响应必须跳过缓存,可用proxy_cache_bypass和proxy_no_cache控制 - POST/PUT/DELETE 请求默认不缓存;若需缓存,务必显式设置
proxy_cache_methods GET HEAD POST并严格校验幂等性 - 动态页面(如用户中心、订单列表)应通过 URL 参数、请求头或 Cookie 标识用户身份,并在缓存 key 中加入该标识,否则会导致 A 用户看到 B 用户的数据
不复杂但容易忽略:缓存共享的价值不在“技术炫酷”,而在减少重复计算与 IO。选 Redis 是为了强一致性,选 CDN 是为了广覆盖,选哈希路由是为了低延迟——根据你的流量特征、更新频率和数据敏感度,挑一条最稳的路走就行。











