上一篇
http怎么缓存数据库
- 行业动态
- 2025-04-26
- 3
HTTP无法直接缓存数据库,需通过应用层(如Redis)缓存查询结果,结合HTTP缓存头(如ETag)控制数据有效性,设置过期策略保障数据
HTTP缓存与数据库交互优化方案
HTTP缓存基础原理
头部字段 | 作用描述 |
---|---|
Cache-Control | 定义缓存策略(max-age=3600表示1小时有效) |
ETag | 资源版本标识(基于内容哈希值) |
Last-Modified | 资源最后修改时间 |
Pragma | 特殊指令(如”no-cache”强制验证) |
Expires | 绝对过期时间(如Expires: Wed, 21 Oct 2023 07:28:00 GMT) |
数据库查询结果缓存策略
应用层缓存:
- 使用Redis/Memcached存储SQL查询结果
- 示例:
SELECT FROM users WHERE id=1
→ 缓存键user:1
- 设置合理过期时间(如5分钟)
HTTP响应缓存:
# Flask示例 from flask import Flask, jsonify, make_response app = Flask(__name__) @app.route('/api/user/<int:id>') def get_user(id): response = make_response(jsonify(db.query("SELECT FROM users WHERE id=%s", id))) response.headers['Cache-Control'] = 'public, max-age=300' # 5分钟缓存 return response
反向代理缓存:
- Nginx配置示例:
location /api/ { proxy_pass http://backend; proxy_cache my_cache; proxy_cache_valid 200 1h; # 200状态码缓存1小时 }
- Nginx配置示例:
缓存更新机制
场景类型 | 处理方案 |
---|---|
数据新增/修改 | 删除对应缓存键(如Redis DEL user:1) |
批量更新 | 使用缓存标记模式(如Redis设置data_version:20231021 ) |
紧急失效 | 客户端添加Pragma: no-cache 强制跳过缓存 |
缓存粒度控制
粗粒度缓存:
- 整个页面/接口结果缓存(适合很少变化的数据统计页面)
- 风险:可能导致数据不一致
细粒度缓存:
- 分模块缓存(如用户信息+订单数据分开缓存)
- 示例:
GET /dashboard
→ 合并user_info
+order_stats
两个缓存结果
缓存穿透防护
# Redis缓存空值示例 def get_user(user_id): cache_key = f"user:{user_id}" data = redis.get(cache_key) if data: return json.loads(data) # 查询数据库 result = db.query("SELECT FROM users WHERE id=%s", user_id) if not result: # 缓存空值(设置短过期时间防止攻击) redis.setex(cache_key, 60, '{}') return None # 正常缓存 redis.setex(cache_key, 300, json.dumps(result)) return result
相关问题与解答
Q1:缓存过期时间如何设置比较合理?
- 高频访问数据:5-15分钟
- 低频变化数据:30分钟-2小时
- 实时性要求高:<1分钟(需结合更新机制)
- 建议采用分层过期策略:基础缓存1小时 + 热点数据单独延长
Q2:如何验证缓存是否生效?
- 使用开发者工具查看响应头:
Age
字段显示缓存存活时间X-Cache-Status
(如Varnish)显示HIT/MISS
- 强制刷新验证:
- Chrome按
Ctrl+F5
或Cmd+Shift+R
- 观察网络请求是否包含
If-None-Match
等条件请求头
- Chrome按
- 日志分析:
- 检查Redis/Memcached命中率统计
- 查看Nginx/Apache缓存日志