Nodejs + redis 订阅并发量太大会不会出问题
Nodejs + redis 订阅并发量太大会不会出问题
redis 的发布 /订阅+node 接收的时候,因为接收到数据后要执行多个任务(比如执行 http 请求、存取数据库),导致发布订阅的速度大于接收订阅的速度。并发量过大,比如一秒有上百个订阅进入 redis , node 这边会实时全部接收么?
要不要加个任务队列,接收到订阅后把任务放任务队列里。。但感觉这样是不是有点冗余, redis 的订阅实际上就已经类似于一个任务队列了?
redis pubsub 是没有持久化的队列,短时间内请求多问题不大,如果并发一直很大 可以考虑在中间加个 kafka 这种带持久化的队列。
redis 是单线程的
sub 是一个个 listen 的,所以 node 处理慢了就会导致 redis 消息队列堆积,内存占用过多
BTW ,@wander2008 说的单线程跟这事情并没啥关系
对,就是你这个意思。。解决方法就是按 的方法做,换持久化的队列?
短期的高并发可以这么搞,一直这么高的话是消费者的消费速度跟不上,磁盘很快就被写满了。
这种情况下可以考虑增加消费者,比如起多个实例增加系统的吞吐。
那你思考的层面是?
在Node.js中使用Redis进行订阅时,如果并发量过大,确实可能会引发问题。这主要源于Redis单实例的处理能力和网络IO的瓶颈。以下是一些解决方案和代码示例:
-
使用Redis集群:
- 将数据分布在多个Redis节点上,从而增加Redis的并发处理能力。
-
信号量控制并发量:
- 使用Redis的信号量(如SETNX命令)来控制同时访问某个资源的并发量。
const redis = require("redis"); const client = redis.createClient(); client.setnx("concurrency_limit", 10, (err, reply) => { if (reply === 1) { console.log("Set concurrency limit to 10"); } else { console.log("Concurrency limit already set"); } }); // 在订阅和处理消息前,检查并发量 client.get("concurrency_limit", (err, concurrencyLimit) => { if (currentConcurrency < parseInt(concurrencyLimit)) { // 允许订阅和处理消息 currentConcurrency++; } else { // 拒绝或延迟处理新的订阅请求 } });
-
使用分布式锁:
- 在Node.js中实现Redis分布式锁,以确保数据的一致性和操作的原子性。可以使用Redis的SET命令结合Lua脚本来实现。
-
优化Redis配置:
- 调整Redis的配置参数,如最大连接数、缓冲区大小等,以适应高并发场景。
综上所述,通过合理的架构设计和配置优化,可以有效应对Node.js + Redis订阅高并发量带来的挑战。