Redis:具有多个密钥的交易

时间:2016-04-15 01:11:25

标签: transactions redis spring-data-redis

我正在使用Spring Data Redis。在Redis中,基本数据模型是

job:包含作业数据的哈希。

queue:包含作为队列的作业ID的列表。

新作业将保存在job哈希中,并且会被推送到queue。我们有多个工作者客户端汇集queue以通过弹出id并从哈希读取详细信息来使用新的作业ID。

现在,我正在尝试制定一项新功能,即某些工作人员只能根据作业数据中的某些标记来使用某些作业。问题是工作人员只会知道在读取其详细信息后是否可以使用该作业,而不是在从队列中获取id时。

我原本以为我可以将这一系列操作放入交易中,

  1. 偷看队列。
  2. 从哈希中读取作业详细信息并检查是否为耗材。
  3. 如果是,请从队列中取出其ID,否则不执行任何操作。
  4. 然而,这种事务涉及队列和散列数据。在阅读Redis的交易支持后,我不确定这是否可以实现。请帮助建议我应该采取什么方法。

2 个答案:

答案 0 :(得分:1)

Redis事务与关系数据库事务略有不同,因为它们更好地描述为条件批处理。事务是发出命令时QUEUED的一堆命令。一旦EXEC使用该事务,就会执行命令,并在EXEC命令的响应中返回命令响应。

从我的角度来看,还没有必要进行交易。定期窥视队列是幂等的,因此如果多次发生,则不会中断。阅读工作细节也是如此。您应该期望在尝试阅读时作业详细信息消失,因为另一个节点可能更快并且已经处理了该作业。这是典型的竞争条件并尽早识别这些条件是有益的。

现在是关键部分:从队列中取出作业通常是BLPOP / BRPOP来保证原子性。在工作完成后,您不会说明作业详细信息应该发生什么。我假设删除哈希。因此,BLPOP队列和DEL作业哈希将成为将它们放入事务的候选者,但这取决于您的用例和条件。特别是至少一次和最多一次的行为。

答案 1 :(得分:1)

If you want to avoid the polling/peeking/race-conditions you could consider the following:

  1. maintain your existing queue as the generic input queue and have a lightweight triage type worker (one is probably enough but you could have more for redundancy) pop items from this queue, using a blocking pop to avoid polling, and based on your job allocation logic push a new item onto a separate queue per worker-type

  2. create multiple workers where each makes blocking pops from its own worker-type queue

One advantage of breaking your queue into multiple queues is that you get more visibility in your monitoring as you can check the length of each queue and see which types of workers are running slowly

It may not be suitable for production usage, but you may be interested in Disque, an in-memory distributed job queue, created by the same author as Redis (and based on Redis code).

相关问题