Php 寻找高效的任务调度器
我有几项工作需要完成X次,我有不同的员工,他们有自己的信息 除此之外,作业有一个日期,我想在一个作业到达下一个作业(从最早的作业开始)之前,将其处理Y次 工人只能处理一次作业 目前,我正在使用mysql数据库和php脚本作为工作人员来实现这一点,但似乎有一个瓶颈,大约每秒50个作业,我需要加快速度,所以我必须寻找替代方案 我的设置包含以下表格:Php 寻找高效的任务调度器,php,sql,multithreading,queue,scheduled-tasks,Php,Sql,Multithreading,Queue,Scheduled Tasks,我有几项工作需要完成X次,我有不同的员工,他们有自己的信息 除此之外,作业有一个日期,我想在一个作业到达下一个作业(从最早的作业开始)之前,将其处理Y次 工人只能处理一次作业 目前,我正在使用mysql数据库和php脚本作为工作人员来实现这一点,但似乎有一个瓶颈,大约每秒50个作业,我需要加快速度,所以我必须寻找替代方案 我的设置包含以下表格: jobs job_id | job_info | last_processed | times_executed | to_be_do
jobs
job_id | job_info | last_processed | times_executed | to_be_done
1 | 949461321 | 05-04-2014 00:14:56 | 192 | 1000
2 | 356454214 | 05-04-2014 00:14:57 | 8 | 200
3 | 321564642 | 05-04-2014 00:14:58 | 16 | 10000
4 | 546412131 | 05-04-2014 00:14:59 | 3 | 50
workers
worker_id | specific_information | status
1 | 4656439897543521456 | ok
2 | 6513165165465498498 | not_responsive
3 | 1046486479849870987 | not_responsive
4 | 6540498465494131131 | ok
5 | 6484654321654657498 | ok
除此之外,我还有以下设置(为了简单起见,这里使用pseudo_代码):
$jobs\u per\u run=10;//脚本运行时处理10个作业
$workers_/次运行=5;//在转移到下一个作业之前,对每个作业进行5次处理
对于$i=0$i<$jobs\u/次运行$i++{
SQL\u QUERY“按上次处理的ASC从执行时间
我希望这能解释我需要什么。我甚至不知道这到底是怎么叫的
我已经读过关于队列
、任务调度器
和消息传递系统
的内容,但这里的问题是,我需要由不同的工作人员按最后处理的任务排序多次执行作业
我想我提到的这些结构就像你扔进一些工作,它们一个接一个地被执行。在我的设置中,我想我需要从一开始就分配工人,然后举例来说,将1000次作业中的1次分配给不同的工人
这对我来说是个问题。有时工作人员并非始终可用,如果我现在让工作人员1与作业2一起排队,那么如果它在几分钟内被执行,那么它将毫无用处,并且工作人员1在当时不会响应。这就是为什么我在当前执行时将工作人员分配给作业
任务调度器
需要更易于管理,我需要能够暂停和恢复单个作业,并根据其“表行”中的不同标准为工人选择它们
我希望有300多名工人在排队系统上工作,不会出现问题。工人在大约1秒内执行一个作业,因此每秒完成300多个作业
理想情况下,我希望有一个类似AmazonAWS的云设置,其中我有一个实例作为任务调度器,还有几个实例执行作业
要达到这样的效果,最好的设置是什么?我现在使用的mysql解决方案似乎最方便、最合适。也许有一个更快的数据库可以用于具有类似功能的工作?关于您的查询,我注意到的一点是,您正在为
循环选择中的所有记录
而不是按使用顺序分组,因为我相信这就是您试图做的,并限制查询本身的作业数:
SELECT * FROM jobs
WHERE times_executed < to_be_done
ORDER BY last_processed ASC LIMIT 10
如果您计划将相同的工作分配给5名可用的员工,则仍然会限制您的查询:
SELECT * FROM workers
WHERE status = 'ok' AND worker_id NOT IN($processed_workers) LIMIT 5
现在在PHP中使用而不是FOR
,使用WHILE
浏览作业和工人记录集
另一件有趣的事情是每个作业的执行时间。看起来您的解决方案不是异步的,因此可能是作业本身造成了瓶颈,而不是查询 关于您的查询,我注意到的一点是,您正在为
循环选择中的所有记录
而不是按使用顺序分组,因为我相信这就是您试图做的,并限制查询本身的作业数:
SELECT * FROM jobs
WHERE times_executed < to_be_done
ORDER BY last_processed ASC LIMIT 10
如果您计划将相同的工作分配给5名可用的员工,则仍然会限制您的查询:
SELECT * FROM workers
WHERE status = 'ok' AND worker_id NOT IN($processed_workers) LIMIT 5
现在在PHP中使用而不是FOR
,使用WHILE
浏览作业和工人记录集
另一件有趣的事情是每个作业的执行时间。看起来您的解决方案不是异步的,因此可能是作业本身造成了瓶颈,而不是查询 我认为0MQ解释的策略可能会帮助您:
术语
首先,在你的问题中,“工作”一词有两种含义:
这就是“工作”,它意味着最终将产生最终结果的总工作量。我会继续称之为工作
需要运行某个流程的1次迭代。因此,这是一次工人会做一些事情。我称之为任务
因此,1个作业由X个任务组成
战略
- 有一个可以开始工作的呼吸机。这意味着将初始任务添加到“命令队列”
- 有任意数量的工人来做实际工作。单个工人将从“命令队列”中提取单个任务,对其进行处理,并将结果推送到“结果队列”
- 有一个从“结果队列”收集结果的接收器。它可以做两件事中的一件:
- 作业尚未完成(需要更多的迭代),因此它会将新任务推送到“命令队列”
- 作业已完成,因此它将最终结果存储在某个位置
为此,任务的有效负载需要包括作业需要运行的次数和已经运行的次数
不同类型的工作
这里有两种可能的方法:
有多种类型的工人。您还需要多个“命令队列”,每种类型的工作人员都需要从专用于该类型的队列中提取任务。水槽也需要安装
SQL_QUERY "SELECT * FROM jobs WHERE times_executed < to_be_done ORDER BY last_processed ASC LIMIT $jobs_per_run";
while (FETCH ROW) {
SQL_QUERY "SELECT * FROM workers WHERE status = 'ok' LIMIT $workers_per_run";
WHILE (FETCH ROW) {
IF job_was_executed_successfully {
SQL_QUERY "UPDATE jobs SET times_executed = times_executed + 1, last_processed = NOW() WHERE job_id = $job_id";
} else {
SQL_QUERY "UPDATE workers SET status = 'not_responsive' WHERE worker_id = $worker_id"
}
}
}