gpt4 book ai didi

并发数据库调用的 PHP/Mysql 问题

转载 作者:可可西里 更新时间:2023-11-01 08:23:32 26 4
gpt4 key购买 nike

在 PHP 中使用 innoDB 表和 mysqli 包装器进行查询。

我们目前遇到一个问题,即每秒请求同一脚本 1,500 次的流量激增。

情况是,前 X 名访问脚本的用户中奖。

奖品是“奖品”表中的单个记录,其中包含 # 个已领取和 # 个已分配的计数。

一旦使用量>=分配量,我们将停止发放奖品。

正在发生的事情是,在脚本的其他实例可以更新该行之前,对脚本的许多请求同时读取该行,从而向他们每个人显示还有#个奖品等待领取。这导致我们奖励超过分配的金额。

关于如何规避此问题的任何想法?

最佳答案

是的,您描述的是典型的竞争条件。

一种解决方案是使用 SELECT...FOR UPDATE 在奖品表中的行上建立锁,然后再更新它。 InnoDB 将建立锁请求的顺序,使每个请求等待轮到它可以获取锁。

但是,这不是一个好的解决方案,因为它会导致每个用户的浏览器不停地旋转,等待响应。在服务器上,您很快就会得到每秒 1500 个锁定请求排队。即使每个 session 只需要 10 毫秒来执行 SELECT FOR UPDATE 和后续的 UPDATE(这已经非常雄心勃勃),但每秒仍需要 15.0 秒的工作。到第 2 秒时,您将有 30.0 秒的工作要做。

与此同时,用户看到他们的浏览器挂起,直到轮到他们为止。这几乎是一个设计的破坏者。

基本上,您需要一些解决方案来建立请求的顺序:

  • 全局
  • 原子
  • 异步

您可以让每个并发请求使用 AUTO_INCREMENT 键对表执行 INSERT,这将保证它们的顺序。然后一旦有 X 行,后续请求就不会费心插入更多行。

另一种方法是使用消息队列。每个请求只是将自己的请求插入队列。然后单个消费者从队列中拉出前 X 个请求,并向它们颁发奖品。队列中的其余请求将被丢弃,它们不会获得奖励。

关于并发数据库调用的 PHP/Mysql 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55009497/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com