2012-04-25 73 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等阻塞調用。