嘿。我使用delayed_job进行背景处理。我有8个CPU服务器,MySQL,然后开始7个delayed_job进程

RAILS_ENV=production script/delayed_job -n 7 start 

Q1:我想知道有可能有2个或多个delayed_job进程开始处理相同的过程(数据库delayed_job中的相同记录行)。我检查了delayed_job插件的代码,但找不到应该以某种方式找到锁定指令(没有锁表或选择...用于更新)。

我认为每个过程都应在执行Lock_by列上的更新之前锁定数据库表。他们只需更新locked_by字段即可锁定记录(更新delayed_jobs set locked_by ...)。真的足够了吗?不需要锁定?为什么?我知道该更新的优先级高于选择,但我认为这在这种情况下没有效果。

我对多线程状况的理解是:

Process1: Get waiting job X. [OK]
Process2: Get waiting jobs X. [OK]
Process1: Update locked_by field. [OK]
Process2: Update locked_by field. [OK]
Process1: Get waiting job X. [Already processed]
Process2: Get waiting jobs X. [Already processed]

我认为在某些情况下,更多的工作可以获得相同的信息,并可以开始处理相同的过程。

Q2: 7 delayed_jobs是8CPU服务器的好数字吗?为什么是/不。

THX 10X!

有帮助吗?

解决方案

我认为您的问题的答案是在“ lib/delayed_job/job.rb”的第168行中:

self.class.update_all(["locked_at = ?, locked_by = ?", now, worker], ["id = ? and (locked_at is null or locked_at < ?)", id, (now - max_run_time.to_i)])

在这里,仅执行该行的更新,如果没有其他工人已经锁定了作业,并且如果表格更新,则将检查。表锁或类似(顺便说一句,将大大降低应用程序的性能),因为您的DBMS确保单个查询的执行是从其他查询中隔离的。在您的示例中,Process2无法获取作业X的锁定,因为它在且仅在没有锁定之前就更新了作业表。

在您的第二个问题上:这取决于。在8个CPU服务器上。这是为这项工作专门的,有8个工人是一个很好的起点,因为工人是单线线,您应该为每个核心运行一个。根据您的设置,更多或多或少的工人会更好。这在很大程度上取决于您的工作。利用您的工作优势对Mutiple内核?还是您的工作大部分时间都等待外部资源?您进行了不同的设置实验,并查看所有涉及的资源。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top