news 2026/4/21 13:42:31

Python 读写 Redis 缓存数据库:写给 Python 初学者的入门案例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 读写 Redis 缓存数据库:写给 Python 初学者的入门案例

Python 读写 Redis 缓存数据库:写给 Python 初学者的入门案例

很多学习 Python 的小伙伴,在学完文件读写、SQLite、MySQL 之后,都会接触到一个新的数据库:Redis。

Redis 和传统关系型数据库不太一样。MySQL、SQLite 更擅长长期保存结构化数据,而 Redis 更常用于缓存、计数器、排行榜、验证码、分布式锁、消息队列等高性能场景。

这篇文章会先简单介绍 Redis 是什么,然后通过 Python 代码演示如何连接 Redis,并完成常见的读写操作。

一、Redis 是什么

Redis 全称是 Remote Dictionary Server,可以理解为一个高性能的内存型 Key-Value 数据库。

它的核心特点是:

  1. 数据主要存放在内存中,读写速度非常快
  2. 使用 Key-Value 形式保存数据
  3. 支持丰富的数据结构,不只是简单字符串
  4. 支持设置过期时间,适合做缓存
  5. 支持持久化,可以把内存数据保存到磁盘
  6. 常用于缓存、计数、排行榜、会话、限流等场景

我们可以把 Redis 想象成一个超快的字典:

cache={"user:1:name":"Alice","article:100:view_count":358,"login:code:13800138000":"829316"}

只不过这个字典不是保存在 Python 程序里,而是保存在 Redis 服务中。多个程序、多个接口、多个服务器都可以一起访问它。

二、Redis 和 MySQL、SQLite 有什么区别

简单对比一下:

对比项RedisMySQL / SQLite
存储方式主要在内存中主要在磁盘中
数据模型Key-Value 和多种数据结构表、行、列
读写速度非常快相对较慢
常见用途缓存、计数、排行榜、验证码业务数据持久化
查询方式通过 key 访问SQL 查询
是否适合复杂查询不适合适合

所以 Redis 通常不是用来完全替代 MySQL 或 SQLite 的,而是和它们配合使用。

例如:

  1. 用户资料保存在 MySQL 中
  2. 热门用户资料缓存到 Redis 中
  3. 下次查询时先查 Redis
  4. Redis 没有命中,再查 MySQL
  5. 查到后再写回 Redis

这个模式通常叫缓存旁路,也叫 Cache Aside。

三、准备 Redis 环境

如果你本机已经安装 Redis,可以直接启动 Redis 服务。

如果没有安装,也可以使用 Docker 快速启动:

dockerrun--nameredis-demo-p6379:6379-dredis

测试 Redis 是否可用:

redis-cliping

如果返回:

PONG

说明 Redis 服务已经启动成功。

四、安装 Python Redis 客户端

Python 操作 Redis 常用的库是redis

安装命令:

pipinstallredis

安装完成后,可以在 Python 中导入:

importredis

五、连接 Redis

新建一个文件redis_demo.py

importredis r=redis.Redis(host="localhost",port=6379,db=0,decode_responses=True)print(r.ping())

运行:

python redis_demo.py

如果输出:

True

说明 Python 已经成功连接到 Redis。

这里的几个参数含义如下:

参数说明
hostRedis 服务器地址
portRedis 端口,默认 6379
dbRedis 数据库编号,默认 0
decode_responses是否把返回值自动解码成字符串

如果不设置decode_responses=True,Redis 返回的字符串可能是字节类型:

b'Alice'

对初学者来说,建议先加上decode_responses=True,这样输出更直观。

六、字符串 String:最基础的缓存读写

Redis 最简单的数据类型是 String。

可以用它保存用户名、验证码、Token、简单配置、缓存结果等。

importredis r=redis.Redis(host="localhost",port=6379,db=0,decode_responses=True)# 写入字符串r.set("user:1:name","Alice")# 读取字符串name=r.get("user:1:name")print(name)

输出:

Alice

设置过期时间

缓存通常不应该永久存在,所以 Redis 支持给 key 设置过期时间。

例如保存短信验证码,60 秒后自动删除:

r.set("login:code:13800138000","829316",ex=60)code=r.get("login:code:13800138000")print(code)

其中ex=60表示 60 秒后过期。

也可以先写入,再单独设置过期时间:

r.set("temp:data","hello")r.expire("temp:data",30)

查看剩余过期时间:

ttl=r.ttl("temp:data")print(ttl)

七、数字自增:计数器案例

Redis 很适合做计数器,例如文章阅读量、点赞数、接口访问次数。

article_key="article:100:view_count"r.set(article_key,0)r.incr(article_key)r.incr(article_key)r.incr(article_key)count=r.get(article_key)print(count)

输出:

3

也可以一次增加指定数量:

r.incrby(article_key,10)print(r.get(article_key))

对应减少:

r.decr(article_key)r.decrby(article_key,5)

计数器是 Redis 非常常见的使用场景,因为这类操作简单、高频,而且对速度要求高。

八、Hash:保存对象信息

如果要保存一个用户对象,用多个 String 也可以:

user:1:name user:1:age user:1:city

但更推荐使用 Hash:

r.hset("user:1",mapping={"name":"Alice","age":20,"city":"Shanghai"})name=r.hget("user:1","name")print(name)user=r.hgetall("user:1")print(user)

输出:

Alice{'name':'Alice','age':'20','city':'Shanghai'}

修改 Hash 中的某个字段:

r.hset("user:1","city","Beijing")

删除某个字段:

r.hdel("user:1","age")

判断字段是否存在:

exists=r.hexists("user:1","name")print(exists)

Hash 非常适合保存用户资料、商品摘要、文章基础信息等对象型数据。

九、List:保存列表数据

Redis 的 List 可以理解为一个有序列表。

常见用途:

  1. 最新消息列表
  2. 简单队列
  3. 最近浏览记录
  4. 日志缓冲

示例:

key="user:1:recent_articles"r.delete(key)r.lpush(key,"article:100")r.lpush(key,"article:101")r.lpush(key,"article:102")articles=r.lrange(key,0,-1)print(articles)

输出:

['article:102','article:101','article:100']

lpush是从左侧插入,所以最后插入的元素排在最前面。

如果想从右侧插入,可以使用:

r.rpush(key,"article:103")

从列表中弹出一个元素:

item=r.lpop(key)print(item)

限制列表长度,只保留最近 3 条:

r.ltrim(key,0,2)

这个操作很适合做“最近浏览记录”。

十、Set:保存不重复集合

Set 是无序且不重复的集合。

常见用途:

  1. 用户标签
  2. 点赞用户集合
  3. 已签到用户集合
  4. 去重统计

示例:记录给文章点赞的用户。

key="article:100:liked_users"r.delete(key)r.sadd(key,"user:1")r.sadd(key,"user:2")r.sadd(key,"user:1")users=r.smembers(key)print(users)is_liked=r.sismember(key,"user:1")print(is_liked)

输出:

{'user:1','user:2'}True

虽然添加了两次user:1,但 Set 会自动去重。

统计集合元素数量:

count=r.scard(key)print(count)

取消点赞:

r.srem(key,"user:1")

十一、Sorted Set:排行榜案例

Sorted Set 是有序集合,每个元素都有一个分数。

它非常适合做排行榜。

例如游戏积分排行榜:

key="game:rank"r.delete(key)r.zadd(key,{"Alice":1500,"Bob":1800,"Cindy":1700,"David":1200})top3=r.zrevrange(key,0,2,withscores=True)print(top3)

输出:

[('Bob',1800.0),('Cindy',1700.0),('Alice',1500.0)]

给用户增加积分:

r.zincrby(key,200,"Alice")

查询 Alice 的排名:

rank=r.zrevrank(key,"Alice")print(rank)

注意:Redis 的排名从 0 开始。如果返回 0,表示第一名。

十二、保存 JSON 数据

有时我们希望把一个 Python 字典直接缓存起来。

可以使用json.dumps()转成字符串保存,读取时再用json.loads()转回来。

importjsonimportredis r=redis.Redis(host="localhost",port=6379,db=0,decode_responses=True)user={"id":1,"name":"Alice","age":20,"roles":["admin","editor"]}r.set("cache:user:1",json.dumps(user,ensure_ascii=False),ex=300)cached_text=r.get("cache:user:1")cached_user=json.loads(cached_text)print(cached_user["name"])print(cached_user["roles"])

这种方式很适合缓存接口返回结果。

不过要注意:Redis 本身保存的是字符串。如果你要频繁修改对象中的某个字段,Hash 可能比 JSON 字符串更方便。

十三、完整案例:使用 Redis 缓存用户资料

下面做一个更贴近实际项目的案例。

假设我们有一个“慢查询函数”,它模拟从数据库查询用户资料。为了提高速度,我们先查 Redis;如果 Redis 中没有,再查数据库,并把结果写入 Redis。

importjsonimporttimeimportredis r=redis.Redis(host="localhost",port=6379,db=0,decode_responses=True)defquery_user_from_database(user_id):"""模拟数据库查询。"""print("正在查询数据库...")time.sleep(2)fake_database={1:{"id":1,"name":"Alice","age":20},2:{"id":2,"name":"Bob","age":22},3:{"id":3,"name":"Cindy","age":19},}returnfake_database.get(user_id)defget_user(user_id):"""优先从 Redis 缓存读取用户资料。"""cache_key=f"cache:user:{user_id}"cached_user=r.get(cache_key)ifcached_user:print("命中 Redis 缓存")returnjson.loads(cached_user)user=query_user_from_database(user_id)ifuserisNone:returnNoner.set(cache_key,json.dumps(user,ensure_ascii=False),ex=60)print("已写入 Redis 缓存")returnuserif__name__=="__main__":print(get_user(1))print(get_user(1))

第一次运行时,输出类似:

正在查询数据库... 已写入 Redis 缓存{'id':1,'name':'Alice','age':20}命中 Redis 缓存{'id':1,'name':'Alice','age':20}

第一次查询 Redis 没有数据,所以会访问“数据库”,并等待 2 秒。

第二次查询时,Redis 中已经有缓存,所以直接返回,速度明显更快。

这就是 Redis 最典型的缓存使用方式。

十四、封装一个简单的 Redis 工具类

在项目中,我们通常不会把 Redis 操作散落在各个地方。可以先封装一个简单工具类:

importjsonimportredisclassRedisCache:def__init__(self,host="localhost",port=6379,db=0):self.client=redis.Redis(host=host,port=port,db=db,decode_responses=True)defset_json(self,key,value,expire_seconds=300):text=json.dumps(value,ensure_ascii=False)self.client.set(key,text,ex=expire_seconds)defget_json(self,key):text=self.client.get(key)iftextisNone:returnNonereturnjson.loads(text)defdelete(self,key):returnself.client.delete(key)defexists(self,key):returnself.client.exists(key)==1cache=RedisCache()cache.set_json("user:1",{"id":1,"name":"Alice"},expire_seconds=60)user=cache.get_json("user:1")print(user)print(cache.exists("user:1"))cache.delete("user:1")

这样后续业务代码会更清晰。

十五、连接池:更适合项目使用

在 Web 项目中,不建议每次请求都重新创建 Redis 连接。

可以使用连接池:

importredis pool=redis.ConnectionPool(host="localhost",port=6379,db=0,decode_responses=True,max_connections=20)r=redis.Redis(connection_pool=pool)r.set("site:name","Python Redis Demo")print(r.get("site:name"))

连接池可以复用连接,减少频繁创建连接带来的开销。

如果你以后使用 Flask、FastAPI、Django,也可以在应用启动时创建 Redis 客户端,然后在接口中复用它。

十六、删除 key 和清理数据库

删除一个 key:

r.delete("user:1")

判断 key 是否存在:

exists=r.exists("user:1")print(exists)

查看匹配的 key:

keys=r.keys("user:*")print(keys)

清空当前数据库:

r.flushdb()

清空所有数据库:

r.flushall()

注意:flushdb()flushall()都是危险操作,真实项目中不要随便执行。

十七、初学者常见问题

1. 连接失败

常见错误:

redis.exceptions.ConnectionError

可能原因:

  1. Redis 服务没有启动
  2. host 或 port 写错了
  3. Docker 容器没有映射 6379 端口
  4. Redis 设置了密码,但代码中没有配置

如果 Redis 设置了密码,需要这样连接:

r=redis.Redis(host="localhost",port=6379,password="your_password",decode_responses=True)

2. 读取结果是字节类型

如果看到:

b'Alice'

可以在连接时加上:

decode_responses=True

3. JSON 读取报错

如果执行:

json.loads(text)

报错,通常说明 Redis 中保存的内容不是合法 JSON 字符串。

建议保存和读取都封装成统一方法,避免同一个 key 有时存普通字符串,有时存 JSON。

4. 缓存数据不是最新的

缓存会带来一个新问题:数据库更新了,但 Redis 里还是旧数据。

常见处理方式:

  1. 更新数据库后删除缓存
  2. 设置较短的过期时间
  3. 对一致性要求很高的数据,不要随便缓存

例如:

defupdate_user_name(user_id,new_name):update_database_user_name(user_id,new_name)r.delete(f"cache:user:{user_id}")

这样下次查询时会重新从数据库读取最新数据,再写入 Redis。

十八、Redis key 命名建议

Redis 的 key 最好有清晰的命名规则。

推荐格式:

业务名:对象名:对象ID:字段名

例如:

user:1:profile user:1:recent_articles article:100:view_count article:100:liked_users login:code:13800138000 game:rank

好的 key 命名可以让排查问题更容易。

不推荐随意命名:

a test data1 abc

项目变大后,这类 key 很难维护。

十九、什么时候适合使用 Redis

适合使用 Redis 的场景:

  1. 高频读取的数据
  2. 可以设置过期时间的数据
  3. 允许短时间不一致的数据
  4. 计数器、排行榜、点赞集合
  5. 验证码、Token、Session
  6. 接口限流、简单队列

不适合使用 Redis 的场景:

  1. 复杂 SQL 查询
  2. 强事务业务
  3. 长期保存的核心数据
  4. 需要大量关联查询的数据

一句话总结:核心业务数据放 MySQL、PostgreSQL、SQLite 等数据库中,Redis 更适合放热点数据和临时数据。

二十、完整练习代码

最后给出一个可以直接运行的综合练习:

importjsonimportredisdefmain():r=redis.Redis(host="localhost",port=6379,db=0,decode_responses=True)print("连接状态:",r.ping())print("\n=== String 示例 ===")r.set("app:name","Redis Python Demo",ex=300)print(r.get("app:name"))print("\n=== Counter 示例 ===")r.delete("article:1:view_count")for_inrange(5):r.incr("article:1:view_count")print(r.get("article:1:view_count"))print("\n=== Hash 示例 ===")r.hset("user:1",mapping={"name":"Alice","age":20,"city":"Shanghai"})print(r.hgetall("user:1"))print("\n=== List 示例 ===")r.delete("user:1:recent")r.lpush("user:1:recent","article:100","article:101","article:102")print(r.lrange("user:1:recent",0,-1))print("\n=== Set 示例 ===")r.delete("article:1:likes")r.sadd("article:1:likes","user:1","user:2","user:1")print(r.smembers("article:1:likes"))print("\n=== Sorted Set 示例 ===")r.delete("rank:score")r.zadd("rank:score",{"Alice":98,"Bob":86,"Cindy":95})print(r.zrevrange("rank:score",0,-1,withscores=True))print("\n=== JSON 缓存示例 ===")user={"id":1,"name":"Alice","skills":["Python","Redis"]}r.set("cache:user:1",json.dumps(user,ensure_ascii=False),ex=60)cached_user=json.loads(r.get("cache:user:1"))print(cached_user)if__name__=="__main__":main()

运行前确保:

  1. Redis 服务已经启动
  2. 已安装 Python 依赖:pip install redis
  3. 代码中的 host、port、password 配置正确

总结

Python 操作 Redis 的核心流程并不复杂:

安装 redis 库 -> 连接 Redis -> 选择数据结构 -> 写入数据 -> 读取数据 -> 设置过期时间

常用方法可以简单记住:

方法作用
set()/get()读写字符串
incr()/decr()计数器
hset()/hgetall()操作 Hash
lpush()/lrange()操作 List
sadd()/smembers()操作 Set
zadd()/zrevrange()操作排行榜
expire()/ttl()设置和查看过期时间
delete()删除 key

对 Python 初学者来说,学习 Redis 的重点不是一开始就背所有命令,而是先理解它适合解决什么问题。

如果你能掌握缓存用户资料、验证码、计数器、排行榜这几个案例,就已经可以在很多真实项目中使用 Redis 了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/21 13:40:15

如何在Windows上高效安装安卓应用:APK Installer完整指南

如何在Windows上高效安装安卓应用:APK Installer完整指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾想过在Windows电脑上直接安装安卓应用&am…

作者头像 李华
网站建设 2026/4/21 13:38:15

Phi-4-mini-reasoning企业落地:为SaaS产品增加‘逻辑验证’API能力模块

Phi-4-mini-reasoning企业落地:为SaaS产品增加逻辑验证API能力模块 1. 为什么企业需要逻辑验证能力 在现代SaaS产品中,逻辑验证能力正变得越来越重要。想象一下这样的场景:你的客户提交了一份合同条款,需要快速判断其中是否存在…

作者头像 李华
网站建设 2026/4/21 13:34:58

OpenClaw 个人AI助手使用教程:从配置到实战

一、前言 通过上一篇文章《OpenClaw 个人AI助手完整安装教程》,你已经成功在本地部署了OpenClaw。现在,是时候让它真正为你工作了! 本文将详细介绍OpenClaw的配置和使用方法,包括: 连接各种聊天渠道(What…

作者头像 李华
网站建设 2026/4/21 13:34:52

【开源鸿蒙PC资源推荐】【2026-04-20更新】

👉点击欢迎加入鸿蒙PC社区 希望大家共享共建,有推荐资源,请提PR ​ 目录 一、鸿蒙PC基础资源推荐【使用鸿蒙PC】二、鸿蒙PC命令行和C/C三方库资源推荐三、鸿蒙PC跨平台框架资源推荐三、鸿蒙PC编程语言资源推荐四、鸿蒙PC应用资源推荐五、其…

作者头像 李华