Aerospike ACID - 如何知道超时交易的最终结果?

Aerospike ACID - How to know the final result of the transaction on timeouts?

我是 Aerospike 新手。

我想知道在所有可能的超时情况下,如link所述:

https://discuss.aerospike.com/t/understanding-timeout-and-retry-policies/2852

  1. Client can’t connect by specified timeout (timeout=). Timeout of zero means that there is no timeout set.

  2. Client does not receive response by specified timeout (timeout=).

  3. Server times out the transaction during it’s own processing (default of 1 second if client doesn’t specify timeout). To investigate this, confirm that the server transaction latencies are not the bottleneck.

  4. Client times out after M iterations of retries when there was no error due to a failed node or a failed connection.

  5. Client can’t obtain a valid node after N retries (where retries are set from your client).

  6. Client can’t obtain a valid connection after X retries. The retry count is usually the limiting factor, not the timeout value. The reasoning is that if you can’t get a connection after R retries, you never will, so just timeout early.

在所有提到的超时场景中,在什么情况下我可以绝对确定交易的最终结果是FAILED?

Aerospike 是否提供任何东西,即如果客户端不响应则回滚事务?

在最坏的情况下,如果我不能确定最终结果,我怎么能确定交易的最终状态?

非常感谢。

编辑: 我们想出了一个临时解决方案:

为该记录保留一个 [generation -> value read] 的映射(可能是后台线程不断读取记录等),然后在超时时,我们会定期检查映射(key = 预期的生成)以查看真正的写入值是否实际上是放置在地图上的值。如果相同则表示写入成功,否则表示写入失败。

大家觉得有必要这样做吗?还是有别的办法?

最近的客户端将提供一个额外的超时标记,称为 "in doubt"。如果为 false,则您确定交易没有成功(客户端甚至无法连接到节点,因此无法发送交易)。如果为真,则仍然存在不确定性,因为客户端会发送交易但不知道它是否已到达集群。

您也可以考虑查看 Aerospike 的 Strong Consistency 功能,它可以帮助您的用例。

首先,超时不是您应该关注的唯一错误。较新的客户端有一个与错误关联的“inDoubt”标志,表明写入可能已应用也可能未应用。

没有内置的方法可以将不确定的交易解决为确定的答案,并且如果网络被分区,则 AP 中没有办法严格解决不确定的交易。 'Strong Consistency'模式确实存在严格的方法,可以使用相同的方法来处理常见的AP场景,但它们在分区下会失败。

我用过的方法如下:

  1. 每条记录都需要一个list bin,list bin将包含最后N个交易id。
    • 对于我的用例,我为每个客户端提供了一个唯一的 2 字节标识符——每个客户端线程都有一个唯一的 2 字节标识符——并且每个客户端线程都有一个 4 字节的计数器。因此,一个特定的交易 ID 看起来会从 2 个 ID 和计数器中屏蔽一个 8 字节的标识符。
  2. * 使用 getHeader api 读取记录元数据 - 这避免了从存储中读取记录箱。
    • 注意 - 我的用例不是增量,所以我实际上必须读取记录并使用生成检查进行写入。这种模式对于计数器用例应该更有效。
  3. 使用操作和gen-equal to the read generation with the these operations: increment the integer bin, prepend to the list of txns, and trim txns 列表写入记录。您会将交易 ID 添加到您的 txns 列表中,然后 trim 将列表添加到您选择的列表的最大大小。
    • N 需要足够大,以便记录可以确保有足够的时间在密钥争用的情况下验证其事务。 N 会影响记录的存储大小,所以选择太大会占用磁盘资源,选择太小会导致算法无效。
  4. 如果交易成功,那么您就完成了。
  5. 如果交易是 'inDoubt' 则读取密钥并检查 txns 列表以查找您的交易 ID。如果存在,那么您的交易 'definitely succeeded'.
  6. 如果您的交易 ID 不在 txns 中,请使用从步骤 5 中读取返回的生成重复步骤 3。
  7. Return 到第 3 步 - 除了在第 5 步 'generation error' 之外,还需要考虑 'in-doubt' 因为它可能是最终应用的先前尝试。

同时考虑到第5步读取记录,在txns中没有找到transaction-id,不能保证交易'definitely failed'。如果你想保持记录不变但有一个 'definitely failed' 语义,你需要观察到这一代已经超过了前一个写入的 gen-check 策略。如果没有,您可以用触摸替换步骤 6 中的操作 - 如果它成功,那么初始写入 'definitely failed' 如果您遇到生成错误,您将需要检查您是否与初始的应用程序竞争事务初始写入现在可能有 'definitely succeeded'.

同样,'Strong Consistency' 提到的 'definitely succeeded' 和 'definitely failed' 是准确的陈述,但在 AP 中,这些陈述有失败模式(尤其是在网络分区周围)。