【问题标题】:Assigning resources in PHP without letting two people access在不让两个人访问的情况下在 PHP 中分配资源
【发布时间】:2019-08-30 19:41:25
【问题描述】:

我有一个将给定资源分配给用户的系统。每天有成千上万的人访问这个系统。

在包含这些资源记录的数据库表中,我们有一列让我们知道该资源是否已分配。

当有分配资源的 API 请求进入时,我们会运行查询以查找未分配的资源。下一行代码是检查是否返回 false,以便我们可以显示错误。之后的下一行 if 将该资源锁定给该用户。我们在查找和分配之间最多讨论 1-2 毫秒。

我担心随着流量的增加,有可能不止一个用户返回相同的资源。我们有一个确定性算法,每次我们请求时都会返回相同的资源。

有没有一种好的方法可以确保两个人不可能返回同一个实例?

我的底层系统是 Laravel 5.8,在 AWS 中运行。负载平衡(应用 ELB)、多个应用服务器、多个工作服务器。 DB 是在 RDS 上运行的 Postgres。 Redis 用于缓存和队列管理。

【问题讨论】:

  • 阅读乐观和悲观锁定策略,并选择最适合您情况的一种。就计算机而言,1-2 毫秒是一个微小的永恒。对你来说,这似乎没什么,但对于一台运行在纳秒级的机器来说,就像站着十分钟一样。
  • 这引导我走上这条路。最终,我找到了一种方法来更新并在一个查询中进行选择,从而消除了任何可能的竞争条件。

标签: php laravel postgresql


【解决方案1】:

对于您的情况,您必须获得数据锁定;包含在数据库级别的事务中。 @tadman 是对的。但是,这些提示可能只是您的高负载系统的起点,因为据我了解,您需要获取昂贵的表锁。

因此,您可能会遇到下一个限制:并发事务;在最坏的情况下导致死锁。 您可以通过查看每分钟实际回答多少“分配请求”(您的 API 端点响应)来评估/估计这种风险。

如果有必要,我会拆分问题:

  • 有一个非常快的“未分配资源堆栈”:分配具体资源,在写入的时刻检查它是否仍然未分配/在池中;如果没有,则从“fast-stack”中获取下一个(或明确地是最后一个)
  • 异步填充快速堆栈,使其池大小始终“足够”

【讨论】:

    猜你喜欢
    • 2011-04-07
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多