Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/287.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_Mysql_Transactions_Process_Innodb - Fatal编程技术网

Php 什么是队列访问并发解决方案?

Php 什么是队列访问并发解决方案?,php,mysql,transactions,process,innodb,Php,Mysql,Transactions,Process,Innodb,我试图找出实现排队系统的困难。我知道如何实现基本队列,因此我将结合一些背景介绍一下我的目标: 我将实现一个队列,其中消息将被放置,这将来自多个用户,消息将被安排在用户定义的时间发布,允许多次出现,精度为分钟,从UI的角度来看,我将限制:每分钟或每小时发生一次,但我希望系统仍然能够处理这个问题 下面是我的问题: 最终,我可能会遇到这样的情况,也可能不需要在当前时间发布很多消息,我希望运行多个进程—一个脚本的多个实例—一次从队列中获取[x,10,25]个消息并对其进行处理。问题是:如何做到这一点,使

我试图找出实现排队系统的困难。我知道如何实现基本队列,因此我将结合一些背景介绍一下我的目标:

我将实现一个队列,其中消息将被放置,这将来自多个用户,消息将被安排在用户定义的时间发布,允许多次出现,精度为分钟,从UI的角度来看,我将限制:每分钟或每小时发生一次,但我希望系统仍然能够处理这个问题

下面是我的问题: 最终,我可能会遇到这样的情况,也可能不需要在当前时间发布很多消息,我希望运行多个进程—一个脚本的多个实例—一次从队列中获取[x,10,25]个消息并对其进行处理。问题是:如何做到这一点,使每个实例处理唯一的消息,而不处理其他实例已经在处理的内容?我担心当前的连接,如何锁定记录,以及其他我可能没有想到的事情

我将使用的技术是PHP和MySQL。我正在寻找一些解决上述问题的方法,我应该在搜索中使用的术语,真实世界的例子,想法,评论和想法

谢谢大家


我遇到的一个解决方案是使用Amazon简单队列服务。。。它承诺了独特的消息处理/锁定

好吧,我会这样做:

为消息创建表并再添加两个字段-PROCESS_ID和PROCESS_TIME。这些将在后面解释

给每个进程一个唯一的ID。它们可以像GUID一样在启动时生成,或者您可以自己分配它们,这样您就可以更容易地区分它们

当一个进程想要获取一组消息时,它会执行如下操作:

更新消息集process_id=$id,process_time=now,其中process_id为空限制20 从消息中选择*,其中process_id=$id 这将找到20条免费邮件并锁定它们。然后,它将找到它锁定的消息并对其进行处理。处理完每条消息后,将其删除

UPDATE语句应该是非常原子化的,特别是如果您使用InnoDB,它会自动将每个这样的语句包装到事务中。MySQL应该负责那里的所有并发性


PROCESS_TIME字段是可选的,但是您可以使用它来查看进程何时挂起。如果邮件被锁定的时间太长,您可以断定出现了问题并进行调查。

两种在线解决方案:

. 我想谷歌的解决方案要便宜得多,如果不使用太多,甚至可以免费使用

我还一直在考虑在PHP/MYSQL中实现队列,并考虑使用:

mysql来实现某种锁。 将队列放入MYSQL数据存储中,因为内存队列比磁盘队列快得多。但是,当计算机崩溃时,您有丢失数据的风险。 用于与流程进行通信。
你可以扭转这个问题

而不是同时从队列中取出东西的问题。一旦获得所有信息,立即发布。但发布时要遵守一条规则,即在某个时间之前,它是不可见的。这样做可以帮助您避免锁定/争用问题。

查看消息队列。它有PHP客户端。Beanstalkd与Drop不同的一个很好的特性是,您可以延迟消息。也就是说,您可以将消息发布到队列,直到X秒过去,消息才会传递到客户端


Beanstalkd确实有一个很大的缺点:它是一个内存队列。这意味着,如果它或您的计算机崩溃,那么队列将为空,内容将丢失。持久性是beanstalkd下一版本计划使用的一项功能。

我的理解是正确的:MySQL应该按照接收到的顺序处理每个更新,而且听起来如果同时接收到两个更新,MySQL应该自己内部处理,有人对此有文档链接吗?请查看MySQL文档中关于InnoDB的部分。注意有关交易的部分。然而,我认为,但我不确定,即使在MyISAM没有事务支持的情况下,这是否也能起作用。其思想是,即使两个UPDATE语句可以同时运行,它们也肯定不能同时访问同一行。如果他们愿意,这将造成重大混乱。但如果他们不能,那么你已经安全了。您无法准确预测UDPATE将影响哪些行,但您知道没有两个更新会冲突-这在您的情况下就足够了。我猜使用此数据库模式,您将大量轮询队列中的消息?否则您会怎么想?不过应该没那么糟糕——MySQL应该能够将这个表完全保存在RAM中。如果它变得太大,t
当你已经遇到更严重的问题时…@Vilx,我相信在插入数据时查询缓存会被刷新。此外,进程P1如何知道进程P2何时在队列中插入消息。将处理P1轮询表。因为我认为当很多当前用户执行msql语句时,表会被阻塞很多??我认为这是一个非常甜蜜的解决方案,如果只有几个用户使用它,但我认为它会运行缓慢,否则。我喜欢它。。。有趣的想法,我一定会记住这一点作为解决方案。。。但我的情况略有不同,will将与API交互,将消息实际发布到第三方系统。该系统现在已经有一段时间了:-b使用binlog将作业保留在中的持久存储上。启动后,beanstalkd将恢复中存在的任何binlog,然后在正常操作期间,将新作业和状态更改附加到binlog中。很酷,谢谢。然后我将升级所有beanstalkd实例。