为什么说 Redis 是“穷人版 MQ”?这道社招题给你答案

29 阅读5分钟



那天面试官端起咖啡,笑着问我一句:“你用 Redis 做过异步队列吗?是怎么实现的?

我脑子里瞬间浮现的,不是 API,而是一家凌晨三点还在出单的外卖店、一堆等着被做掉的订单,以及一个永远不加班却扛下所有活的 Redis。

今天,我们就用一个故事,把 Redis 异步队列 这道社招高频题彻底讲透。

故事开场:凌晨三点的外卖店

先给你讲个故事。

凌晨三点,我朋友老王开了一家外卖店,生意爆火。问题来了:

  • 下单的人很多
  • 做饭的人就那几个
  • 老板不想让顾客一直等在前台

于是老王想了个办法。顾客下单后,把订单写在小票上,丢进一个盒子里;厨师有空了,就从盒子里拿一张出来做。 这个“盒子”,本质上就是一个——队列

而在程序世界里,这个盒子,很可能就是 Redis

为什么要用“异步队列”?

在面试官眼里,你如果直接说“我用 Redis 的 list 实现队列”,那只是及格。但如果你能说清楚:为什么要用异步队列,那才是加分项。

我们先站在业务角度看:

核心问题只有一个:我不想让用户等“没必要等的事情”

于是,异步队列就登场了:

  • 主线程:只做核心逻辑
  • 次要任务:丢进队列慢慢处理

而 Redis,刚好满足几个关键条件:

  • 内存级别,速度快
  • API 简单
  • 运维成本低
  • 单机就能用

所以,在很多中小系统里,Redis 就是“穷人版 MQ”

最基础实现:List + rpush + lpop

我们先从最经典、也是面试官最爱问的方案开始。

1、用 List 当队列

Redis 的 List,天生就是一个双端队列

  • rpush:从右边塞数据
  • lpop:从左边取数据

完美符合 FIFO(先进先出)

2、生产者:rpush

生产者就像“顾客下单”,只负责把任务丢进队列。

这一步的特点是:

  • 非常快
  • 不阻塞
  • 失败概率低

只要 Redis 还活着,消息基本就进去了。

3、消费者:lpop + sleep(最原始方案)

消费者就像“厨师”,不停地从队列里拿订单。

这个方案,面试官一定会追问:“如果一直没消息怎么办?”

你要回答得很冷静:

  • 没消息就 sleep
  • 避免 CPU 空转
  • 简单粗暴,但不优雅

4、这种方案的问题

我们用一张表总结一下:

于是,Redis 给了我们一个更聪明的办法

进阶方案:BLPOP(阻塞队列)

这个时候,面试官往往会点点头,然后继续问: “那你知道 BLPOP 吗?”

如果你这时候眼睛一亮,说明这题你稳了。

1、什么是 BLPOP?

BLPOP 是 Blocking List Pop,阻塞式弹出。特点只有一句话:队列没数据时,线程会一直阻塞,直到有新消息进来

就像:

  • 厨师没单子
  • 不转圈、不发呆
  • 直接站那等
  • 有单子“啪”一声递到手里

2、BLPOP 示例代码

这里的 0 表示:

  • 一直等
  • 不超时

如果你想设置超时,比如 5 秒:

3、BLPOP 的优势

我们对比一下两种方案:

面试语境下,你一定要强调一句:生产环境更推荐使用 BLPOP

一个生产者,多个消费者可以吗?

这个问题,面试官几乎一定会问。答案是:可以,而且很自然。

1、多消费者模型

  • 多个消费者
  • 同时 BLPOP 同一个队列
  • Redis 保证:一条消息只会被一个消费者拿到

就像:

  • 多个厨师
  • 一个订单盒
  • 谁先伸手,谁拿走

2、特点总结

这也是 Redis 队列在中小项目里特别受欢迎的原因。

再进阶:Pub/Sub 实现广播型队列

聊到这一步,面试官往往会换一个问法: “那 Redis 的 Pub/Sub 用过吗?”

这个时候,你可以顺势升级故事。

1、Pub/Sub 是什么?

如果说 List 是“订单盒子”,那 Pub/Sub 更像是“广播喇叭”。

  • 生产者:往频道里喊一句
  • 所有订阅者:同时听到

2、示例代码

生产者

消费者

3、Pub/Sub 的典型场景

Pub/Sub 的致命缺点(面试必答)

说到这里,千万别只夸不骂。面试官真正想听的是这句话:消费者下线期间,消息会丢失

我们用一句人话翻译:

  • 没订阅
  • 就听不到
  • Redis 不帮你存

对比总结

所以你要总结得很清楚:Pub/Sub 更适合“通知”,不适合“任务队列”

面试官真正想考你的是什么?

到这里,我们跳出代码,看一眼面试官的视角。这道题,他其实在看三点:

  • 你是否理解“异步”的本质:不是 API,是 削峰、解耦、提速
  • 你是否理解 Redis 的数据结构:为什么用 List,而不是 String、Set
  • 你是否知道 Redis 的边界:知道它 不是 MQ 的完全替代品

如果你最后能补一句:“如果对可靠性要求高,我会用 MQ;Redis 更适合轻量级、对丢失不敏感的场景。”

基本上,面试官心里已经给你打了个 A-

总结:回到凌晨三点的外卖店

故事最后,老王的外卖店活下来了。

  • 订单先放盒子
  • 厨师慢慢做
  • 顾客不用一直等
  • 系统也不崩

Redis 在这里,就像那个永远不喊累的订单盒。它不复杂,但足够稳定;它不高级,但非常实用。

END

技术不是炫技,而是用合适的工具,解决合适的问题。

如果你下次在面试中,被问到: “你用 Redis 做过异步队列吗?”

希望你脑子里浮现的,不只是 rpush 和 blpop,还有这家凌晨三点还在出单的外卖店。

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!