Redis 实战教程

你是不是还在吐槽Web应用查询慢、偶尔Session丢、甚至电商超售超订?今天带大家从「0安装」到「Python高频场景落地」,用轻量高效的方案解决这些问题!


什么是Redis?

Redis(Remote Dictionary Server)是一个开源的内存优先数据结构存储系统,可以同时当缓存、半持久化数据库、轻量消息中间件用。它最大的特点是支持比普通键值多太多的结构化操作,能帮我们用Redis原生命令快速实现复杂逻辑,不用在应用层写一堆代码。

简单列几个生产级常用特点:

  • 毫秒级响应:全内存存储,单节点读写可达10万/秒+
  • 数据半落地:RDB(定时快照)+ AOF(增量日志)双持久化,兼顾速度和安全
  • 主从/哨兵/集群全覆盖:从读写分离到高可用,再到分布式横向扩容
  • Lua脚本原子操作:解决超卖、计数一致性的神器

1. 3步快速安装Redis

1.1 推荐方案:Docker一键启动

不管你是Windows、Mac还是Linux,Docker都能避免环境依赖问题:

# 1. 拉取官方稳定版(LTS最新通常选7.x以上)
docker pull redis:7-alpine

# 2. 后台启动,绑定本地6379端口,开启持久化
docker run -d \
  --name my-redis-dev \
  -p 6379:6379 \
  -v redis-data-dev:/data \
  redis:7-alpine \
  redis-server --appendonly yes

# 3. 测试连接
docker exec -it my-redis-dev redis-cli ping
# 输出PONG就成功了!

1.2 备用:WSL/Ubuntu原生

如果不习惯Docker,用WSL 2 Ubuntu/Debian安装:

sudo apt update && sudo apt install -y redis-server
sudo systemctl enable --now redis-server
redis-cli ping  # 测试

2. 高频Redis数据类型速览(附代码)

Redis的核心不是“存键值”,而是用对应的数据结构解决对应问题!下面只列生产中80%场景会用到的类型:

2.1 字符串(String):万金油

存单个值、计数器、临时token都能用:

# 设置带过期时间的token(NX=仅不存在时设,EX=过期秒数)
SET token:user:1000 "abc123xyz" EX 3600 NX

# 获取token
GET token:user:1000

# 原子自增(电商库存、日活统计)
INCR daily:active:users
INCRBY product:stock:2024 5  # 补5件库存

2.2 哈希(Hash):存对象更省内存

代替“user:1000:name=xx”这种散列的字符串键,节省约30-50%的内存:

# 设置用户信息
HSET user:profile:1000 name "道满Python" role "博主" age 28

# 批量获取指定字段
HMGET user:profile:1000 name role

# 只获取某个字段
HGET user:profile:1000 age

2.3 列表(List):轻量队列/栈

用LPUSH/RPUSH+BRPOP/BLPOP实现阻塞式消息队列,完全不用引入RabbitMQ/Kafka这种重量级中间件:

# 模拟生产者:左侧推入待处理订单
LPUSH orders:todo "order:20240501001" "order:20240501002"

# 模拟消费者:右侧阻塞等待订单(0=永久等待)
BRPOP orders:todo 0

2.4 有序集合(Sorted Set):自动排行榜

按分数(比如点赞数、分数、时间戳)自动排序,无需应用层操作:

# 发布文章并设置初始点赞数
ZADD article:likes 0 "article:20240501001"

# 点赞+1(ZINCRBY自动更新排序)
ZINCRBY article:likes 1 "article:20240501001"

# 获取点赞数前3的文章(带分数,倒序)
ZREVRANGE article:likes 0 2 WITHSCORES

3. Python与Redis无缝集成

生产环境推荐用官方维护的 redis 库,支持同步/异步:

3.1 安装与基础连接

# 安装同步/异步通用库
pip install redis redis[hiredis]  # hiredis是C加速解析器,性能翻倍
import redis
# 同步基础连接(自动解码响应,避免bytes转str)
r = redis.Redis(
    host="localhost",
    port=6379,
    db=0,
    decode_responses=True,
    socket_timeout=5  # 超时避免卡死
)
print(r.ping())  # 测试

3.2 高频Python场景1:接口缓存

写个装饰器就能给任意同步/异步接口加Redis缓存,避免频繁查库:

import json
from functools import wraps

# 同步装饰器
def sync_cache(expire=300):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            # 生成唯一缓存键(要考虑参数顺序)
            key = f"cache:{func.__name__}:{hash(repr(args)+repr(sorted(kwargs.items())))}"
            cached = r.get(key)
            if cached:
                return json.loads(cached)
            # 查库并缓存
            res = func(*args, **kwargs)
            r.setex(key, expire, json.dumps(res, ensure_ascii=False))
            return res
        return wrapper
    return decorator

# 测试装饰器
@sync_cache(expire=600)
def get_user_profile(user_id: int):
    print("=== 模拟数据库查询 ===")
    return {"id": user_id, "name": "道满Python", "role": "博主"}

print(get_user_profile(1000))  # 第一次查库
print(get_user_profile(1000))  # 第二次走缓存

3.3 高频Python场景2:超卖原子锁

用Lua脚本+SET NX EX解决电商秒杀、预约挂号的超卖问题,保证原子性:

import uuid

# Lua脚本:检查库存>0 → 扣减库存 → 返回扣减结果
LUA_DEDUCT_STOCK = """
local stock = tonumber(redis.call('GET', KEYS[1]))
if stock and stock >= tonumber(ARGV[1]) then
    redis.call('DECRBY', KEYS[1], tonumber(ARGV[1]))
    return 1  -- 成功
end
return 0  -- 失败
"""

def deduct_stock(product_id: int, count: int = 1):
    key = f"product:stock:{product_id}"
    # 加载脚本(缓存后SHA执行更快)
    sha = r.script_load(LUA_DEDUCT_STOCK)
    try:
        res = r.evalsha(sha, 1, key, count)
        return res == 1
    except Exception as e:
        # 如果脚本过期(比如重启Redis),重新加载
        print(f"脚本过期,重新加载:{e}")
        return deduct_stock(product_id, count)

# 测试
r.set("product:stock:2024", 3)  # 初始3件库存
for _ in range(5):  # 5个请求
    print(f"秒杀{'成功' if deduct_stock(2024) else '失败'}")

4. Redis小技巧避坑

4.1 键命名规范

团队统一规范避免混乱,推荐用 业务:模块:资源ID 的冒号分层:

✅ session:user:1000
✅ cache:article:list:page1
✅ product:stock:2024
❌ a123456(无业务含义)
❌ User_Profile-1000(符号混用)

4.2 慢查询监控

生产环境用 SLOWLOG GET 10 查最近10条超过指定时间的命令,默认超过10000微秒(10ms)记录:

# 临时设置慢查询阈值为5ms(生产建议永久改配置文件)
CONFIG SET slowlog-log-slower-than 5000

总结

Redis是一款轻量但功能爆炸的工具,只要选对数据结构,就能用最少的代码解决最棘手的性能问题。今天我们学了:

  1. Docker一键启动开发环境
  2. 4种高频数据结构的用法
  3. Python加接口缓存、超卖原子锁的完整代码
  4. 生产避坑的小技巧

如果想深入学习,可以看后面的「哨兵模式/集群模式」和「内存优化」内容!