Redis 项目实战分析

Redis 项目实战分析


1.1 项目实战一:百万 PV 新闻网站缓存架构

✅ 背景

某新闻网站日均访问量达百万级,文章访问量极不均衡(80/20 法则),对热点文章访问频繁,需设计高性能缓存方案。

📌 关键目标

  • 缓存热点新闻,减轻 DB 压力
  • 页面缓存 + 数据缓存结合
  • 缓存过期与更新机制

📦 架构设计

缓存层 说明 技术选型
页面缓存 对静态页面直接缓存 Nginx + Redis
数据缓存 查询 DB 前先查 Redis Redis
热点预热 发布文章时提前缓存热点 后台管理逻辑

🧠 代码示例(Python,使用 Flask 框架)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from flask import Flask, jsonify
import redis
import time

app = Flask(__name__)
r = redis.Redis(host='localhost', port=6379, decode_responses=True)

def get_article_from_db(article_id):
# 模拟数据库查询
time.sleep(0.5)
return {"id": article_id, "title": f"文章{article_id}", "content": "这是一篇内容丰富的文章。"}


@app.route("/article/<int:article_id>")
def get_article(article_id):
key = f"article:{article_id}"
article = r.get(key)
if article:
return jsonify({"source": "cache", "data": eval(article)})

# 缓存未命中,访问 DB
article = get_article_from_db(article_id)
r.setex(key, 300, str(article)) # 缓存 5 分钟
return jsonify({"source": "db", "data": article})

if __name__ == "__main__":
app.run(debug=True)

💡 缓存更新策略

  • 发布/修改文章后,后台自动刷新 Redis 中对应的 key。
  • 对热点文章列表定时进行预热(job 脚本自动执行)。

1.2 项目实战二:高并发电商抢购系统

✅ 背景

秒杀活动中,用户瞬间涌入,需要保障商品不被超卖、服务不被打垮。


📌 技术关键点

问题 解决方案
库存扣减一致性 Redis 原子操作
接口幂等性 防止重复请求
并发控制 限流 + 排队机制

🧠 示例代码:Redis 原子扣库存(Python)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from flask import Flask, request, jsonify
import redis

app = Flask(__name__)
r = redis.Redis(host='localhost', port=6379, decode_responses=True)

@app.route("/buy", methods=["POST"])
def buy_item():
user_id = request.form["user_id"]
product_id = request.form["product_id"]
key = f"stock:{product_id}"
user_key = f"purchased:{product_id}:{user_id}"

# 避免重复下单
if r.exists(user_key):
return jsonify({"status": "fail", "msg": "重复下单"})

# 扣减库存
with r.pipeline() as pipe:
while True:
try:
pipe.watch(key)
stock = int(pipe.get(key) or 0)
if stock > 0:
pipe.multi()
pipe.decr(key)
pipe.set(user_key, 1)
pipe.expire(user_key, 3600)
pipe.execute()
return jsonify({"status": "success", "msg": "购买成功"})
else:
pipe.unwatch()
return jsonify({"status": "fail", "msg": "已售罄"})
except redis.WatchError:
continue

if __name__ == "__main__":
r.set("stock:1001", 100) # 初始化库存
app.run()

1.3 项目实战三:消息中心与延时任务系统

✅ 背景

电商平台需要给用户发送短信/站内信/推送等消息,同时支持延迟通知(如:1 小时后提醒付款)。


📌 技术设计

功能 方案
延时消息调度 Redis ZSET
多级优先队列 队列优先级划分
失败重试机制 失败任务重新入队

🧠 延时队列实现(ZSET)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import redis
import time
import json

r = redis.Redis(host='localhost', port=6379, decode_responses=True)
DELAY_QUEUE = "delay:queue"

# 推送延时任务
def push_delay_task(task_id, delay_seconds):
timestamp = int(time.time() + delay_seconds)
task_data = {"id": task_id, "type": "sms", "msg": "请尽快完成支付"}
r.zadd(DELAY_QUEUE, {json.dumps(task_data): timestamp})
print("推送任务成功")

# 消费任务
def consume_delay_task():
while True:
now = int(time.time())
items = r.zrangebyscore(DELAY_QUEUE, 0, now, start=0, num=1)
if not items:
time.sleep(1)
continue
for item in items:
print("处理任务:", item)
r.zrem(DELAY_QUEUE, item)

if __name__ == "__main__":
# 示例:推送任务
push_delay_task("task_001", delay_seconds=10)

# 消费任务
consume_delay_task()

🔚 附录

✅ Redis 命令速查表(部分)

功能 命令 示例
设置键值 SET SET user:1 "Tom"
获取键值 GET GET user:1
增加数值 INCR INCR page:view
有序集合加分 ZINCRBY ZINCRBY rank 10 "user1"

🔍 Redis 可视化工具推荐

工具 特点
RedisInsight 图形化分析、键空间管理
RDM 跨平台、支持 SSH 连接
Medis macOS 优雅 Redis GUI

⚠ Redis 实战坑点与建议

  • 热点 key 分布不均:引入本地缓存或按用户打散 key。
  • keys 命令造成阻塞:避免线上使用,替换为 scan
  • AOF 日志膨胀:定期重写(rewrite)。
  • 慢查询拖垮主线程:开启 slowlog 并监控。

Redis 项目实战分析
https://dreamshao.github.io/2025/07/22/redis项目实战分析/
作者
Yun Shao
发布于
2025年7月22日
许可协议