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

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

4

1 回答 1

4

这不是真正的先进先出,因为代码是错误的。

如果您使用 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。

于 2012-04-25T16:13:40.290 回答