2012-04-25 9 views
2

私は、注文商品のセットを格納するためにredisを使用しています。ここではサンプルコードは次のとおりです。Redis Queue不適切な注文

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) 
     } 
    } 

    } 
} 

私がプロデューサーを実行すると、私は消費者を実行したときに項目の順序が正しくないのはなぜ、私は

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

を取得している間、私は

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

を取得しますこれは実際にはFIFOではありません。

答えて

4

コードが間違っているため、これは実際にはFIFOではありません。

lpushを使用してアイテムをキューする場合は、lpopではなくrpopを使用して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)でアイテムを取得する必要があります。しかし、あなたの2人のエージェントはおそらく同時に実行されるので、lpopで取得する順序は決定的ではありません。

デキューエージェントは、CPUが100%(待機状態はありません)、キューが空のときにlenコマンドでRedisを飽和させるため実装が不適切です。代わりにbrpopなどのブロッキングコールを使用することを検討してください。