构建分布式系统很困难。 当您使用跨越星球的应用程序时,光速就阻碍了您要做的事情,使服务器和服务之间的数据复制变得复杂。 几乎有人在香港与巴黎人在同一时间在香港购买了一个小部件,但只有一个库存。 您如何知道向谁付款,以及谁告诉购买失败? 谁的购买最终记录在您的业务工具中?
微软的Azure驱动器在分布式系统设计中工作,为围绕无状态微服务构建的服务提供支持。 管理跨此结构工作的应用程序需要两件事:一种有效的处理消息传递流量的方法和一种大规模处理分布式数据的方法。
Microsoft Research在其Orleans虚拟actor框架上的工作处理了等式的消息传递方面,既可以在Xbox等服务中单独使用,也可以作为Azure Service Fabric中使用的actor /消息模式的基础。 同时,数据方面由Microsoft全球规模的分布式数据库Cosmos DB处理。
Cosmos DB是一项引人入胜的工作,尤其是当您将其视为某些非常复杂的计算机科学概念的实际实现时。 它不像其他云规模系统那样仅提供最终或强一致性模型,而是在其他三个模型之间更精确地映射了应用程序设计模式和意图,从而在准确性和延迟之间取得了平衡。 所有这五个一致性模型均具有较高的服务级别,可在不同实例之间快速复制数据并降低发生冲突的风险。 正是这些冲突导致了诸如同一项目的多次购买之类的问题,这些问题无法影响您的业务。
直到最近,仅通过允许对单个区域进行写入,同时允许从整个网络进行读取来解决冲突。 但是,现在,Cosmos DB可以处理在多个主机中进行写操作的多主机模式 。 这使服务更具可伸缩性,因为更新是由整个Cosmos DB网络处理的,同时仍支持服务的一致性模型。 应用程序可以将数据写入最近的节点,从而减少延迟,而Cosmos DB会维护其现有的SLA,因此应该不改变读取数据的速度。
有趣的是,当您开始查看Cosmos DB如何处理冲突解决方案时,可以随时写入任何副本。 像所有数据库一样,它必须处理三种类型的冲突:插入,替换和删除。 在具有相同索引的多个区域中同时插入记录时,会发生插入冲突。 替换冲突类似,尽管此处更新了现有记录。 同样,如果从一个区域中删除一条记录并从另一个区域中更新一条记录,则会发生删除冲突。
为了防止这些冲突,Cosmos DB实施了三种不同的机制:上次编写者获胜,用户定义的过程和异步。 这三个都可用于其SQL API,但只有一个可用于其NoSQL API。 您可以在设置集合时定义要使用的模型。
大多数操作由Last Writer Wins机制处理(NoSQL操作可用的唯一方法)。 每次写入都包含一个数值,该数值是使用Cosmos DB内置的函数在写入时生成的,并存储在该条目的冲突解决路径中,通常是来自处理该操作的服务器的时间戳。 如果发生冲突,则在插入或更新数据时,具有最大关联值的操作将获胜。 无论操作中有什么解决冲突的数据,删除总是赢。 在实践中,您不太可能拥有具有相同冲突解决路径的操作,但是如果这样做,Cosmos DB最终会融合为一个获胜者,但无法预测可能是哪个获胜者。
其他冲突解决方法使事情变得更加复杂,您将不得不在Cosmos DB中编写存储过程以使用其内部JavaScript函数来处理它们。
User-Defined Procedures方法基于Last Writer Wins触发您自己的自定义操作。 例如,在另一个过程确定哪个版本有效之前,创建一个存储所有冲突文档的集合,或者在将自定义逻辑应用于更新时自动存储所有新写入。 您可以选择代码提供的操作,具体取决于要存储的数据类型以及使用方式。 实际上,您可能会实现与OneDrive之类的服务类似的模型,其中应用程序中的冲突会提示用户重试操作或在保存数据之前更改某些关键信息。
异步方法更进一步,将所有冲突存储在可由应用程序处理的只读Feed中。 您可以通过CosmosDB API访问冲突供稿,并且可以对每种操作类型应用不同的操作。 通过处理冲突并异步处理它们,您可以将大多数操作的等待时间保持在尽可能低的水平,只有在发生冲突时才放慢速度。 结果是相对自由的数据流,当代码轮询冲突源并应用冲突解决规则时,将处理冲突。
那么,为什么Microsoft在Cosmos DB中实现了多个母版? 显而易见的答案是性能。 通过允许尽可能靠近用户的位置进行写操作,可以大大减少延迟。 将此功能与Azure Frontdoor等新的全局负载平衡工具结合使用,可以自动将用户数据定向到最近的Cosmos数据库实例。 来自英国的访问美国的用户无需通过大西洋回传数据,因此您既可以给他们提供他们期望的体验,又可以将带宽成本降至最低。
另一个诱人的前景是:多主模式可以使Microsoft将Cosmos DB带到网络边缘。 您不太可能在自己的Windows服务器上运行Cosmos DB,但是Azure现在有一个使其成为其自身边缘扩展的一部分的选项:在Azure Stack或Azure IoT Edge上运行。 还有可能将其用作新硬件的一部分,例如Data Box Edge数据上传工具,处理来自服务器的数据并将其作为云ETL服务的一部分上传到Cosmos DB。
借助在Azure Stack上运行的Cosmos DB,您可以快速从本地服务加载数据并使其在全球范围内可用。 大型零售商可以使用它来将其仓库库存控制系统扩展到其电子商务服务中,从而使用户可以更好地了解产品的可用性和预期的交付。 同样,一家大型加油站公司可以使用Cosmos数据库实例通过IoT Edge在整个组织中快速共享泵遥测。
借助Cosmos DB,这是Azure自身服务的基础工具,将其带到网络边缘应该可以使构建和部署这些复杂的分布式应用程序变得更加容易。