目录
[1. Redis简介与核心概念](#1. Redis简介与核心概念)
[1.1 什么是Redis?](#1.1 什么是Redis?)
[1.2 安装与连接](#1.2 安装与连接)
[2. Redis配置文件精要](#2. Redis配置文件精要)
[📋 配置文件记忆表](#📋 配置文件记忆表)
[3. 键管理:Redis的钥匙串](#3. 键管理:Redis的钥匙串)
[🔑 键操作记忆表](#🔑 键操作记忆表)
[4. 数据类型详解与应用场景](#4. 数据类型详解与应用场景)
[4.1 字符串(String) - 最简单的存储](#4.1 字符串(String) - 最简单的存储)
[4.2 哈希(Hash) - 对象存储专家](#4.2 哈希(Hash) - 对象存储专家)
[4.3 列表(List) - 消息队列能手](#4.3 列表(List) - 消息队列能手)
[4.4 集合(Set) - 唯一性保障者](#4.4 集合(Set) - 唯一性保障者)
[4.5 有序集合(Sorted Set) - 排行榜专家](#4.5 有序集合(Sorted Set) - 排行榜专家)
[5. 实战:Redis缓存MySQL数据](#5. 实战:Redis缓存MySQL数据)
[🛡️ 缓存问题解决方案记忆表](#🛡️ 缓存问题解决方案记忆表)
[6. 主从复制配置](#6. 主从复制配置)
[7. 最佳实践总结](#7. 最佳实践总结)
[🎯 使用场景快速选择指南](#🎯 使用场景快速选择指南)
[💡 性能优化建议](#💡 性能优化建议)
1. Redis简介与核心概念
1.1 什么是Redis?
Redis(Remote Dictionary Server)是一个开源的内存键值数据库 ,支持多种数据结构,以其高性能、低延迟著称。它通常用作:
- 🚀 缓存系统
- 💬 消息队列
- 📊 实时数据分析
- 🎯 会话存储
1.2 安装与连接
# 安装Redis Python客户端
pip install redis
python
import redis
# 创建连接池(推荐生产环境使用)
pool = redis.ConnectionPool(
host='localhost',
port=6379,
decode_responses=True # 自动解码为字符串
)
r = redis.Redis(connection_pool=pool)
# 测试连接
print("连接成功!" if r.ping() else "连接失败!")
2. Redis配置文件精要
📋 配置文件记忆表
配置项 | 默认值 | 作用 | 记忆口诀 |
---|---|---|---|
port |
6379 | 服务端口 | "6379"谐音"redis吃酒" |
bind |
127.0.0.1 | 绑定IP | "绑定谁就能访问" |
timeout |
0 | 客户端超时时间 | "0表示永不超时" |
databases |
16 | 数据库数量 | "16个数据库房间" |
save 900 1 |
- | 持久化规则 | "15分钟至少1次改" |
持久化规则解析:
python
save 900 1 # 15分钟(900秒)内至少1个更改 → 🕒 低频备份
save 300 10 # 5分钟内至少10个更改 → 🕒 中频备份
save 60 10000 # 1分钟内至少10000个更改 → 🕒 高频备份
3. 键管理:Redis的钥匙串
🔑 键操作记忆表
命令 | 作用 | 示例 | 记忆技巧 |
---|---|---|---|
exists |
检查key是否存在 | r.exists('user:1') |
"存在吗?" |
type |
获取key类型 | r.type('user:1') |
"什么类型?" |
expire |
设置过期时间 | r.expire('token', 3600) |
"1小时后过期" |
ttl |
查看剩余时间 | r.ttl('token') |
"还能活多久?" |
delete |
删除key | r.delete('temp:data') |
"扔掉钥匙" |
python
# 实际应用场景:用户会话管理
def manage_user_session(user_id, token):
session_key = f"session:{user_id}"
# 设置会话token,30分钟过期
r.setex(session_key, 1800, token)
# 检查会话是否有效
if r.exists(session_key) and r.ttl(session_key) > 0:
return "会话有效"
else:
return "会话已过期"
4. 数据类型详解与应用场景
4.1 字符串(String) - 最简单的存储
🎯 应用场景:缓存数据、计数器、分布式锁
python
# 计数器实现:文章阅读量统计
def article_view_counter(article_id):
key = f"article:views:{article_id}"
# 阅读量+1
views = r.incr(key)
# 每天凌晨重置,设置24小时过期
if r.ttl(key) == -1: # 没有设置过期时间
r.expire(key, 86400) # 24小时
return views
# 分布式锁实现
def acquire_lock(lock_name, timeout=10):
"""获取分布式锁"""
import time
lock_key = f"lock:{lock_name}"
# 使用setnx实现原子性加锁
while timeout > 0:
if r.setnx(lock_key, 1):
r.expire(lock_key, 5) # 5秒后自动释放
return True
time.sleep(0.1)
timeout -= 0.1
return False
4.2 哈希(Hash) - 对象存储专家
🎯 应用场景:用户信息、商品属性、配置存储
python
# 用户信息管理
def manage_user_profile(user_id, user_data):
user_key = f"user:{user_id}"
# 批量设置用户属性
r.hset(user_key, mapping=user_data)
# 设置整个用户对象的过期时间
r.expire(user_key, 3600) # 1小时过期
# 获取用户信息
profile = r.hgetall(user_key)
return profile
# 商品库存管理
def update_product_stock(product_id, quantity):
product_key = f"product:{product_id}"
# 使用hincrby原子性更新库存
remaining = r.hincrby(product_key, 'stock', quantity)
if remaining < 0:
# 库存不足,回滚操作
r.hincrby(product_key, 'stock', -quantity)
return "库存不足"
return f"更新成功,剩余库存: {remaining}"
4.3 列表(List) - 消息队列能手
🎯 应用场景:消息队列、最新消息、任务队列
python
# 简易消息队列实现
class SimpleMessageQueue:
def __init__(self, queue_name):
self.queue_key = f"queue:{queue_name}"
def push_message(self, message):
"""推送消息到队列"""
r.lpush(self.queue_key, json.dumps(message))
def pop_message(self, timeout=0):
"""从队列获取消息"""
if timeout > 0:
# 阻塞式获取
result = r.brpop(self.queue_key, timeout)
return json.loads(result[1]) if result else None
else:
# 非阻塞式获取
result = r.rpop(self.queue_key)
return json.loads(result) if result else None
# 使用示例
task_queue = SimpleMessageQueue('tasks')
task_queue.push_message({'type': 'email', 'to': 'user@example.com'})
4.4 集合(Set) - 唯一性保障者
🎯 应用场景:标签系统、好友关系、唯一计数器
python
# 标签系统实现
class TagSystem:
def add_tags(self, item_id, tags):
"""为物品添加标签"""
tags_key = f"item:tags:{item_id}"
# 添加多个标签(自动去重)
r.sadd(tags_key, *tags)
def get_common_tags(self, item1_id, item2_id):
"""获取两个物品的共同标签"""
key1 = f"item:tags:{item1_id}"
key2 = f"item:tags:{item2_id}"
return r.sinter(key1, key2)
# 用户投票系统(防止重复投票)
def user_vote(user_id, post_id):
voted_key = f"post:voted:{post_id}"
# 检查是否已经投过票
if r.sismember(voted_key, user_id):
return "已经投过票了"
# 记录投票用户
r.sadd(voted_key, user_id)
# 更新投票计数
r.hincrby(f"post:{post_id}", "votes", 1)
return "投票成功"
4.5 有序集合(Sorted Set) - 排行榜专家
🎯 应用场景:排行榜、优先级队列、时间线
python
# 游戏排行榜系统
class Leaderboard:
def update_score(self, player_id, score):
"""更新玩家分数"""
r.zadd('game:leaderboard', {player_id: score})
def get_top_players(self, limit=10):
"""获取前十名玩家"""
return r.zrevrange('game:leaderboard', 0, limit-1, withscores=True)
def get_player_rank(self, player_id):
"""获取玩家排名"""
# 返回排名(从0开始,所以+1显示实际名次)
return r.zrevrank('game:leaderboard', player_id) + 1
# 使用示例
leaderboard = Leaderboard()
leaderboard.update_score('player1', 1000)
leaderboard.update_score('player2', 1500)
top_players = leaderboard.get_top_players(5)
print("排行榜前5名:", top_players)
5. 实战:Redis缓存MySQL数据
🛡️ 缓存问题解决方案记忆表
问题 | 现象 | 解决方案 | 记忆口诀 |
---|---|---|---|
缓存雪崩 | 大量缓存同时失效 | 随机过期时间 | "雪崩来了随机躲" |
缓存穿透 | 查询不存在的数据 | 缓存空值 | "空值也要缓存住" |
缓存击穿 | 热点key突然失效 | 互斥锁 | "热点key要加锁" |
python
def get_user_with_cache(user_id):
"""带缓存的用户信息查询"""
cache_key = f"user:{user_id}"
# 1. 先查缓存
user_data = r.get(cache_key)
if user_data:
if user_data == "NULL": # 缓存空值
return None
return json.loads(user_data)
# 2. 缓存不存在,查数据库(加锁防止缓存击穿)
lock_key = f"lock:{cache_key}"
try:
# 尝试获取锁
if acquire_lock(lock_key):
# 查询数据库
user_data = query_database(f"SELECT * FROM users WHERE id = {user_id}")
if user_data:
# 缓存数据,设置随机过期时间(防雪崩)
import random
expire_time = 3600 + random.randint(0, 300) # 1小时±5分钟
r.setex(cache_key, expire_time, json.dumps(user_data))
else:
# 缓存空值,较短时间(防穿透)
r.setex(cache_key, 300, "NULL")
return user_data
else:
# 没获取到锁,等待重试
time.sleep(0.1)
return get_user_with_cache(user_id)
finally:
release_lock(lock_key)
6. 主从复制配置
python
# 主从配置示例
def setup_replication(master_host, master_port, slave_hosts):
"""
设置主从复制
master_host: 主服务器地址
slave_hosts: 从服务器列表
"""
for slave in slave_hosts:
# 在每个从服务器上执行 slaveof 命令
slave_client = redis.Redis(host=slave['host'], port=slave['port'])
slave_client.slaveof(master_host, master_port)
print(f"设置 {slave['host']} 为 {master_host} 的从库")
7. 最佳实践总结
🎯 使用场景快速选择指南
数据类型 | 适用场景 | 示例 | 选择理由 |
---|---|---|---|
String | 简单缓存、计数器 | 文章阅读量 | 简单快速 |
Hash | 对象存储 | 用户信息 | 结构化数据 |
List | 消息队列 | 任务队列 | 顺序处理 |
Set | 唯一集合 | 用户标签 | 自动去重 |
Sorted Set | 排行榜 | 游戏排名 | 带分数排序 |
💡 性能优化建议
- 合理设置过期时间:避免内存泄漏
- 使用批量操作:减少网络往返
- 避免大key:单个value不要超过1MB
- 使用连接池:避免频繁创建连接
- 监控内存使用:定期清理无用数据
📚 记忆口诀总结:
- "字符串最简单,哈希存对象"
- "列表做队列,集合保唯一"
- "有序集排序,缓存要过期"
- "雪崩随机躲,穿透缓存空"