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

如何有效地在扳手中创建强有序序列?

  •  2
  • SoftMemes  · 技术社区  · 6 年前

    GoogleSranger建议不要使用时间戳或序列号之类的东西作为主键或索引的初始部分,这基于体系结构是有意义的。但是,对于我的需求,我确实需要某种方法来确保严格的行顺序。

    i_m使用扳手建模事件(如事件源)。每个事件都有一个类别、一个流ID,用于标识需要严格按照相互关系排序的事件序列,以及一些有效负载字段——从这里开始,我将忽略实际有效负载。

    天真地说,这将被建模为:

    | Category    | STRING       |
    | Stream Id   | STRING       |
    | Sequence Nr | INT64        |
    

    (使用由类别、流ID、序列号组成的主键)这将确保一个流的事件顺序是强的。现在,由于一些类别有很多与之相关的事件,而扳手的最佳实践是在高位上有差异,所以最好将其颠倒过来。每个“流”将包含相当少的事件(数千个而不是数百万个),并将一起读取,以便更好地分布数据,并鼓励属于一个流的事件的位置:

    | Stream Id   | STRING       |
    | Category    | STRING       |
    | Sequence Nr | INT64        |
    

    但是,由于我希望能够附加事件而不必读取当前状态来查找当前序列号,所以我宁愿使用时间戳。

    | Aggregate Id | STRING      |                         | 
    | Category     | STRING      |                         |
    | Timestamp    | TIMESTAMP   | allow_commit_timestamp  |
    

    扳手内置了一个提交时间戳,在实际处理事务时标记它。但最后的问题是:

    即使我在一个事务中提交多个事件,是否可以如上所述表示数据并获得唯一的提交时间戳?

    如果没有,是否可以通过添加额外的列来确保严格的排序?

    这个 documentation 声明“提交时间戳值不保证是唯一的。写入不重叠字段集的事务可能具有相同的时间戳。写入重叠字段集的事务具有唯一的时间戳。”—但我不太清楚在此上下文中什么是“字段集”。

    文档还指出,“提交时间戳使创建changelog更容易,因为时间戳可以强制更改日志条目的顺序。”但不清楚在多个并发编写器或多个事件同时写入的情况下,提交时间戳具有强制顺序的保证是什么。时间。

    1 回复  |  直到 6 年前
        1
  •  2
  •   RedPandaCurios    6 年前

    如果在同一个事件中有多个事件 交易 然后它们都将具有相同的提交时间戳。

    字段是表格单元格(一行中有一个列值)。因此,在这个上下文中,“不重叠的字段集”基本上意味着单独的行,因为其中一个字段 提交时间戳!

    两个独立事务,一个更新行“r1”,一个更新行“r2”,位于同一个表上 可以 理论上,提交时间戳与它们不重叠的时间戳相同。

    即使我在一个事务中提交多个事件,是否可以如上所述表示数据并获得唯一的提交时间戳?

    在您给出的示例中,您在主键中使用提交时间戳,那么不,您将无法在单个事务中向同一个流ID/类别对添加多个事件,因为它们具有相同的时间戳,因此也具有相同的主键。

    如果没有,是否可以通过添加额外的列来确保严格的排序?

    如果使用提交时间戳的组合 每个(stream_id,category,timestamp)元组都有一个序列号,然后您可以在单个事务中保持严格的顺序:

    为同一事务中的每个(stream_id,category)对增加一个从0开始的序列号。 然后提交时间戳将确保不同事务之间的顺序,序列号将确保顺序 在内部 交易…