【问题标题】:Is there a way to execute a blocking get() call in Google Cloud Datastore?有没有办法在 Google Cloud Datastore 中执行阻塞 get() 调用?
【发布时间】:2020-06-12 05:34:27
【问题描述】:

我有一个需要以下操作的操作:

  1. 使用 Google Cloud Datastore 从密钥获取实体
  2. 资源(CPU/内存)密集型工作大约 10 秒
  3. 使用 Google Cloud Datastore 中的结果更新实体

理想情况下,为了最大程度地减少资源使用,如果已经有另一个工作人员正在处理 #2,我什至不希望程序开始执行 #2。

这意味着get() 调用将阻塞,直到没有其他人处理#2。

我从docs 和对数据存储区的Transaction 进行试验的理解是,在调用commit() 之前不会进行任何争用检查。只有这样才会引发错误并发生回滚。但这意味着每个工人在意识到其他人已经在做这项工作之前,都会执行昂贵的步骤 2。

有没有办法让get() 调用阻止其他人使用该密钥进行交易?

this article 中,他们使用了内存缓存。但是,如果可能的话,我更愿意将其保留在 Cloud Datastore 中,以尽量减少额外的基础架构。

【问题讨论】:

  • 这是实时过程还是批处理过程?在哪个组件上运行您的工作负载?
  • 这是一个实时过程。将有 N 个复制的应用程序实例来服务请求,每个实例都可以从 Datastore 中 get()/put() 并运行 CPU/内存密集型工作。我们想要阻止的原因是我们不会意外地让许多应用实例同时执行相同的工作。
  • 好的,您想防止多次处理同一数据,而不是同时占用大量计算内存。最后,您想将数据存储用作信号量,不是吗?
  • 一个信号量,但它也是从中获取和插入数据的地方。因此,我们的目标是找到一种以这种方式使用它的方法,而不是带来额外的工具来管理锁定。

标签: python multithreading google-cloud-platform google-cloud-datastore


【解决方案1】:

事务的目标是准备写入,然后在事务提交时有效写入,或者在回滚时取消更改。

不阻塞读,只有写操作。

你有两个解决方案:

  1. 您必须将实体 ID 存储在某处,例如内存存储中。
  2. 您可以依靠您的处理持续时间并执行此过程

    • 获取实体
    • 在您的实体中写一个字段(任何人)
    • 设置写入持续时间的超时,例如设置为 500 毫秒。 (在 Go 中很容易做到,我不知道其他语言)。如果达到超时,则表示该实体上已在进行事务,请跳过该实体。如果没有,请继续
    • 创建交易
    • 执行密集的过程
    • 写出结果
    • 提交事务

但是,在这两种情况下,如果同时发生,您仍然存在竞争条件

【讨论】:

    猜你喜欢
    • 2017-08-05
    • 1970-01-01
    • 1970-01-01
    • 2019-10-20
    • 1970-01-01
    • 2012-04-13
    • 2020-04-15
    • 2022-08-24
    • 1970-01-01
    相关资源
    最近更新 更多