queue - 跨多个redis主服务器实现一个队列

标签 queue redis

我正在尝试使用两个 EC2 可用性区域中的两个 redis 主服务器构建一个作业队列。所有 LPUSH 操作都在应用层中完成到两个 AZ 中的两个 master 机器。理想情况下我会使用 GitHub's resque , 但重新请求 does not seem to have any notion多个 AZ 中的多个 master。

我需要确保只有一名 worker 在从事给定的工作。一些工作人员将在 AZ 1A 中与 1A 中的 redis 机器通信,而一些将在 AZ 1B 中与 1B 中的机器通信。我需要避免 1A 中的工作人员和 1B 中的工作人员都从不同的 redis master 中获取相同的工作并尝试同时处理它的情况。

这个 worker 伪代码是否有任何我可能错过的竞争条件?

job_id = master1.BRPOPLPUSH "queue", "working"
m1lock = master1.SETNX "lock.#{job_id}"
m2lock = master2.SETNX "lock.#{job_id}"
completed = master1.ZSCORE "completed", job_id

if completed
  # must have been completed just now on other server, no-op
  master1.LREM "working", 0, job_id
  master1.del "lock.#{job_id}"
  master2.del "lock.#{job_id}"
elsif not m1lock or not m2lock
  # other server is working on it? We will put back at the end of our queue
  master1.LPUSH "queue", job_id
  master1.LREM "working", 0, job_id
  master1.del "lock.#{job_id}" if m1lock
  master2.del "lock.#{job_id}" if m2lock
else
  # have a lock, it's not complete, so do work
  do_work(job_id)

  now = Time.now.to_i
  master1.ZADD "completed", now, job_id
  master2.ZADD "completed", now, job_id

  master1.del "lock.#{job_id}"
  master2.del "lock.#{job_id}"

  master1.LREM "working", 0, job_id
  master2.LREM "queue", 0, job_id # not strictly necessary b/c of "completed"
end

最佳答案

本质上你想做的是master-master replication,无论是队列还是其他什么,redis都不支持,而且你的伪代码存在race conditions。 只是在做:

m1lock = master1.SETNX "lock.#{job_id}"
m2lock = master2.SETNX "lock.#{job_id}"

意味着另一个 worker 可以在你做这件事的时候接手这项工作,两个 worker 将同时工作。 我不认为 redis 是您的模式的理想选择,而且我不知道有任何队列服务器可以那样工作,但话又说回来,我不知道有多少这样的服务器,所以我确定有。

如果您对您的工作进行负载平衡,以便一次只有一个主服务器获得一份工作,这是可能的,但实际上您有两个队列,而不是一个。

关于queue - 跨多个redis主服务器实现一个队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10822812/

相关文章:

azure - Redis 集群的 MOVED 异常 - StackExchange.Redis

caching - 如何使用redis缓存更新页面计数器?

redis - 使用 python-rq (redis) 在多个服务器上进行远程工作

node.js - NodeJS + ExpressJS + RedisStore session 未定义

django - 用于为初学者编写 Twitter 克隆代码的数据库

c++ - STD 队列 : Efficient, 还是矫枉过正?

python - 清除队列中的所有项目

java - 什么是从树中添加的队列上的节点、指针或节点的副本?

node.js - 最佳实践 beanstalkd(队列)和 node.js

python - 如何在python中实现队列的深复制