代码之家  ›  专栏  ›  技术社区  ›  willem

在大表数据存储中,对于并发性,如何“锁定”一个实体?

  •  2
  • willem  · 技术社区  · 15 年前

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

    想象下面的例子(只是为了解释这个概念。示例与我的实际数据模型不匹配):

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

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

    对如何处理这种情况有什么建议吗?我可以“锁定”计数器以确保第二个Web请求 阅读 直到第一个Web请求完成?

    2 回复  |  直到 15 年前
        1
  •  4
  •   Nick Johnson    15 年前

    您有几个选项:

    • 根据计数器和实体的范围,将事务实体作为计数器的子实体。然后,您可以插入一个事务并更新计数器 transactionally . 请记住,这将您的更新率限制在1-5 qps左右。
    • 如果您的计数不必100%准确,请插入实体并单独更新计数器(使用单个实体事务)。您可以运行一个常规的cronjob来重新计算实体的数量,并在错误导致计数器不同步时修复计数器。
    • 你可以建立自己的 limited distributed transaction support .
        2
  •  1
  •   Steve Jessop    15 年前

    除了尼克给出的选择外,你还可以考虑把柜台切碎。

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

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

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