Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 寻找高效的任务调度器_Php_Sql_Multithreading_Queue_Scheduled Tasks - Fatal编程技术网

Php 寻找高效的任务调度器

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

我有几项工作需要完成X次,我有不同的员工,他们有自己的信息

除此之外,作业有一个日期,我想在一个作业到达下一个作业(从最早的作业开始)之前,将其处理Y次

工人只能处理一次作业

目前,我正在使用mysql数据库和php脚本作为工作人员来实现这一点,但似乎有一个瓶颈,大约每秒50个作业,我需要加快速度,所以我必须寻找替代方案

我的设置包含以下表格:

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"
            }
        }
    }