大多数nosql解决方案只使用最终的一致性,并且鉴于DynamoDB将数据复制到三个数据中心,如何保持读写后一致性?
这种问题的一般方法是什么?我认为这很有趣,因为即使在MySQL中,复制数据也是异步复制的。
答案 0 :(得分:3)
我将使用MySQL来说明答案,因为你提到它,但很明显,我们都没有暗示DynamoDB在MySQL上运行。
在具有一个MySQL主服务器和任意数量的从服务器的单个网络中,答案似乎非常简单 - 为了最终的一致性,从随机选择的从服务器获取答案;对于读写后一致性,总是从主控器获取答案。
即使在MySQL中,复制数据也是异步复制的
该声明有一个重要的例外,我怀疑它更接近DynamoDB的实际情况,而不是其他任何替代方案:在兼容MySQL的Galera cluster中,主服务器之间的复制是同步的,因为主服务器在提交时协作处理每个事务,并且无法提交给所有主服务器的事务也会在主服务器上发生错误。这样的集群在技术上只能运行2个节点,但不应少于3个节点,因为当集群中存在拆分时,任何发现自身或小于原始集群大小一半的组的节点都将滚动它本身就是一个无害的小球并且拒绝服务查询,因为它知道它是孤立的少数,它的数据不再可信。所以在这样的分布式环境中有三个is一些神奇的数字,以避免灾难性的split-brain condition。
如果我们假设DynamoDB中的“three geographically-distributed replicas”都是“主”副本,那么它们可能与您在Galera中找到的同步主线的逻辑相同,因此解决方案基本相同因为该设置还允许任何或所有主设备仍然使用MySQL本机复制具有传统的对向异步从设备。不同之处在于,如果您想要写后一致性,则可以从当前连接到群集的任何主服务器中获取,因为它们都是同步的;否则从奴隶那里取货。
我能想到的第三种情况类似于循环复制配置中的三个地理位置分散的MySQL主服务器,它再次支持每个主服务器的子服务器,但是还有主服务器不同步的其他问题。没有冲突解决能力 - 对于这个应用程序根本不可行,但是出于讨论的目的,如果每个“对象”具有某种高度精确的时间戳,则仍然可以实现该目标。当需要读写后一致性时,这里的解决方案可能是服务于响应的系统轮询所有主控器以找到最新版本,在所有主控器被轮询之前不返回答案,或者从从器件读取最终的一致性。
基本上,如果有多个“写主”,那么主人似乎别无选择,只能在提交时进行协作,或者在一致阅读时进行协作。
有趣的是,我认为,尽管有一些抱怨,你可以在网上查看有关DynamoDB中两个读一致性水平之间定价差异的信息,这个分析 - 尽管与DynamoDB内部的现实脱节了是 - 似乎证明了这种差异的合理性。
最终一致的只读副本本质上是无限可扩展的(即使使用MySQL,主设备可以轻松地为多个从设备提供服务,每个设备也可以轻松地为多个从设备提供服务,每个设备都可以服务多个... ad infinitum )但是read-after-write并不是无限可扩展的,因为根据定义它似乎需要一个“更权威”的服务器的参与,无论具体意味着什么,从而证明更高的读取价格需要那种一致性的地方。
答案 1 :(得分:0)
我知道我问这个问题很久以后我就回答了这个问题,但我认为可以提供一些有用的信息......
在分布式数据库中,“主”的概念不再特别相关(至少对于读/写)。每个节点都应该能够执行读写操作,以便随着机器数量的增加读/写性能提高。如果您希望在写入后立即读取正确,则写入并随后读取的计算机数量必须大于系统中计算机的总数。
示例:如果您只写入1台计算机,则必须从所有计算机上读取,以确保您的数据不会过时。或者,如果您写入2台计算机(在本例中为仲裁),您可以执行仲裁读取并保证您的数据是最近的。
注意:当系统中的一部分节点崩溃时,这些假设会发生变化。
答案 2 :(得分:0)
我会确切地告诉您 DynamoDB 如何做到这一点。不用猜了。
为了向客户端确认写入请求,写入必须在该分区的三个存储节点中的两个节点上是持久的。两个存储节点之一必须是该分区的领导节点。第三个存储节点也可能会更新,但万一发生了某些事情,可能不会。 DynamoDB 会尽快更新。
当您请求强一致性读取时,该读取来自项目所在分区的领导者存储节点。