扳手中的下一个数字

时间:2018-07-25 17:39:34

标签: google-cloud-platform google-cloud-spanner

在Spanner中实施下一个数字例程的最佳方法是什么?

背景: 我们需要生成用于分配的序号。多个并发用户可以请求下一个号码。我们要确保没有用户收到相同的号码。

当前设计是要有一个表,其中包含最后使用的数字。将读取此列,将其递增一定数量,然后将其写出。事务中的读取是否会锁定要读取的行,直到事务完成?

2 个答案:

答案 0 :(得分:1)

在Cloud Spanner中处理序列时要非常小心,因为这可能是anti-pattern,可能会导致热点(即性能问题)。您真的确定您绝对需要序号吗?如果您只需要为人员分配唯一的标识符,则可以使用多种方法来执行此操作,而无需他们是连续的。例如,有关设计主键的信息,请参见此答案here

在问题的应用程序描述中,您说多个并发用户可能正在请求下一个号码。该值(next_number在整个应用程序中是否全局唯一?如果是这样,那么此值将成为热点,并可能限制数据库(和应用程序)的可伸缩性,因为这意味着数据库的性能将受到单台计算机可以在此单行上处理事务的速度的限制。您是否可以为数据库中的不同用户/实体使用不同的next_number?例如,每个用户都可以有一个next_number值吗?或者,您可以“分片”您的应用程序,以使next_number有成百上千的值?例如

CREATE TABLE MyTable(
  ShardNum INT64 NOT NULL,
  NextNumber INT64 NOT NULL
  .. etc..
) PRIMARY KEY (ShardNum, NextNumber)

请注意,我只是在讨论应用程序的性能。就正确性而言(即确保next_value是唯一的),Cloud Spanner ReadWrite事务确保两个读取器不会读取相同的next_number值(或更准确地说,两个读取器将读取)不允许两者都提交)。因此,只要您对Read-Modify-Commit流使用ReadWrite事务,就可以了(从正确性的角度来看)。

答案 1 :(得分:0)

在Spanner中实现下一个数字例程的最佳方法是什么?

就像在任何数据库中一样,要确保读写事务是相互独立的,原子的。

事务中的读取是否会锁定正在读取的行,直到事务完成?

  

锁定读写。这种交易类型是唯一支持将数据写入Cloud Spanner的交易类型。

     

属性   Cloud Spanner中的读写事务在单个逻辑时间点执行一组读取和原子写操作。

     

原子性,一致性,耐久性   属性,Cloud Spanner提供原子性(如果有任何写入   事务提交,它们都提交),一致性(数据库   交易后保持一致状态)和耐久性   (提交的数据保持提交状态。)

直接引自their documentation.

  

性能 >> 锁定

     

Cloud Spanner允许多个客户端同时与同一个数据库进行交互。为了确保   多个并发事务的一致性,Cloud Spanner使用   共享锁和排他锁的组合,用于控制对   数据。在事务中执行读取时,云   Spanner获取共享的读取锁,从而允许其他读取仍   访问数据,直到您的交易准备提交。当你的   事务正在提交并且正在应用写操作,   事务尝试升级到排他锁。它阻止新   数据上的共享读取锁,等待现有的共享读取锁   清除,然后放置一个排他锁以独占访问数据。

所以...我想,如果您像本文档末尾的读写示例那样进行操作,那么您会完全冷静。