这是我的问题:每天晚上,我必须处理大约5万个后台工作,每个工作平均需要60秒。这些工作基本上是通过Facebook,Instagram和Twitter API来收集用户的工作。发布并将其保存在我的数据库中。这些工作由sidekiq处理。
首先,我的设置是:
:concurrency: 5
中 sidekiq.yml
我的pool: 5
database.yml
RAILS_MAX_THREADS
在我的Web服务器( puma )配置中设置为5.
我的理解是:
我的网络服务器(rails s
)将使用最多5个线程,因此最多可以连接到我的数据库5个,这是正常的,因为连接池设置为5。
我的sidekiq进程将使用5个线程(,因为并发设置为5 ),这也可以,因为连接池设置为5。
为了在同一时间处理更多作业并减少处理所有作业的全局时间,我决定将sidekiq并发性增加到25.在生产中,我配置了一个Heroku Postgres标准数据库,最大连接数为120 ,确保我能够使用Sidekiq并发。
因此,现在的设置是:
:concurrency: 25
中 sidekiq.yml
我的pool: 25
database.yml
RAILS_MAX_THREADS
在我的Web服务器( puma )配置中设置为5.
我可以看到25名sidekiq工人正在工作但是每份工作都花费更多时间(有时超过40分钟而不是1分钟)!?
实际上,我一直在做一些测试,并意识到使用sidekiq并发性为5,10或25处理我的作业50会产生相同的持续时间。好像不知怎的,在某个地方出现了5个连接的瓶颈。
我已经检查了Sidekiq文档和其他一些关于SO的帖子(sidekiq - Is concurrency > 50 stable?,Scaling sidekiq network archetecture: concurrency vs processes),但我还没有能够解决我的问题。
所以我想知道:
是我对rails database.yml
连接pool
和sidekiq concurrency
的理解吗?
设置这些参数的正确方法是什么?
答案 0 :(得分:0)
把它放在这里以防其他人可以使用一个快速、非常通用的指针:
有时增加并发工作器的数量可能不会产生预期的结果。
例如,如果任务数量和核心数量之间存在很大差异,调度程序会不断切换您的任务,实际上并没有太多收获,作业将花费大致相同或一点点更多时间。
这是有关作业调度如何工作的相当有趣的阅读的链接https://en.wikipedia.org/wiki/Scheduling_(computing)#Operating_system_process_scheduler_implementations
还有其他方面需要考虑,例如数据存储访问,您的工作人员是否使用相同的表?它是否由锁定整个表的存储引擎支持,例如 MyISAM?如果是这样的话,如果你有 100 个工人同时运行,以及足够的 RAM 和内核,它们都将排队等待正在运行的任何查询以释放表上的锁,它们都没有关系打算与之合作。 这也可能发生在使用 InnoDB 等引擎的表上,它不会在写入时锁定整个表,但您可能有不同的工作人员访问相同的行(InnoDB 使用行级锁定)或只是一些不锁定的大索引但放慢桌子。
我遇到的另一个问题与 Rails(我假设您正在使用)有关,在某些情况下会对 RAM 造成相当大的损失,因此您可能还想查看您的内存占用情况。
我的建议是打开日志记录并查看数据,您的员工在何处花费的时间最多?它是否在网络层(不太可能)上,是否正在等待访问核心?从您的数据存储读取/写入?你的机器换了吗?