我是Aerospike的新手。
我想知道在所有可能的超时情况下,如以下链接所述:
https://discuss.aerospike.com/t/understanding-timeout-and-retry-policies/2852
客户端无法在指定的超时 (timeout=) 之前连接。超时为零 表示未设置超时。
客户端在指定的超时 (timeout=) 之前未收到响应。
- 客户端在重试
服务器在自己的处理过程中使事务超时(默认 如果客户端未指定超时,则为 1 秒)。为了调查这一点, 确认服务器事务延迟不是瓶颈。
的 M 次迭代后超时,当没有错误时 由于节点故障或连接失败。
客户端在 N 次重试后无法获取有效节点(其中重试次数为 从您的客户端设置)。
客户端在 X 重试后无法获取有效的连接。重试 计数通常是限制因素,而不是超时值。这 推理是,如果在 R 重试后无法获得连接,则 永远不会,所以只是提前超时。
在提到的所有超时场景中,在什么情况下我可以绝对确定事务的最终结果是失败的?
Aerospike 是否提供任何功能,即在客户端没有响应时回滚交易?
在最坏的情况下,如果我不能确定最终结果,我怎么能确定交易的最终状态?
提前非常感谢。
编辑:我们想出了一个临时解决方案:
为该记录保留一个 [生成 -> 值读取] 的映射(可能是不断读取记录的后台线程等),然后在超时时,我们会定期检查映射(键 = 预期的生成),以查看真正的写入值是否实际上是放入映射的值。如果它们相同,则表示写入成功,否则表示写入失败。
你们认为有必要这样做吗?还是有其他办法?
首先,超时不是您应该关注的唯一错误。较新的客户端具有与错误关联的"inDoubt"标志,该标志将指示写入可能已应用,也可能未应用。
没有将未决事务解析为明确答案的内置方法,如果网络已分区,则 AP 中没有办法严格解析未决事务。"强一致性"模式确实存在严格的方法,相同的方法可用于处理常见的AP场景,但它们会在分区下失败。
我使用的方法如下:
- 每条记录都需要一个列表箱,列表箱将包含最后 N 个交易 ID。
- 对于我的用例,我为每个客户端提供了一个唯一的 2 字节标识符 - 每个客户端线程都有一个唯一的 2 字节标识符 - 每个客户端线程都有一个 4 字节计数器。因此,特定的事务 ID 看起来像会屏蔽 2 个 id 和计数器中的 8 字节标识符。
- * 使用 getHeader API 读取记录元数据 - 这样可以避免从存储中读取记录箱。
- 注意 - 我的用例不是增量,所以我实际上必须读取记录并使用代检查进行写入。对于计数器用例,此模式应该更有效。
- 使用以下操作使用操作和 gen-等于读取生成来写入记录:递增整数箱,附加到 txns 列表前面,并修剪 txns 列表。您将在 txns 列表中附加事务 ID,然后将列表修剪为所选列表的最大大小。
- N 需要足够大,以便记录可以确保有足够的时间来验证其事务,给定密钥上的争用。N 将影响记录的存储大小,因此选择太大将消耗磁盘资源,选择太小将使算法无效。
- 如果交易成功,那么您就完成了。
- 如果交易是"不确定",请阅读密钥并检查 txns 列表中的交易 ID。如果存在,那么您的交易"肯定成功"。
- 如果您的事务 ID 不在 txns 中,请对步骤 5 中的读取返回的生成重复步骤 3。
- 返回步骤 3 - 除了在第 5 步中,"生成错误"也需要被视为"可疑",因为它可能是最终应用的先前尝试。
还要考虑,读取步骤 5 中的记录并且在 txns 中找不到事务 ID 并不能确保事务"绝对失败"。如果您想保持记录不变,但具有"绝对失败"的语义,则需要观察生成通过上一次写入的生成检查策略。如果没有,您可以用触摸替换步骤 6 中的操作 - 如果成功,则初始写入"肯定失败",如果您收到生成错误,则需要检查您是否参加了初始事务初始写入的应用程序现在可能"绝对成功"。
同样,对于"强一致性",提及"绝对成功"和"绝对失败"是准确的陈述,但在 AP 中,这些陈述具有故障模式(尤其是在网络分区周围)。
最近的客户端将在超时时提供一个额外的标志,称为"有疑问"。如果为 false,则确定事务未成功(客户端甚至无法连接到节点,因此它无法发送事务)。如果为 true,则仍然存在不确定性,因为客户端会发送事务,但不知道它是否已到达集群。
您也可以考虑查看 Aerospike 的强一致性功能,它可以帮助您的使用案例。