2012-04-25 46 views
2

我使用Redis的存放有序组项目。下面是一个示例代码: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 

为什么项目的顺序不正确,这不是真正的先入先出。

回答

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获得的顺序不是确定性的。

请注意您的离队代理执行不力,因为它需要CPU的100%(没有等待状态),将Redis的饱和与LLEN命令时队列为空。考虑使用诸如brpop等阻塞调用。