首页 新闻 会员 周边 捐助

多个消费者重复消费问题

0
悬赏园豆:50 [已解决问题] 解决于 2019-03-02 10:00

有一个集合存储在 Redis 中,有多个相同的消费者访问这个集合,每读到一条数据都要持久化到数据库中,并从 Redis 中删除这条数据。

现在是通过 SCAN 遍历所有的 Key,但是 SCAN 不支持并行操作,因为 Redis 服务是不记录状态的。

希望实现以下目标:

  1. 多个消费者不会重复消费集合中数据
  2. 尽可能并行消费,因为集合的数据量可能比较大
问题补充:

在并发比较高时,SCAN命令的遍历速度明显跟不上新增的速度,导致数据越积越多,所以不能使用SCAN

蝌蝌的主页 蝌蝌 | 初学一级 | 园豆:158
提问于:2019-02-22 10:38
< >
分享
最佳答案
0

有一个不成熟的想法,新建一个监听者,只运行一个实例,它只负责遍历 Redis 中的集合,然后通过负载均衡发送给消费者。

蝌蝌 | 初学一级 |园豆:158 | 2019-02-22 10:59

Redis的锁,是可以锁key的。

Shendu.CC | 园豆:2138 (老鸟四级) | 2019-02-26 14:54

@Shendu.CC: 目的是要尽可能并行消费,必须在很短的时间内把集合中的数据消费完,所以加锁就有悖初衷。

最终采用的方案是通过将所有的 keys 存储在SET集合中,通过SET.Pop()消费,Pop()支持并行操作,速度非常快,能够达到要求。

同时也就不需要最初的这种负载均衡的方案了。

蝌蝌 | 园豆:158 (初学一级) | 2019-03-02 09:59
其他回答(5)
0

还可以增加一个储存 监听实例的队列。redis 实例 和监听实例都可以横向扩展。

但是监听实例和redis不是一一对应的情况。 监听实例每监听完一个 redis 都会回到队列中,等待出队列。出队列的标准,是查看哪个redis实例 被监听者遍历过后处于空闲状态,如果查到了,立刻出队列去遍历这个redis实例。redis实例的状态也有空闲变成忙碌。

这样的话,效果就是多个redis,多个监听实例在同时的并行工作,而且可以横向扩展redis实例和 监听实例。而且队列中监听的实例一定要比redis实例多。

收获园豆:50
Shendu.CC | 园豆:2138 (老鸟四级) | 2019-02-22 11:35
0

用消息队列去消费处理呢?比如kafka

让我发会呆 | 园豆:2929 (老鸟四级) | 2019-02-22 11:48
0

为什么没有考虑使用 redis 的分布式锁,园子里的参考博文:

dudu | 园豆:31030 (高人七级) | 2019-02-26 14:15
0

如果Python的话,用multiprocessing.Queue呢?将消息写入Queue,多进程消费Queue。

阿牧路泽 | 园豆:202 (菜鸟二级) | 2019-02-27 23:56
0

可以考虑加个锁

jerry-Tom | 园豆:4077 (老鸟四级) | 2019-03-01 14:09
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册