Redis队列不正确的排序

时间:2012-04-25 13:41:37

标签: scala redis jedis

我使用redis存储一组有序的项目。以下是示例代码:

object Producer{
  def main(args:Array[String]){
    val jedis = new Jedis("localhost")
    for (i<-1 to 10){
      println("publishing:"+(i))
      jedis.lpush("q1",i.toString)
    }
  }
}
object Consumer {
  def main(args:Array[String]){
    val jedis = new Jedis("localhost")
    while(true){
      while(jedis.llen("q1")>0){
        val msg=jedis.lpop("q1")
        println("processing:"+msg)
      }
    }

  }
}

当我运行制作人时,我得到了

publishing:1
publishing:2
publishing:3
publishing:4
publishing:5
publishing:6
publishing:7
publishing:8
publishing:9
publishing:10

当我运行消费者时,我得到了

processing:1
processing:2
processing:4
processing:5
processing:6
processing:7
processing:9
processing:10
processing:8
processing:3

为什么项目的顺序不正确,这实际上不是FIFO。

1 个答案:

答案 0 :(得分:4)

这不是真正的FIFO,因为代码是错误的。

如果使用lpush排队项目,则应使用rpop而不是lpop以FIFO顺序将它们出列。

redis 127.0.0.1:6379> lpush x 10
(integer) 1
redis 127.0.0.1:6379> lpush x 20
(integer) 2
redis 127.0.0.1:6379> lpush x 30
(integer) 3
redis 127.0.0.1:6379> lpop x
"30"
redis 127.0.0.1:6379> lpop x
"20"
redis 127.0.0.1:6379> lpop x
"10"

通常你应该以相反的顺序检索项目(LIFO)。但是你的两个代理可能同时运行,所以你用lpop获得的顺序不是确定性的。

请注意,您的出列代理程序执行得很差,因为它需要100%的CPU(没有等待状态),并且当队列为空时将使用llen命令使Redis饱和。考虑使用阻塞调用,例如brpop。