快速上手Redis
一、认识Redis
Redis 是一个内存数据库,常用于缓存和高性能数据存储。特点:
- 数据存储在内存,读写速度快(毫秒级甚至微秒级)
- 支持多种数据结构:String、Hash、List、Set、Sorted Set(ZSet)
- 支持过期时间(TTL),可以当作缓存
- 支持 Pub/Sub 发布/订阅,适合实时消息
通俗来讲 Redis 就是一个超级升级版的键值对结构。
二、安装Redis
推荐使用Docker安装(方便快捷)
- 没有Docker可以访问官网(Docker: Accelerated Container Application Development)选择对应安装包进行下载。
- 需要注意的是:启动 Redis 容器是运行在 Docker 引擎上的,因此 Docker 程序不能退出;退出则所有容器都会关闭。
- 打开终端,执行以下命令
# 拉取最新 Redis 镜像dockerpull redis:latest# 启动 Redis 容器,映射本地 6379 端口dockerrun-d--namemy_redis-p6379:6379 redis# 测试 Redis 是否启动redis-cliping# 正常输出 PONGdocker run用来创建并启动容器,-d代表在后台运行,--name my_redis指定容器名字,
-p 6379:6379端口映射(本地 6379 连 Redis的6379),redis使用官方 Redis 镜像。
三、终端使用Redis
1. 找容器
继续在终端执行docker ps可以查看正在运行的 Redis 容器:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES abc123456789 redis"docker-…"2days ago Up2days0.0.0.0-6379 my_redis在以上输出中找到IMAGE为redis的行,并确认NAMES字段值和我们刚启动容器名相同。
2. 查数据
然后我们就可以记住容器 IDabc123456789或 容器名my_redis(二选一即可)
一条命令直接进入 Redis 命令行客户端
# 替换为你的容器名/IDdockerexec-itmy_redis redis-cli执行后会进入 Redis 交互模式(提示符变为127.0.0.1:6379>),直接输入查询命令即可。
- tip:
1. 默认数量
容器内的 Redis 默认创建16 个独立数据库,编号从0到15。
2. 默认数据库
你连接 Redis 时,默认自动进入 0 号库。
3. 隔离性
不同数据库之间数据完全隔离:在 0 库写的 key,在 1 库看不到,互不干扰。
2.1 基础查询命令
# 1. 查看当前数据库的所有 key(测试环境用,生产环境禁用)keys *# 2. 查看 Redis 所有数据库的 key 数量(默认16个库:0~15)info keyspace# 3. 切换数据库(比如切换到第1个库,默认在 0 库)select12.2 数据查询命令
# 先查看某个 key 的类型typemykey# ① 字符串类型(最常用)Stringget mykey# ② 哈希类型(存对象)Hashhgetall myhash# ③ 列表类型 Listlrange mylist0-1# 0 -1 表示查看所有元素# ④ 集合类型 Setsmembers myset# ⑤ 有序集合类型 ZSetzrange myzset0-13. 删除容器 / 清空数据
| 需求 | 命令 |
|---|---|
| 只清空内存数据(容器保留) | docker exec -it my_redis redis-cli flushall |
| 只删容器(数据保留) | docker rm -f my_redis |
| 彻底删容器 + 清空所有数据 | 执行上条命令 +删除 D:\my_redis-data 文件夹 |
四、python操作 Redis
在python中,FastAPI推荐使用redis
安装:
pipinstallredis连接 Redis:
importredis# 连接本地 Redisr=redis.Redis(host='localhost',port=6379,db=0,decode_responses=True)# 测试是否连接print(r.ping())# True 表示连接成功1. String 类型(键值对)
可以理解为键值对:
key -> value在项目中用来存用户登录 Token或游客临时数据
# 设置 key,过期 7 天r.set("user:session:1001","token_abc123",ex=7*24*60*60)# 获取 keytoken=r.get("user:session:1001")print(token)# 输出 token_abc123# 删除 keyr.delete("user:session:1001")解释:
user:session:1001是 key(用户 ID 对应的登录会话)"token_abc123"是 value(登录令牌)ex表示过期时间,这里 7 天
2. Hash 类型(字典)
可以理解为字典:一个 key 里存很多字段
在项目中用来存用户信息数据
user_id=1001# 创建用户状态r.hset(f"user:state:{user_id}",mapping={"name":"Li","status":1,"age":18})# 添加伙伴列表(字符串保存)r.hset(f"user:state:{user_id}","players","1002,1003")# 读取用户状态user_info=r.hgetall(f"user:state:{user_id}")print(user_info)# 输出 {'name': 'Li',, 'status': '1', 'age': '18', 'players': '1002,1003'}# 更新用户状态(无字段顺序要求)r.hset(f"user:state:{user_id}","status",2)# 修改一个字段r.hset(f"user:state:{user_id}",mapping={"status":2,"age":20,"players":"1001,1002,1003"})# 修改多个字段3. Set 类型(集合)
可以理解为集合:无序,自动去重
在项目中用来存一些唯一列表数据(玩家列表)
# 添加元素r.sadd("room:2001:players",1001)# 玩家 1001 加入房间r.sadd("room:2001:players",1002)# 玩家 1002 加入房间r.sadd("room:2001:players",1001)# 重复加入,不会报错,也不会重复存# 读取集合元素players=r.smembers("room:2001:players")print(players)# 输出 {'1001', '1002'},顺序不固定# 判断某元素是否在集合中is_in=r.sismember("room:2001:players",1001)print(is_in)# True# 删除元素r.srem("room:2001:players",1002)players=r.smembers("room:2001:players")print(players)# 输出 {'1001'}# 获取集合长度count=r.scard("room:2001:players")print(count)# 输出 14. ZSet(有序集合)
可以理解为排行榜:每个元素都有一个分数,Redis 会自动排序
在项目中用来存榜单数据
# 添加分数r.zadd("ranking:total:score",{"1001":5000,"1002":4800})# 获取前 3 名top3=r.zrevrange("ranking:total:score",0,2,withscores=True)print(top3)# 输出 [('1001', 5000), ('1002', 4800)]# 查询某用户排名rank=r.zrevrank("ranking:total:score","1001")print(rank+1)# 排名从 1 开始解释:
- ZSet 会按分数自动排序,
zrevrange从高分到低分取前 N 名
5. List(列表)
可以理解为一排排数据,可以从两头操作
在项目中用来做分数异步校验队列
# 入队r.lpush("game:score:check:queue","1001:5000:1683900000")# 出队score=r.rpop("game:score:check:queue")print(score)# 输出 "1001:5000:1683900000"6. Pub/Sub(发布/订阅)
用来做实时消息广播
在项目中用来聊天消息
# 订阅消息(频道)pubsub=r.pubsub()pubsub.subscribe("room:msg:2002")# 发布消息chat_msg={"type":"chat","userId":1001,"msg":"你好"}r.publish("room:msg:2002",json.dumps(chat_msg))# 循环监听频道中的消息formessageinpubsub.listen():# 过滤出用户发送的消息ifmessage["type"]=="message":# 解析 JSON 字符串data=json.loads(message["data"])# 过滤出聊天消息ifdata["type"]=="chat":print(f"用户{data['userId']}:{data['msg']}")解释:
subscribe订阅频道,所有订阅者都能收到消息publish发送消息到频道- 实时同步房间信息
五、Redis 持久化
在安装 Redis 一节中,我们使用docker run -d --name my_redis -p 6379:6379 redis创建并启动 Redis容器,但Redis 默认数据只存在内存,重启 / 宕机数据就丢;所以为了不使数据丢失,我们采用持久化——把内存数据保存到硬盘文件,重启后自动恢复。
1. Redis 的两种持久化方式
1.1 RDB 快照(默认开启)
原理:定时给全量数据拍快照,保存在容器内的
/data目录下文件dump.rdb优点:文件小、恢复速度极快、性能损耗小
缺点:会丢数据(两次快照之间写入的数据会丢失)
默认规则:15 分钟 1 次、5 分钟 10 次、60 秒 1 万次写入
1.2 AOF 日志(推荐)
原理:记录每一条写命令,实时写入容器内的
/data目录下文件appendonly.aof优点:数据几乎 100% 不丢失,最安全
缺点:文件更大、恢复稍慢
用法:创建容器时,
redis-server --appendonly yes就是启动 Redis 服务,并开启 AOF 持久化
2. 硬盘挂载(永久保存)
Redis 应用以上两种持久化方式,数据会存放在容器内的/data目录下,无论电脑重启,容器重启,都不会丢失。
不过想让数据更加安全,即把容器删掉也不会丢失,就必须用-v 宿主机目录:/data把数据存在你电脑上,才是真正永久保存;
因此完整的AOF + 挂载整理如下:
dockerrun-d--namemy_redis-p6379:6379-vD:\my_redis-data:/data redis redis-server--appendonlyyes