在BigTable数据存储中,关于并发,如何“锁定”实体?

问题描述 投票:0回答:3

我不知道如何在 BigTable 数据存储中处理这个问题。

想象一下以下示例(只是为了解释概念。该示例与我的实际数据模型不符):

  • 我有一个计数器实体,用于跟踪我的数据存储中的事务数量。假设当前的“计数”是 100。
  • 现在两个网络请求同时读取这个值。
  • 两个 Web 请求都会添加一个新事务
  • 最后都更新计数器(到 101)。

计数器值现在不准确。应该是102。

对于如何处理这种情况有什么建议吗?我可以“锁定”计数器以确保第二个 Web 请求在第一个 Web 请求完成之前不会读取吗?

google-app-engine concurrency bigtable
3个回答
4
投票

您有多种选择:

  • 根据您的柜台和实体的范围,让交易实体成为柜台的子实体。然后,您可以插入交易并以交易方式更新计数器。请记住,这会将您的更新率限制为大约 1-5 QPS。
  • 如果您的计数不必 100% 准确,请分别插入实体并更新计数器(使用单实体事务)。您可以运行常规 cronjob 来重新计算实体数量,并在错误导致计数器不同步时修复计数器。
  • 您可以构建自己的有限的分布式事务支持

1
投票

除了 Nick 提供的选项之外,您还可以考虑对计数器进行分片。

保留多个计数器,并选择一个计数器进行更新,使得任何两个请求(理想情况下)不可能或(如果失败)不太可能同时选择同一个分片。

然后您还有更多选择。您可以使用分片作为父级进行交易(与单个计数器相比,这减少了争用),尽管最终您的新交易实体将具有任意选择的父级。或者不要理会交易,在这种情况下,您可能必须不时地修正计数,就像尼克的非交易选项一样。

要读取总计数,请将所有分片相加。您不会“同时”阅读所有这些内容,但这通常没问题。读取任何计数器,它可能会在您读取它和使用该值之间增加,因此该值实际上只是一个下限。添加碎片没有什么不同,只是可能需要更长的时间。


0
投票

目前,这种类型的整数增量可以通过利用

ReadModifyWriteRow
请求,通过对 BigTable 的一次调用来完成。这种类型的写入请求称为增量和追加

ReadModifyWriteRow
是功能,包装方法在客户端库中可用,代码示例

this github issues 时间轴来看,此功能似乎自 2018 年发布以来就已在某个地方可用。

© www.soinside.com 2019 - 2024. All rights reserved.