blpop指令的简要描述是:
从队列左边取出一个元素,并将元素从队列里移除
完整的介绍看这里
然后最近用redis做消息队列的时候用到blpop指令(nodejs+redis包),本来想队列里无数据的时候用blpop阻塞查询,一是、无数据的时候减少去redis取数据的操作;二是、有数据的时候,能尽快的消费数据。
但是在操作过程中发现,blpop在阻塞的时候,队列里有数据,但是不能立即取出消费,似乎需要等到本次阻塞超时后才能取出数据返回。
后面排查原因后,发现由于写数据的rpush指令是属于非阻塞指令,而blpop属于阻塞指令,由于两者共用一个队列操作数据,所以rpush到redis后,因为前面有一条blpop阻塞而不能写数据,要等阻塞超时后才能写数据,写完数据后,后续的blpop立即取到数据去消费。
那么解决办法就是阻塞指令走一个连接通道,非阻塞走一个连接通道即可。
/**
* 非阻塞指令连接通道
*/
const client: RedisClient = createClient({ host: REDIS_HOST, port: REDIS_PORT, socket_keepalive: true });
/**
* 阻塞指令连接通道
*/
const blockClient: RedisClient = client.duplicate();
实际上redis包的文档上有指出该问题(client.duplicate描述处),不过没注意,然后花费了一些时间排查了下。。。。