2

注文したアイテムのセットを保存するために 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 ではありません。

4

1 に答える 1

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% を使用し (待機状態がない)、キューが空の場合に llen コマンドで Redis を飽和状態にするため、デキュー エージェントの実装が不十分であることに注意してください。代わりに、brpop などのブロッキング呼び出しを使用することを検討してください。

于 2012-04-25T16:13:40.290 に答える