NoSQL 100%ACID是100%的时间吗?

teo*_*eol 3 nosql

引用:http://gigaom.com/cloud/facebook-trapped-in-mysql-fate-worse-than-death/

已经有各种尝试来克服SQL的性能和可扩展性问题,包括几年前突然出现在场景中的值得关注的NoSQL运动.然而,很快发现虽然NoSQL可能更快并且扩展性更好,但它是以牺牲ACID一致性为代价的.

等等 - 我读错了吗?

这是否意味着如果我使用NoSQL,我们可以预期交易会被破坏(虽然我敢说它的百分比非常低)?

Nie*_*jes 8

它实际上是真的,但也有点虚假.这不是关于腐败,而是关于在(有限的)时期看到不同的东西.

这里真实的是CAP定理,它简单地说明你只能选择以下三个中的两个:

  1. 一致性(所有节点同时看到相同的数据)
  2. 可用性(保证每个请求都收到有关成功或失败的响应)
  3. 分区容差(尽管任意消息丢失,系统仍继续运行)

传统的SQL系统选择放弃"分区容差",其中许多(并非所有)NoSQL系统选择放弃"一致性".

更精确:他们放弃"强一致性"并选择更加宽松的一致性模型,如" 最终一致性 ".

因此,从不同的角度来看,数据将是一致的,而不是立即.


Add*_*dys 5

NoSQL解决方案通常旨在克服SQL的规模限制.这些规模限制由CAP定理解释.理解CAP是理解为什么NoSQL系统倾向于放弃对ACID的支持的关键.

所以让我用纯粹直观的术语解释CAP.首先,C,A和P是什么意思:

一致性:从外部观察者的角度来看,每个"交易"要么完全完成,要么完全回滚.例如,在进行亚马逊购买时,无论内部分区为子系统,购买确认,订单状态更新,库存减少等都应显示为"同步"

可用性:100%的请求已成功完成.

分区容差:即使系统中的节点子集不可用,也可以完成任何给定的请求.

从系统设计的角度来看,这些意味着什么?CAP定义的紧张是什么?

要达到P,我们需要复制品.很多人!我们保留的副本越多,即使某些节点处于脱机状态,我们所需的任何数据都可用的机会也越大.对于绝对"P",我们应该将每个数据项复制到系统中的每个节点.(显然在现实生活中我们在2,3等方面妥协)

要实现A,我们不需要单点故障.这意味着"主要/次要"或"主/从"复制配置会离开窗口,因为主/主要是单点故障.我们需要使用多个主配置.要实现绝对"A",任何单个副本必须能够独立于其他副本处理读取和写入.(实际上我们在异步,基于队列,仲裁等方面妥协)

为了实现C,我们需要在系统中使用"单一版本的事实".这意味着如果我写入节点A然后立即从节点B读回,则节点B应返回最新值.显然,在真正的分布式多主系统中不会发生这种情况.

那么,问题的"正确"解决方案是什么?它的细节实际上取决于您的要求,但一般的方法是放松一些约束,并妥协其他约束.

例如,要在具有n个副本的系统中实现"完全写入一致性"保证,读取数和写入数必须大于或等于n:r + w> = n.这很容易通过一个例子来解释:如果我将每个项目存储在3个副本上,那么我有几个选项来保证一致性:

A)我可以将项目写入所有3个副本,然后从3中的任何一个中读取并确信我正在获取最新版本B)我可以将项目写入其中一个副本,然后阅读所有3个副本并选择3个结果中的最后一个C)我可以写入3个副本中的2个,并从3个副本中的2个中读取,我保证我将在其中一个上有最新版本.

当然,上面的规则假设在此期间没有节点出现故障.为了确保P + C你需要更加偏执......

还存在几乎无限数量的"实现"黑客 - 例如,如果存储层无法写入最小仲裁,则可能会使调用失败,但即使在返回成功后,也可能继续将更新传播到其他节点.或者,它可能会放松语义保证并推动将版本控制冲突合并到业务层的责任(这是亚马逊的Dynamo所做的).

不同的数据子集可以有不同的保证(即单点故障可能对于关键数据是正常的,或者可以阻止写入请求,直到写入副本的最小数量成功写入新版本)

解决90%案例的模式已经存在,但每个NoSQL解决方案都将它们应用于不同的配置中.这些模式类似于分区(基于稳定/散列或基于变量/查找),冗余和复制,内存缓存,分布式算法(如map/reduce).

当您深入研究这些模式时,底层算法也相当普遍:版本向量,merckle树,DHT,八卦协议等.