1

我有一个客户端按顺序执行以下两个操作:

  1. 使用键“ABC123”创建一个新项目。
  2. 更新项目“newestKey”以包含值“ABC123”。

同时,第二个客户端正在运行以下程序:

  1. 读取item“newestKey”得到最新item的key K。
  2. 阅读 K 项。

第二个客户端是否有可能将“ABC123”作为“newestKey”,但在尝试加载项目“ABC123”时收到未找到错误,因为该项目尚未通过数据库传播?

换句话说,是否保证如果单个客户端对数据库进行两次写入,那么除非它也看到第一次写入,否则没有客户端将看到第二次写入?

4

1 回答 1

2

DynamoDB,尽管它的名字,并不是基于启发 Riak 的 Dynamo 白皮书,所以我不能谈论这部分问题。

使用 Riak,由于其可用性优先于一致性,因此保证相对较少。由于发生网络分区,客户端总是有可能读取包含键“ABC123”的对象(我们称之为“INDEX123”),但可能无法访问具有“ABC123”的服务器键/值对。

抛开网络严重受损或者服务器出现故障的情况,如果满足以下条件,那么我想不出客户端可以从“INDEX123”读取密钥“ABC123”但找不到密钥的场景/值对“ABC123”:

  • “ABC123”表示的键/值对是一个新的(而不是对具有相同键的旧对象的更新)
  • 所有操作(如 W、R 和 DW)的请求参数都为默认值 2(假设 N=3)
  • 你描述的两个操作都成功了

鉴于这些情况,这里有一个示例,说明服务器故障如何阻止客户端找到新的键/值对“ABC123”,但只是暂时的。

  1. 键/值对“ABC123”仅成功写入了它应该存在的两个主服务器。第三台服务器接收并确认写入,但由于磁盘故障或其他暂时性故障,它没有将值写入永久存储
  2. 包含键/值对的 2 台服务器中有 1失败
  3. 客户端请求键/值对,第一个响应请求的服务器是最初未能写入该键/值对的服务器和承担了在步骤 #2 中失败的服务器角色的故障转移服务器

此时,客户端将被告知不存在此类数据项,Riak 会在从具有副本的服务器接收到键/值对后,将其推送到不存在的服务器,以及任何未来的客户端请求会找到的。

这种修复操作称为“读取修复”。Riak 还具有主动的反熵机制,可以主动识别丢失/不一致的数据项并进行修复。

于 2013-12-09T03:31:47.010 回答