关于 Redis 队列的一道面试题

2016-03-08 15:01:55 +08:00
 tanteng

面试的时候讲到自己做的一个项目,我说用了 Redis 队列, lpush 进, rpop 出,面试官打断问:一般入队列没有问题,如果出对列阻塞了怎么办?实际生产环境中在这里没有出现问题,而且队列量很大,我没有太理解面试官问的什么。

Redis 作队列需要注意什么问题?如果是高并发情况下怎么办?谢谢大家指点!

30558 次点击
所在节点    Redis
38 条回复
tanteng
2016-03-08 15:11:08 +08:00
还有另外的地方用的是 HTTPSQS 消息队列系统,还有 Kafka
CosWind
2016-03-08 15:38:13 +08:00
同没有 get 到面试官的点,队列阻塞也分很多种情况,和业务挂钩;
如果是单纯的处理能力不够,增加 consumer 就可以;
如果对顺序有要求,要对消息作 shard 。。

但这么问,实在 get 不到点呀
gaocheng
2016-03-08 15:41:23 +08:00
1 、队列阻塞问题做好报警
2 、从业务方面考虑能够动态调控提高队列处理能力
sampeng
2016-03-08 15:43:09 +08:00
面试官的意思就是字面意思啊。。堵塞。。消费者挂掉 or 太慢。怎么处理
sampeng
2016-03-08 15:44:26 +08:00
单纯加 cunsumer 真可以么。。资源不是无限的。
我这线上就有一个典型例子,消费者突然处理变慢,加到能加的极限了,然后,然后就 redis 的内存吃满领便当了。
tanteng
2016-03-08 15:59:16 +08:00
@sampeng 那如何解决的呢
Mirana
2016-03-08 16:17:04 +08:00
我怎么觉得阻塞的意思是队列空了呢
iyaozhen
2016-03-08 16:17:17 +08:00
最近就遇到这个问题了。

消费者的速度没有生产者快,增加消费者也缓解不了, Redis 会被打满,直到挂掉(影响其它业务功能)。而且 Redis 目前的数据清理策略是根据 key 的,如果设置了清理用作队列的那个 list key 会被清掉,如果这是业务代码写的不是太好的话消费者和生产者都会挂掉。消费者最好还是异步消费,不要阻塞队列。

当然还是要对队列长度做监控。

目前已经转投 Kafka 了。
iyaozhen
2016-03-08 16:18:50 +08:00
@Mirana 空了没关系吧, sleep 几秒。或者使用 brpop 指令。
tanteng
2016-03-08 16:19:55 +08:00
@iyaozhen 消费者异步消费?这里能具体讲讲吗
sampeng
2016-03-08 16:23:39 +08:00
kafka 是正理。。
redis 只适合快速消费不会堆积的业务场景上,数据存内存里实在太贵了。。
lecher
2016-03-08 16:24:10 +08:00
出队列阻塞就是消费者的处理速度跟不上生产者产生的任务,加消费者提高处理速度。
消费者加到极限还处理不过来,实在有爆内存的风险的时候,可以考虑将任务数据持久化,避免数据丢失,先把任务状态保存下来,根据具体业务做优化调整,等待异常问题解决之后再继续处理。
Mirana
2016-03-08 16:26:28 +08:00
消费和生产有数量级的差异的话,增加消费者也是没用的,数据重要就放到数据库里,不重要就直接丢掉。
tabris17
2016-03-08 16:26:29 +08:00
使用支持持久化的队列消息,比如 rabbitmq
iyaozhen
2016-03-08 16:26:35 +08:00
@tanteng 额,可能说的不是太专业。看具体业务吧,你拿到数据肯定是需要做一些处理,这个过程可以异步操作,比如异步写文件,异步入库等。甚至继续向下游业务抛,压力往后转移。
tanteng
2016-03-08 16:35:10 +08:00
@CosWind
@sampeng
增加消费者会不会存在并发取 redis 队列的情况,这种情况要如何处理
cYcoco
2016-03-08 16:37:11 +08:00
用 kafka 好了吧。在我印象里 redis 更适合做类 memcached 这种内存缓存吧。不过对 redis 不太了解。。
lijinma
2016-03-08 17:12:03 +08:00
关于你的问题我遇见过:
1. Redis 关于内存满了如何处理的策略要配置好,是使用 lru 还是 noviction 等,一定要想清楚, Redis 可使用的内存大小要配置适当,最好是你 Redis 内存使用峰值的几倍甚至 10 倍。

2. Redis 内存要做好报警,简单的做法是每分钟或更短的时间使用 info 指令获取内存使用情况,如果超过某个值要马上想办法处理。

3. 如果能多加 consumer ,就尝试多加 consumer 解决。

4. 如果还没有解决,你可能需要想办法提升 Redis 内存占用,可能想办法平行扩展 Redis Server 。

5. 如果还没有解决,就只能想办法用 kafka 这种可以持久化的方式了,或者你自己设计一种 Redis 的持久化方式,因为内存总归是有限的且稀缺的。
tanteng
2016-03-08 17:23:52 +08:00
稍微总结一下:对于大数据的队列不适合用 Redis 弄,考虑 HTTPSQS , RabbitMQ 之类的消息队列系统,或者 Kafka , Redis 队列适合小型,快速,消费也快的场景。
neoblackcap
2016-03-08 17:32:33 +08:00
@tanteng 不会, redis 就是一单线程实现,所有操作都是顺序执行

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/261936

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX