gpt4 book ai didi

synchronization - Pyramid REST API : How do I handle concurrent data access safely?

转载 作者:行者123 更新时间:2023-12-03 14:12:42 24 4
gpt4 key购买 nike

我正在使用 Pyramid 为 Web 服务开发 REST API和 Cornice ;服务器端的数据使用 SQLAlchemy 处理和 MySQL .网络服务器是 nginx使用 uwsgi ,并且它被配置为运行多个 Python 进程:

[uwsgi]
socket = localhost:6542
plugins = python34
...
processes = 2 # spawn the specified number of workers/processes
threads = 2 # run each worker in prethreaded mode with the specified number of threads

问题

假设有一张表 customers在服务器端。使用 API 可以读取、修改或删除客户数据。除此之外,还有其他读取客户数据的 API 函数。

我可以同时发出多个 API 调用,然后竞争相同的客户资源:
# Write/modify the customer {id} data
curl --request POST ... https://some.host/api/customer/{id}
# Delete customer {id} and all of its associated data
curl --request DELETE https://some.host/api/customer/{id}
# Perform some function which reads customer {id}
curl --request GET ... https://some.host/api/do-work

本质上这是一个 Readers-Writers Problem ,但由于涉及多个进程,传统线程同步使用 locks/mutexes/semaphores不会在这里工作。

问题

我想了解为这种基于 Pyramid 的 Web API 实现锁定和同步的最佳方法,以便安全有效地处理上述示例中的并发调用(即没有不必要的序列化)。

解决方案 (?)
  • 我认为标记/标记客户 {id} 没有意义如locked因为 SQLAlchemy 缓存了这样的修改,并且 flush() 在这种情况下似乎不够原子?
  • This article描述使用 HTTP ETag管理共享资源。
  • 也可以使用 Redis作为 distributed lock manager用于包装 View 功能的自旋锁?
  • Pyramid 的 transaction manager 怎么样? ?
  • 最佳答案

    我假设您正在处理一个 MySQL 数据库,并且您的锁不需要覆盖其他资源(Redis、第三方 API 等)。我还假设您的客户端函数本身不需要处理事务数据(通过多个 API 调用保持 session ),您只是想防止并发 API 访问弄乱您的数据库。

    锁有两种,悲观锁和乐观锁。

    悲观锁定是大多数人通常通过锁定所知道的 - 您可以预先在代码中以编程方式创建和获取锁。这就是分布式锁管理器。

    乐观锁定是您可以轻松摆脱 SQL 数据库的原因。如果两个事务从同一资源竞争,数据库有效地注定了其中一个事务和应用程序框架(在本例中为 Pyramid + pyramid_tm)可以在放弃之前重试事务 N 次。

    从开发的角度来看,乐观锁定是更理想的解决方案,因为它不会给应用程序开发人员带来任何认知负担,以记住正确锁定资源或创建内部锁定机制。相反,开发人员依靠框架和数据库来重试和管理并发情况。然而,乐观锁定在 web 开发人员中并不为人所知,因为在广泛的 PHP 式环境中进行乐观锁定是很困难的,因为编程语言缺乏灵 active 。
    pyramid_tm实现乐观锁定解决方案,我建议您使用它或其他一些乐观锁定解决方案,除非您知道您不想使用的非常具体的原因。

  • pyramid_tm将事务生命周期与 HTTP 请求联系起来,从 Web 开发人员的角度来看非常自然
  • pyramid_tm可以将其他事件与成功的交易联系起来,例如pyramid_mailer仅当事务提交
  • 时才向用户发送电子邮件
  • pyramid_tm经过良好测试并基于 ZODB transaction事务管理器,自 2000 年初以来一直在生产中使用
  • 确保您的 SQLAlchemy session设置为 SERIALIZABLE SQL isolation级别 - 您从最高一致性模型开始。如果您知道 API 调用可以容忍它,您可以降低此性能要求 - 例如调用做统计只读分析。
  • 乐观锁定通常在“正常”大量读取中表现更好 - 很少发生冲突的写入工作负载(两个 API 调用更新同一个用户一次)。仅当存在冲突时才会触发事务重试惩罚。
  • 如果事务在 N 次重试后最终失败,例如在异常高负载情况下,这应该在 API 消费者端解决,告知服务器端数据已更改,用户必须再次验证或重新填写表单

  • 进一步阅读
  • Optimistic concurrency control in Wikipedia
  • SQLAlchemy + pyramid_tm example .注:Try to avoid global DBSession object and use request.dbsession instead .
  • Race condition incidence examples
  • ConflictResolver, Alternative, more low level, optimistic locking solution for SQLAlchemy, based on using Python functions as retryable context instead of full HTTP request
  • 关于synchronization - Pyramid REST API : How do I handle concurrent data access safely?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33934771/

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