引用:http://gigaom.com/cloud/facebook-trapped-in-mysql-fate-worse-than-death/
已经进行了各种尝试 克服SQL的性能和 可扩展性问题,包括 嗡嗡作响的NoSQL运动爆发了 几年前到现场。 然而,它很快就被发现了 虽然NoSQL可能会更快 规模更好,它是以牺牲为代价的 ACID一致性。
等等 - 我读错了吗?
这是否意味着如果我使用NoSQL,我们可以预期交易会被破坏(虽然我敢说它的百分比非常低)?
答案 0 :(得分:8)
这实际上是真实的,但也有点虚假。这不是关于腐败,而是关于在(有限)时期看到不同的东西。
这里真实的是CAP theorem,它只是说明你只能选择以下三种中的两种:
传统的SQL系统选择放弃“分区容差”,其中许多(并非所有)NoSQL系统选择放弃“一致性”。
更精确:他们放弃了“强一致性”并选择了更加轻松的Consistency model,例如“Eventual Consistency”。
因此,从不同角度观察数据时,数据将保持一致,而不是马上。
答案 1 :(得分:5)
NoSQL解决方案通常旨在克服SQL的规模限制。这些规模限制由CAP theorem解释。理解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>
当然,上面的规则假设在此期间没有节点出现故障。为了确保P + C你需要更加偏执...
还有几乎无限数量的“实施”黑客 - 例如,如果存储层无法写入最小法定数量,则可能会使调用失败,但即使在返回后,仍可能继续将更新传播到其他节点成功。或者,它可能会放松语义保证并将版本控制冲突合并到业务层的责任(这是亚马逊的Dynamo所做的)。
不同的数据子集可以有不同的保证(即单点故障可能对关键数据没有问题,或者可以阻止写请求,直到写入副本的最小数量成功写入新版本)< / p>
解决90%案例的模式已经存在,但每个NoSQL解决方案都将它们应用于不同的配置中。这些模式类似于分区(基于稳定/散列或基于变量/查找),冗余和复制,内存缓存,分布式算法(如map / reduce)。
当您深入研究这些模式时,基础算法也相当普遍:版本向量,merckle树,DHT,八卦协议等。
答案 2 :(得分:1)
这并不意味着交易会被破坏。事实上,许多NoSQL系统根本不使用事务!有些NoSQL系统有时可能会丢失记录(例如MongoDB,当你“点击并忘记”插入而不是“安全”插入时),但通常这是一个设计选择,而不是你坚持使用的。
如果您需要真正的事务语义(可能正在构建银行会计应用程序),请使用支持它们的数据库。
答案 3 :(得分:1)
首先,在100%的时间内询问NoSql是否是100%ACID是一个毫无意义的问题。这就像问“狗100%的时间100%保护狗?”有些狗是保护性的(或者可以训练成型),如德国牧羊犬或杜宾犬。还有其他狗可以不关心保护任何人。
NoSql是运动的标签,而不是特定的技术。有几种不同类型的NoSql数据库。有文件商店,例如MongoDb。有图形数据库,如Neo4j。有一些键值商店,如cassandra。
其中每一项都有不同的用途。我使用的专有数据库可以归类为NoSql数据库,它不是100%ACID,但它不需要。这是一次写入,读取许多数据库。我认为它每季度(或每月一次?)建成一次,然后每天读取1000次。
答案 4 :(得分:1)
有许多不同的NoSQL商店类型和实现。它们中的每一个都可以在不同方面解决一致性和性能之间的权衡问题。您可以获得的最佳结果是可调框架。
从你引用的句子“很快被发现”明显是愚蠢的,这并不是一个令人惊讶的发现,而是一个具有深刻理论根源的事实。
答案 5 :(得分:0)
一般情况下,并不是任何给定的更新都无法保存或损坏 - 这显然对任何数据库都是一个非常大的问题。
他们在ACID上失败的地方是数据检索。
考虑一个NoSQL数据库,它可以在众多服务器上复制,以便为繁忙的站点提供高速访问。
让我们假设网站所有者使用一些新信息更新网站上的文章。
在此方案中的典型NoSQL数据库中,更新将立即仅影响其中一个节点。在其他节点上对站点进行的任何查询都不会立即反映更改。实际上,当数据在整个站点上复制时,尽管同时查询,但不同的用户可能会被给予不同的内容。数据可能需要一些时间才能在所有节点上传播。
相反,在符合事务ACID的SQL数据库中,数据库必须确保所有节点都已完成更新,然后才能允许其中的任何节点提供新数据。
这允许网站保留高性能和页面缓存,因为牺牲了任何给定页面在给定时刻绝对最新的保证。
事实上,如果你认为这样,DNS系统可以被认为是一个专门的NoSQL数据库。如果在DNS中更新域名,新数据可能需要几天时间才能在整个互联网上传播(取决于TTL配置)。
所有这些使得NoSQL成为网站内容等数据的有用工具,只要页面合理地是最新的,页面不一定是最新的和一致的并不一定重要。
另一方面,它确实意味着将NoSQL数据库用于需要一致性和最新准确性的系统是一个非常糟糕的主意。订单处理系统或银行系统绝对不是典型的NoSQL数据库引擎的好地方。
答案 6 :(得分:0)
NOSQL与数据损坏无关。它是关于从不同的角度查看您的数据。它提供了一些有趣的杠杆点,可以实现更容易的可扩展性故事,并且通常也可用。但是,您必须以不同的方式查看数据,并相应地编写应用程序(例如,接受BASE而不是ACID的后果)。大多数NOSQL解决方案都会阻止您做出可能使您的数据库难以扩展的决策。
NOSQL不适合所有事情,但ACID并不是最终用户视角下最重要的因素。只有我们的开发人员才能想象没有ACID保证的世界。
答案 7 :(得分:0)
您正在正确阅读。如果您拥有CAP的AP,则您的数据将不一致。用户越多,越不一致。由于拥有许多用户是您扩展的主要原因,因此不要指望不一致的情况很少见。您已经看到Facebook内外的数据弹出。想象一下,如果你遗漏了ACID,那对于亚马逊的股票库存数据会有什么影响。最终的一致性只是说你没有一致性的好方法,但你应该在不需要它的地方编写应用程序。某些类型的游戏和社交网络应用程序不需要一致性。甚至还有不需要它的业务线系统,但这些系统非常罕见。当你的客户拨打错误的账户金额或愤怒的扑克玩家没有得到他的奖金时,答案不应该是你的软件设计的方式。
正确工作的合适工具。如果每秒的事务少于几百万,则应使用一致的NewSQL或NoSQL数据库,如VoltDb(非并发Java应用程序)或Starcounter(并发.NET应用程序)。这些天没有必要放弃ACID。