面试的时候讲到自己做的一个项目,我说用了 Redis 队列, lpush 进, rpop 出,面试官打断问:一般入队列没有问题,如果出对列阻塞了怎么办?实际生产环境中在这里没有出现问题,而且队列量很大,我没有太理解面试官问的什么。
Redis 作队列需要注意什么问题?如果是高并发情况下怎么办?谢谢大家指点!
1
tanteng OP 还有另外的地方用的是 HTTPSQS 消息队列系统,还有 Kafka
|
2
CosWind 2016-03-08 15:38:13 +08:00
同没有 get 到面试官的点,队列阻塞也分很多种情况,和业务挂钩;
如果是单纯的处理能力不够,增加 consumer 就可以; 如果对顺序有要求,要对消息作 shard 。。 但这么问,实在 get 不到点呀 |
3
gaocheng 2016-03-08 15:41:23 +08:00
1 、队列阻塞问题做好报警
2 、从业务方面考虑能够动态调控提高队列处理能力 |
4
sampeng 2016-03-08 15:43:09 +08:00
面试官的意思就是字面意思啊。。堵塞。。消费者挂掉 or 太慢。怎么处理
|
5
sampeng 2016-03-08 15:44:26 +08:00 1
单纯加 cunsumer 真可以么。。资源不是无限的。
我这线上就有一个典型例子,消费者突然处理变慢,加到能加的极限了,然后,然后就 redis 的内存吃满领便当了。 |
7
Mirana 2016-03-08 16:17:04 +08:00
我怎么觉得阻塞的意思是队列空了呢
|
8
iyaozhen 2016-03-08 16:17:17 +08:00 2
最近就遇到这个问题了。
消费者的速度没有生产者快,增加消费者也缓解不了, Redis 会被打满,直到挂掉(影响其它业务功能)。而且 Redis 目前的数据清理策略是根据 key 的,如果设置了清理用作队列的那个 list key 会被清掉,如果这是业务代码写的不是太好的话消费者和生产者都会挂掉。消费者最好还是异步消费,不要阻塞队列。 当然还是要对队列长度做监控。 目前已经转投 Kafka 了。 |
11
sampeng 2016-03-08 16:23:39 +08:00 1
kafka 是正理。。
redis 只适合快速消费不会堆积的业务场景上,数据存内存里实在太贵了。。 |
12
lecher 2016-03-08 16:24:10 +08:00 via Android 3
出队列阻塞就是消费者的处理速度跟不上生产者产生的任务,加消费者提高处理速度。
消费者加到极限还处理不过来,实在有爆内存的风险的时候,可以考虑将任务数据持久化,避免数据丢失,先把任务状态保存下来,根据具体业务做优化调整,等待异常问题解决之后再继续处理。 |
13
Mirana 2016-03-08 16:26:28 +08:00 1
消费和生产有数量级的差异的话,增加消费者也是没用的,数据重要就放到数据库里,不重要就直接丢掉。
|
14
tabris17 2016-03-08 16:26:29 +08:00 1
使用支持持久化的队列消息,比如 rabbitmq
|
15
iyaozhen 2016-03-08 16:26:35 +08:00
@tanteng 额,可能说的不是太专业。看具体业务吧,你拿到数据肯定是需要做一些处理,这个过程可以异步操作,比如异步写文件,异步入库等。甚至继续向下游业务抛,压力往后转移。
|
17
cYcoco 2016-03-08 16:37:11 +08:00
用 kafka 好了吧。在我印象里 redis 更适合做类 memcached 这种内存缓存吧。不过对 redis 不太了解。。
|
18
lijinma 2016-03-08 17:12:03 +08:00 1
关于你的问题我遇见过:
1. Redis 关于内存满了如何处理的策略要配置好,是使用 lru 还是 noviction 等,一定要想清楚, Redis 可使用的内存大小要配置适当,最好是你 Redis 内存使用峰值的几倍甚至 10 倍。 2. Redis 内存要做好报警,简单的做法是每分钟或更短的时间使用 info 指令获取内存使用情况,如果超过某个值要马上想办法处理。 3. 如果能多加 consumer ,就尝试多加 consumer 解决。 4. 如果还没有解决,你可能需要想办法提升 Redis 内存占用,可能想办法平行扩展 Redis Server 。 5. 如果还没有解决,就只能想办法用 kafka 这种可以持久化的方式了,或者你自己设计一种 Redis 的持久化方式,因为内存总归是有限的且稀缺的。 |
19
tanteng OP 稍微总结一下:对于大数据的队列不适合用 Redis 弄,考虑 HTTPSQS , RabbitMQ 之类的消息队列系统,或者 Kafka , Redis 队列适合小型,快速,消费也快的场景。
|
20
neoblackcap 2016-03-08 17:32:33 +08:00 via iPhone
@tanteng 不会, redis 就是一单线程实现,所有操作都是顺序执行
|
21
Lucups 2016-03-08 17:35:22 +08:00 1
首先, Redis 是支持持久化的,所以队列数据完全可以持久化;其次, Consumer(Worker) 消化不了扛不住,先尝试多开一些,如果还不行,说明硬件或其他地方(如数据库存储)存在瓶颈,跟队列本身有毛关系?真以为上 Kafka 就能解决问题了?感觉题主没有 Get 到要点。
|
22
keakon 2016-03-08 17:37:50 +08:00
其实是让你用 epoll 之类的注册事件,等到可读时再去读…
|
25
wikimore 2016-03-08 18:00:27 +08:00
BRPOP 一个时间周期(如阻塞 30 秒)轮询,不能一直阻塞,因为长时间连接没有读写可能会被系统干掉,作为客户端就永远阻塞在那里了,而同时服务端的队列里可能有很多消息了。
|
26
500miles 2016-03-08 18:00:44 +08:00 2
按我的理解, 是说 " consumer 吞吐量太弱, 不及 producer 生产速度, 此时何解? "
这就难玩儿了. . 就好比要解决北上广住房问题 . 不考虑移民 (投靠其他技术选型), 1. 监控队列, 动态调配 consumer, 适时增加 consumer 最简单有效的办法, 从根本上解决问题. 当然你得花钱加机器 2. 做好降级方案, 达到预设阀值, 出队后暂不处理, 直接先持久化再说 3. consumer 投递异步任务, 不要阻塞出队列 这个比较难玩儿 |
27
wikimore 2016-03-08 18:07:37 +08:00 1
redis 做队列主要问题应该就是内存,如果使用到 swap 的话, redis 的队列会异常的慢,还有就是消息的大小,不要超过 1K ,再大写入基本就是很慢了,还有就是主从保证高可用,如果量非常大,可以多实例做 partition ,不过这时候用 Kafka 明显更划算, Redis 做做小业务玩玩还是可以的。
|
28
bengol 2016-03-08 18:12:11 +08:00
允许请求超时 /失败,做好失败后处理
|
29
imlewc 2016-03-08 18:28:01 +08:00
分布式 一键解决
|
31
isno 2016-03-08 19:24:23 +08:00 via iPhone
涉及队列的任务学会先消费后处理
|
33
22too 2016-03-08 19:52:57 +08:00
我们也是 rabbitmq
|
34
hxsf 2016-03-08 20:42:46 +08:00 1
@keakon 读不到才阻塞(阻塞消费者),后面的消费者也会一起排队,有内容的时候按先后顺序解除阻塞啊。
redis 文档上的啊,做队列用的时候建议使用 R 官网文档 http://redis.io/commands/brpop 以下引用他人翻译的 列表的阻塞操作 (blocking) 列表有一个特别的特性使得其适合实现队列,通常作为进程间通信系统的积木:阻塞操作。 假设你想往一个进程的列表中添加项,用另一个进程来处理这些项。这就是通常的生产者消费者模式,可以使用以下简单方式实现: 生产者调用 LPUSH 添加项到列表中。 消费者调用 RPOP 从列表提取 / 处理项。 然而有时候列表是空的,没有需要处理的, RPOP 就返回 NULL 。所以消费者被强制等待一段时间并重试 RPOP 命令。这称为轮询(polling),由于其具有一些缺点,所以不合适在这种情况下: 强制 Redis 和客户端处理无用的命令 (当列表为空时的所有请求都没有执行实际的工作,只会返回 NULL)。 由于工作者受到一个 NULL 后会等待一段时间,这会延迟对项的处理。 于是 Redis 实现了 BRPOP 和 BLPOP 两个命令,它们是当列表为空时 RPOP 和 LPOP 的会阻塞版本:仅当一个新元素被添加到列表时,或者到达了用户的指定超时时间,才返回给调用者。 |
35
moe3000 2016-03-08 21:04:38 +08:00
1 、 brpop 可以解决
2 、 redis 分布式部署?具体没研究过。。 |
37
solaro 2016-03-09 11:12:14 +08:00
@wikimore 咦,才 1K ,我之前做的都是限制 10K 以内, 5000/S 的吞吐量还是很快的。大促高峰期内存各种报警
|
38
jinya 2018-03-17 13:20:35 +08:00
马克
|