一篇详解Redis延时队列

【一篇详解Redis延时队列】redis的 list 数据结构常用来作为 异步消息队列 使用,使用 rpush/lpush 操作 入队 ,使用 lpop/rpop 来操作 出队

一篇详解Redis延时队列

文章插图
 
> rpush my-queue Apple banana pear(integer) 3> llen my-queue(integer) 3> lpop my-queue"apple"> llen my-queue(integer) 2> lpop my-queue"banana"> llen my-queue(integer) 1> lpop my-queue"pear"> llen my-queue(integer) 0> lpop my-queue(nil)空队列
  1. 如果队列为空,客户端会陷入 pop的死循环 , 空轮询 不仅拉高了 客户端的CPU , Redis的QPS 也会被拉高
  2. 如果空轮询的客户端有几十个, Redis的慢查询 也会显著增加,可以尝试让客户端线程 sleep 1s
  3. 但睡眠会导致消息的 延迟增大 ,可以使用 blpop/brpop (blocking, 阻塞读 )
  • 阻塞读在队列没有数据时,会立即进入 休眠 状态,一旦有数据到来,会立即被 唤醒, 消息延迟几乎为0
空闲连接
  1. 如果线程一直阻塞在那里,Redis的客户端连接就成了 闲置连接
  2. 闲置过久, 服务器 一般会 主动断开 连接, 减少闲置的资源占用 ,此时 blpop/brpop 会 抛出异常
锁冲突处理
  1. 分布式锁 加锁失败 的处理策略
  2. 直接抛出异常 ,通知用户稍后重试
  3. sleep 后再重试
  4. 将请求转移到 延时队列 ,过一会重试
  5. 抛出异常
  6. 这种方式比较适合由 用户直接发起 的请求
  7. sleep
  8. sleep会 阻塞 当前的消息处理线程,从而导致队列的后续消息处理出现 延迟
  9. 如果 碰撞比较频繁 ,sleep方案不合适

    • 推荐阅读