繁体   English   中英

运行多个delayed_job的Rails - 锁定表

[英]Rails running multiple delayed_job - lock tables

嘿。 我使用delayed_job进行后台处理。 我有8个CPU服务器,MySQL和我启动7个delayed_job进程

RAILS_ENV=production script/delayed_job -n 7 start 

Q1:我想知道是否有可能2个或更多个delayed_job进程开始处理相同的进程(数据库delayed_jobs中的相同记录行)。 我检查了delayed_job插件的代码但是找不到它应该的方式的锁定指令(没有锁定表或SELECT ... FOR UPDATE)。

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

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

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:对于8CPU服务器,7个delayed_jobs是否是一个好的数字? 为什么是/否。

这是10倍!

我认为你的问题的答案在'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名工人是一个很好的起点,因为工人是单线程的,你应该为每个核心运行一个。 根据您的设置,或多或少的工人会更好。 这很大程度上取决于你的工作。 利用多核的工作优势? 或者你的工作大部分时间都在等待外部资源? 您已尝试不同的设置,并查看所有相关资源。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM