【发布时间】:2018-01-17 15:01:06
【问题描述】:
我有一个运行我们的网络服务请求的后台作业的守护进程。我们有 4 名工人同时运行。
有时一个作业会同时执行两次,因为两个工人决定运行该作业。为了避免这种情况,我们尝试了几件事:
- 由于我们的作业来自我们的数据库,我们添加了一个名为
executed的标志,以防止其他工作获取已经开始执行的作业;这并不能解决问题,有时我们数据库的延迟足以同时执行; - 在系统中添加了
memcached(所有工作人员都在同一个系统中运行),但不知何故,我们今天有同时运行的作业——memcached也不能解决多台服务器的问题。
下面是我们目前使用的逻辑:
// We create our memcached server
$memcached = new Memcached();
$memcached->addServer("127.0.0.1", 11211);
// Checkup every 5 seconds for operations
while (true) {
// Gather all operations TODO
// In this query, we do not accept operations that are set
// as executed already.
$result = findDaemonOperationsPendingQuery();
// We have some results!
if (mysqli_num_rows($result) > 0) {
$op = mysqli_fetch_assoc($result);
echo "Found an operation todo #" . $op['id'] . "\n";
// Set operation as executed
setDaemonOperationAsDone($op['id'], 'executed');
// Verifies if operation is happening on memcached
if (get_memcached_operation($memcached, $op['id'])) {
echo "\tOperation id already executing...\n";
continue;
} else {
// Set operation on memcached
set_memcached_operation($memcached, $op['id']);
}
... do our stuff
}
}
这类问题通常是如何解决的? 我在互联网上查找了一个名为 Gearman 的库,但我不相信当我们有多个服务器时它会解决我的问题。
我想到的另一件事是预定义一个守护程序以在插入时运行操作,并创建一个故障安全独占守护程序来运行由停止服务的守护程序设置的操作。
有什么想法吗?
谢谢。
【问题讨论】:
-
将表锁定在“findDaemonOperationsPendingQuery”和“setDaemonOperationAsDone”之间可以解决我的问题吗?
-
让我猜猜……你在使用 MyISAM?
-
不,我正在使用 InnoDb
标签: php mysql concurrency daemon