Skip to main content

缓存

一、浏览器端缓存:减少重复请求

  1. HTTP 缓存策略 强缓存(Cache-Control/Expires) 通过 Cache-Control: max-age=31536000 设定资源缓存时间,浏览器直接从本地读取,无需发起请求。 兼容旧版本可使用 Expires 字段(如 Expires: Thu, 31 Dec 2025 23:59:59 GMT)。 协商缓存(ETag/Last-Modified) 服务器通过 ETag(文件指纹)或 Last-Modified(修改时间)判断资源是否更新: 若未更新,返回 304 Not Modified,浏览器复用本地缓存; 若更新,返回 200 OK 及新资源。
  2. 本地存储(LocalStorage/IndexedDB) LocalStorage:持久化存储静态数据(如配置项、用户信息),适用于 5MB 以内数据。 IndexedDB:大容量异步数据库,适合缓存大量结构化数据(如离线表格、历史记录),可结合 Service Worker 实现离线访问。
  3. Service Worker 缓存(PWA) 拦截 HTTP 请求,将资源缓存至浏览器本地,实现离线访问或快速加载(如首页骨架屏、静态资源预缓存)。 二、CDN 缓存:加速静态资源访问
  4. 静态资源托管 将图片、CSS、JS、字体等静态资源部署到 CDN,利用全球节点缓存,减少源站负载和用户访问延迟。 配置示例: 为图片设置长缓存:Cache-Control: max-age=31536000; 版本更新时通过 URL 参数(如 style.css?v=2.0)强制刷新缓存。
  5. 动态内容缓存(部分 CDN 支持) 对动态页面(如新闻详情页)的 HTML 片段进行缓存,根据 URL 参数、Cookie 等条件设置缓存规则(需谨慎使用,避免内容不一致)。 三、服务器端缓存:减少应用层计算
  6. 反向代理缓存(Nginx/Apache) Nginx 缓存配置:
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g;
server {
location / {
proxy_cache my_cache;
proxy_cache_valid 200 304 1d; # 200/304响应缓存1天
proxy_cache_key $host$uri$is_args$args; # 缓存键规则
}
}

缓存动态接口响应(如商品列表),减少应用服务器压力。 2. 应用层缓存(Redis/Memcached) 热点数据缓存: 将高频查询数据(如商品详情、用户信息)存入 Redis,避免重复查询数据库。 示例(Node.js + Redis):

// 读取缓存,若无则查询数据库并写入缓存
const cacheKey = `product:${id}`;
const cachedData = await redis.get(cacheKey);
if (cachedData) return JSON.parse(cachedData);

const data = await db.query(`SELECT * FROM products WHERE id=${id}`);
await redis.setex(cacheKey, 3600, JSON.stringify(data)); // 缓存1小时
return data;

缓存策略: 过期时间:根据数据更新频率设置(如商品信息缓存 10 分钟,配置信息缓存 1 天); 缓存淘汰:使用 LRU(最近最少使用)、LFU(最少频率使用)策略释放内存。 3. 本地缓存(应用服务器内存) 对极小范围高频数据(如用户登录状态、当前在线人数)使用本地内存缓存(如 Java 的 Guava Cache、Node.js 的内存对象),避免远程缓存访问开销。 四、数据库层缓存:减少磁盘 IO

  1. 数据库自带缓存 MySQL 查询缓存: 开启 query_cache_type=1,缓存 SELECT 语句结果,下次相同查询直接返回缓存(需注意表更新时缓存自动失效)。 InnoDB 缓冲池(Buffer Pool): 缓存表数据和索引到内存,减少磁盘读取。可通过 innodb_buffer_pool_size 配置(建议设为物理内存的 50%~70%)。
  2. Redis 作为数据库缓存中间层 读写分离缓存: 读请求先查 Redis,无数据再查数据库并写入缓存; 写请求更新数据库后,同步删除 Redis 缓存(避免脏数据)。 缓存穿透与击穿解决方案: 缓存穿透(恶意请求不存在的数据):用布隆过滤器(Bloom Filter)预判断数据是否存在; 缓存击穿(热点 key 过期瞬间大量请求):加互斥锁(如 Redis 的 SET NX)保证同一时间只有一个请求查询数据库。 五、缓存一致性与风险控制
  3. 缓存更新策略 主动更新:数据变更时同步更新 / 删除缓存(如订单状态变更后删除相关缓存)。 被动失效:缓存设置过期时间,下次访问时自动刷新(适合非实时数据)。
  4. 缓存雪崩应对 分散过期时间:给缓存键添加随机过期时间(如 3600+Math.random()*600 秒),避免大量缓存同时失效; 缓存降级:当缓存服务故障时,直接访问数据库并开启限流,防止数据库被压垮。 六、链路缓存效果对比 缓存层级 缓存位置 响应速度 数据一致性 适用场景 浏览器缓存 客户端本地 最快(ms 级) 低(需协商更新) 静态资源(JS/CSS/ 图片) CDN 缓存 边缘节点 次快 中 全国用户访问的静态资源 反向代理缓存 服务器前端 较快 中 动态接口的公共数据 应用层缓存 应用服务器内存 快 高(需主动更新) 高频查询的热点数据 数据库缓存 数据库内存 较慢 最高 核心数据的持久化存储

通过多层级缓存策略的协同,可显著降低链路中的网络延迟和数据库压力,提升系统吞吐量。实际应用中需根据业务场景平衡缓存效率与数据一致性,避免过度缓存导致的维护成本。