用Redis来搞定那些特别慢的操作,顺便聊聊怎么用redis模拟耗时过程
- 问答
- 2026-01-08 20:14:55
- 5
行,那咱们就直接聊,有时候写代码,你会碰到一些特别“磨叽”的操作,用户注册完,要发一封欢迎邮件;或者上传一张大图片,后台需要吭哧吭哧地压缩、打水印;又或者是调用某个第三方接口,对方慢得像蜗牛,一次查询要等五六秒。
这些操作有个共同点:它们不是立刻、马上必须给用户结果的,用户点完“注册”,你完全可以先告诉他“注册成功啦!”,然后偷偷在后台慢慢发邮件,没必要让他干等着邮件发送成功才跳转页面,这些“磨叽”操作,就是我们说的“耗时操作”或“重任务”。
那怎么搞定它们呢?一个很常见的办法就是把它们“扔到一边慢慢搞”,专业点叫“异步处理”,而 Redis,这个我们平时主要拿来当缓存用的家伙,其实是个玩“异步任务”的好帮手,它里面有一个叫“列表”(List)的数据结构,你可以把它想象成一个队伍,或者一个管道,我们的核心思路特别简单:把要处理的耗时任务打包成一个消息,塞进 Redis 的这个“队伍”里,然后立马返回响应给用户,你背后开一个或多个“工人”(Worker)程序,不停地从这个队伍里取任务出来执行。
这么做的好处太明显了:
- 用户感觉飞快:主程序(Web 服务器)只负责收任务、塞队列,速度极快,用户体验杠杠的。
- 能抗住突然的流量:就算一瞬间来了十万个注册请求,你的 Web 服务器也不会崩,因为它只是把十万个“发邮件”的任务塞进了 Redis 队列,然后就不管了,处理能力取决于后台有多少个“工人”,可以随时增减。
- 解耦:发邮件的代码和用户注册的代码分开了,以后要修改邮件模板或者换邮件服务商,都不会影响主流程。
好,道理讲完了,我们来点实际的,怎么用 Redis 模拟一个耗时操作呢?咱们就拿“发送欢迎邮件”这个场景来玩一下。
你得有个 Redis,假设已经安装好并在本地运行了。

第一步:生产者(Producer)—— 制造任务
假设我们有一个简单的 Python 程序(用别的语言也一样,道理相通),模拟用户注册的接口,当用户注册成功后,它不直接发邮件,而是把一个任务塞进 Redis 队列。
import redis
import json
import time
# 连接到本地Redis
r = redis.Redis(host='localhost', port=6379, db=0)
# 模拟用户注册
def user_signup(username, email):
# ... 这里是真的注册逻辑,比如把用户存进数据库 ...
print(f"用户 {username} 注册成功!")
# 构建一个耗时的“发送邮件”任务
task = {
'task_type': 'send_welcome_email',
'username': username,
'email': email,
'timestamp': time.time()
}
# 将任务转换成JSON字符串,然后塞进名为 'task_queue' 的列表的右侧(RPUSH)
r.rpush('task_queue', json.dumps(task))
print(f"已将为 {email} 发送邮件的任务加入队列。")
# 测试一下
if __name__ == '__main__':
user_signup('张三', 'zhangsan@example.com')
运行这段代码,你会看到控制台输出“用户张三注册成功!”和“任务已加入队列”,程序就结束了,整个过程非常快,可能就几毫秒。

第二步:消费者(Consumer)—— 处理任务
我们写另一个程序,它就是任劳任怨的“工人”,它的工作就是死循环地盯着那个叫 task_queue 的队列,一旦有任务,就取出来执行。
import redis
import json
import time
# 同样连接到Redis
r = redis.Redis(host='localhost', port=6379, db=0)
def simulate_slow_email_sending(email_content):
"""模拟发送邮件的耗时过程"""
print(f"[Worker] 开始处理发送邮件任务:{email_content}")
# 用 time.sleep 来模拟耗时,比如网络延迟、处理时间等
time.sleep(5) # 暂停5秒,代表这个操作很慢
print(f"[Worker] 邮件发送成功!收件人:{email_content['email']}")
def worker():
print("工人已启动,正在等待任务...")
while True:
# 从队列左侧(LPOP)取出一个任务,如果队列为空,这里会返回None。
# 使用 blpop 可以阻塞等待,直到有任务到来,比一直循环跑空转要好。
task_data = r.blpop('task_queue', timeout=0) # timeout=0 表示无限等待
if task_data:
# task_data 是一个元组 (list_name, task_json),我们取第二个元素
task_json = task_data[1].decode('utf-8')
task = json.loads(task_json)
# 根据任务类型执行不同的操作
if task['task_type'] == 'send_welcome_email':
simulate_slow_email_sending(task)
else:
print(f"未知任务类型:{task['task_type']}")
# 启动工人
if __name__ == '__main__':
worker()
我们来模拟整个耗时过程:
- 你先运行第二步的工人程序(consumer.py),它会打印“工人已启动...”,然后卡在那里,因为
blpop在安静地等待队列里出现新任务。 - 你运行第一步的生产者程序(producer.py),它唰的一下就执行完了,告诉你任务进了队列。
- 你立刻看工人程序的窗口,会发现它马上开始工作了:“开始处理发送邮件任务...”,然后等待5秒,最后打印“邮件发送成功!”。
这个简单的实验,完美地演示了异步处理,对于用户“张三”他点击注册按钮后,几乎瞬间就看到了“注册成功”的提示,他根本不知道、也不关心后台花了5秒钟才把邮件发出去,而这5秒的“耗时过程”,正是通过 Redis 队列和 time.sleep(5) 模拟出来的。
这是最最基础的模型,真实世界里,我们可能会用更专业的任务队列库,Python 的 Celery(它背后也常用 Redis 做 Broker),它们提供了重试机制、任务状态查询、定时任务等更强大的功能,但万变不离其宗,其核心思想就是咱们上面演示的这个“生产者-消费者”模型,用 Redis 来模拟和实现这个过程,非常直观,能帮你很好地理解异步和队列是怎么一回事。
本文由雪和泽于2026-01-08发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/77012.html
