Azure Cosmos DB 是微软公司打造的一项全球分布式、横向分区、多模型数据库服务。该服务允许客户弹性(及独立形式)跨越任意数量地理服务区对吞吐量与存储进行扩展。Azure Cosmos DB 可立足第 99 百分位比例提升 99.99% 高可用性水平,提供可预测吞吐量以及多套经过明确定义的一致性模型,从而保证实现低延迟表现。Azure Cosmos DB 亦当前行业中第一项,同时也是惟一一项全球分布式数据库服务。其可提供全面的服务水平协议(简称 SLA),其中涵盖客户最为关心的四大维度:吞吐量、第 99 百分位比例延迟表现、可用性以及一致性。
作为一项云服务,我们对 Azure Cosmos DB 进行了精心设计与工程开发,同时充分考虑到多租户及全球分布等实际因素。在今天的博文当中,我们将对 Azure Cosmos DB 当中的关键性功能以及架构选择作出解读。
Azure Cosmos DB 基本信息
(点击放大图像)
图灵奖获得者兼全球知名计算机科学家Leslie Lamport 博士的工作成果深刻影响到众多大规模分布式系统。Azure Cosmos DB 自然也不例外。在Azure Cosmos DB 长达七年的构建过程当中,Leslie 的成果一直是我们最重要的灵感源泉。
在此前接受采访时,Leslie 亦分享了他对于Azure Cosmos DB 基础架构的看法及其在Azure Cosmos DB 设计工作当中发挥的巨大作用。
Azure Cosmos DB 的设计目标
Azure Cosmos DB 自 2010 年起既已立项,当时的代号为“Florence 项目”。其目标在于解决开发者在微软环境下构建互联网规模应用程序时面临的几大根本性痛点。我们为 Azure Cosmos DB 制定出以下发展目标。
- 保证客户能够在全球规模下根据需求以弹性方式扩展吞吐量与存储量。 从收到请求到完成扩展,这套系统应能够在 99% 比例的场景下于 5 秒之内交付经过配置的吞吐能力。
- 帮助客户构建起具备高度响应性的关键性任务应用程序。 这套系统必须能够在 99% 比例的场景下交付可预测且拥有可靠性保障的端到端低读取与写入延迟。
- 确保这套系统“始终开启”。这套系统必须实现 99.99% 的可用性,且不因与数据库相关的具体服务区数量而受到影响。为了保证客户能够对应用程序的端到端可用性属性进行测试,该服务必须能够在稳定状态下允许客户模拟服务区故障或者标记与其数据库下线状况相关的服务区。这将有助于难应用程序的端到端可用性属性。
- 使得开发人员能够编写出正确的全球分布式应用程序。这套系统必须围绕数据一致性提供直观且可预测的编程模型。尽管强大的一致性会带来成本提升,但仅依托于“最终一致性”在数据库当中编写大型全球分布式应用程序将引发难以回溯的应用程序代码问题、缺陷以及正确性 bug。
- 为之前 4 项目标提供严格且符合财务要求的综合性 SLA。
- 减轻开发人员所面临的数据库模式 / 索引管理以及版本控制等负担。对于全球分布式应用程序而言,确保数据库模式与索引同应用程序模式保持同步往往尤为难以实现。
- 以原生方式支持多种数据模型以及各类高人气数据访问 API。外部公开 API 与内部数据表达之间的翻译流程必须高效可行。
- 提供极低运营成本以帮助客户节约资金投入。
Azure Cosmos DB 设计中值得强调的各个方面
无论立足单一目标抑或是全部要求,以上提到的各项前提都需要新颖的解决方案与复杂的工程权衡方有望实现。Azure Cosmos DB 在设计当中的独特之处,在于我们采取独特的方法以引导这些约束条件并在各工程技术任务之间选取最佳平衡点。
以下为 Azure Cosmos DB 系统设计当中值得强调的各个重要方面。我们将在后续博文当中更为具体地为大家阐述其相关细节。
- Azure Cosmos DB 的设计旨在以动态形式配置数据库引擎与底层存储之间的接近度,从而支持匹配不同性能 SLA 的多个服务层。根据具体服务层,系统可通过配置用于支持计算及存储资源,从而(a)立足同一进程空间进行同地协作 ; (b)立足同一集群内的各设备进行分解 ; 或者(c)跨越同一服务区内多个不同集群 / 数据中心进行分解。
- Azure Cosmos DB 面向吞吐能力、延迟、一致性以及可用性等角度建立起综合性 SLA 体系。这些 SLA 负责明确定义一套全球分布式设置当中对于延迟、一致性、可用性以及吞吐能力间的权衡结果。
- Azure Cosmos DB 在系统内核层面采取独特的资源治理设计,其能够提供一套一致性编程模型以跨越一组异构性数据库运营集实现吞吐能力配置。
- Azure Cosmos DB 拥有一套高度模块化且资源得到充分治理的方案,旨在解决各类常见协调问题,具体包括跨服务区复制以及透明分区管理等等。
- Azure Cosmos DB 在设计上能够跨越多个地理服务区实现吞吐能力的弹性扩展,同时保证不影响到 SLA。该系统在设计上即考虑到跨服务区吞吐量扩展需求,且可确保吞吐量变化以即时形式存在。
- Azure Cosmos DB 的设计与实现方案可精确指定一组简单明确且符合 TLA+ 要求的、经过良好定义的一致性模型。这种能力使得各一致性模型能够充分适应各类现实场景,提供可证明的一致性保证,在多租户与全球分布式设置当中拥有商业可行性,同时提供一套直观的编程模型以帮助开发人员编写出正确的分布式应用程序。据我们所知,Azure Cosmos DB 亦是目前市场上惟一一套全球分布式数据库系统,其可实现有限过期、会话与一致性前缀等一致性模型的顺利运营,同时将其交付给开发者并配合明确的语义、性能 / 可用性权衡以及 SLA 支持能力。
- Azure Cosmos DB 拥有一套写入优化型资源治理与模式中立式数据库引擎(备注:自相关论文发布以来,其又迎来了可观的长足演进)。这套引擎能够持续处理大规模更新,以自动化方式对全部输入内容进行索引,并在保证确认客户更新前以同步方式实现索引持久性与高可用性的同时,维持稳定的低延迟表现。
- Azure Cosmos DB 在设计中充分考虑到其核心数据模型与类型系统的具体需求并配合极具可扩展数据库引擎设计,旨在允许用户高效向其核心数据模型当中添加、翻译以及投射多种数据模型以及 API 与编程语言类型系统。
一项多模型、多 API 数据库服务
(点击放大图像)
图一:Azure Cosmos DB 是一套多模型、多API 全球分布式数据库平台
如图一所示,Azure Cosmos DB 能够原生支持多种数据模型。Azure Cosmos DB 数据引擎的核心类型系统基于原子- 记录- 序列(简称ARS)。各原子由一组小型原始类型组成,具体包括字符串、布尔类型以及数字等组成。其中各记录为结构体,序列则为包含有原子、记录或序列的数组。Azure Cosmos DB 的数据库引擎能够高效将各数据模型翻译并投射至基于ARS 的数据模型当中。Azure Cosmos DB 的核心数据模型可原生接受来自动态类型编程语言的访问,并可直接表达为JSON 或者其它类似的形式。这样的设计亦使其能够原生支持用于数据访问及查询的各类主流数据库API。Azure Cosmos DB 的数据库引擎目前支持DocumentDB SQL、MongoDB、Azure Table Storage 以及Gremlin 图形查询API。我们还计划对其进行进一步扩展,借以支持其它高人气数据库API。而最重要的优势在于,开发人员可以利用流行的OSS API 以构建应用程序,且同时享受经过实战验证且完全受控的全球分布式数据库系统所能带来的所有助益。
资源模型与API 投射
开发人员能够通过订阅Azure 的方式配置数据库帐户,从而轻松运用Azure Cosmos DB。数据库帐户负责管理一套或者多套数据库。Azure Cosmos DB 数据库能够管理用户、权限以及容器。Azure Cosmos DB 容器属于模型中立型容器,可用于容纳用户生成的任意实体、存储规程、触发器以及用户定义函数(简称UDF)。客户数据库帐户当中的各类实例——包括数据库、用户、权限以及容器等等——皆被称为资源,具体如图二所示。
(点击放大图像)
图二:资源模型与API 投射
每种资源皆由一条稳定的逻辑URI 作为惟一标识,并被表达为一个JSON 文档。使用Azure Cosmos DB 的应用程序的整体资源模型属于一套层级化资源叠加结构,根植于数据库帐户当中并可利用超链接进行导航。除了用于表达用户所定义的任意内容的条目资源内容之外,所有其它资源皆遵循一套系统定义模式。条目资源的内容模型基于此前提到的原子- 记录- 序列(简称ARS)原则。如表一所示,容器与条目资源皆被进一步投射为面向特定API 接口类型的物化资源类型。举例来说,在使用面向文档API 时,容器与条目资源会被分别投射为集合(容器)与文档(条目)资源; 同样的,对于面向图形的API 访问,底层容器与条目资源会被分别投射为图形(容器)、节点(条目)以及边缘(条目)资源; 而在使用键- 值API 进行访问时,其将被投射为表(容器)与条目/ 行(条目)。
API
容器被投射为……
条目被投射为……
DocumentDB SQL
集合
文档
MongoDB
集合
文档
Azure Table Storage
表
条目
Gremlin
图形
节点与边缘
表一:基于特定 API 数据模型的容器与条目投射方式。
横向分区
(点击放大图像)
图三:利用横向分区实现弹性可扩展性。
Azure Cosmos DB 容器当中的全部数据(例如集合、表以及图形等)皆由资源分区进行横向分区与透明化管理,具体如图三所示。一个资源分区,是指一套根据客户指定分区 - 键进行分区的一致性、高可用性数据容器 ; 其负责为其管理下的资源组提供单一系统镜像,且属于可扩展性与分布机制的基本单元。Azure Cosmos DB 在设计当中充分考虑到客户根据不同地理服务区间应用程序流量模式实现吞吐量弹性扩展的需求,帮助其借此支持受地理位置与时间因素影响的波动性工作负载。该系统以透明化方式管理各分区,且不会影响到 Azure Cosmos DB 容器的可用性、一致性、延迟或者吞吐能力。
客户可立足 Azure Cosmos DB 容器以分或秒等粒度水平通过编程方式配置吞吐量,从而实现容器的弹性吞吐能力扩展。从内部来看,该系统以透明方式管理各资源分区,从而为特定容器提供其需要的吞吐能力。大家可以根据自身系统资源预算水平对整体吞吐量进行划分,借此交付不同资源分区,并最终利用资源横向分区实现吞吐量的弹性扩展。由于 Azure Cosmos DB 容器拥有全球分布式特性,因此 Azure Cosmos DB 可确保某一容器的吞吐量可用于该容器分布涵盖到的全部服务区,而且整个各数值变更只需要数秒即可完成。客户可通过分或秒等粒度级别对 Azure Cosmos DB 容器的吞吐量进行配置(吞吐量的请求单位,简称 RU,被称为‘货币单位’)。以分钟级别配置的吞吐量适用于管理工作负载当中以秒为单位出现的意外资源需求峰值。举例来说,客户可能以一小时为周期在某一容器当中配置 10000 RU 每秒与 100000 RU 每分钟。如图四所示,该工作负载在任意某分钟内出现的资源需求峰值会被该分钟内配置的 RU 每分钟所抵消。在本示例当中,客户能够将吞吐量的整体配置成本降低达 73%。
(点击放大图像)
图四:客户在处理意外工作负载峰值时,利用RU 每秒与RU 每分钟方式降低实现成本。
立足基础层面建立全球分布体系
如图五所示,客户资源通过两大维度进行分布:在特定服务区中,全部资源双可利用资源分区进行横向分区(本地分布)。而各资源分区亦可跨地理服务区进行复制(全球分布)。
(点击放大图像)
图五:同一容器可同时进行本地与全球分布。
当客户对吞吐量或存储量进行弹性扩展时,Azure Cosmos DB 能够以透明方式在所有服务区内执行分区管理操作。无论具体规模、分布或者故障情况如何,Azure Cosmos DB 都能够持续提供单一全球分布式资源系统镜像。Azure Cosmos DB 当中的资源全球分布系统属于交钥匙型方案:无论何时,您仅需数次点击(或者通过编程方式进行一次API 调用),即可将任意数量地理服务区与其数据库帐户进行关联。另外,无论数据规模或者服务区数量如何,Azure Cosmos DB 皆保证在99% 比例的场景下,能够于接到客户申请的1 小时之内完成服务区关联。之所以能够实现这一效果,是因为我们以并行方式将来自全部源资源分区的数据馈送并复制至新的关联服务区当中。客户亦可移除现有服务区,或者对原本关联至其数据库帐户的服务区进行“离线”操作。
透明多归属与99.99% 高可用性
客户也可以将“优先级”动态关联至与其数据库帐户相关的服务区处。一旦发生服务区故障,此优先级可用于将请求定向至特定服务区。而且尽管可能性极低,但如果出现服务区规模的灾难事件,Azure Cosmos DB 亦会根据优先级设定进行自动故障转移。为了测试应用程序的端到端可用性,客户可以手动方式触发故障事件(要求每小时内最多进行两次此类操作)。Azure Cosmos DB 保证在客户触发服务区故障时提供零数据丢失保障,同时为服务区灾难期间因系统触发之自动故障转移带来的数据丢失状况设定上限。应用程序本身并不需要在服务区故障状况下进行重新部署,而且可用性SLA 仍然有效。为此,Azure Cosmos DB 允许开发者利用逻辑(任意服务区)或者物理(特定服务区)端点与其资源进行交互。前者能够确保应用程序在故障场景下以透明化方式实现多归属; 后者则提供细粒度控制,以确保将指向该应用程序的读取与写入请求重新定向至特定服务区。Azure Cosmos DB 为每个数据库帐户提供高达99.99% 的可用性SLA。这一可用性保证不因具体规模(客户数据库中的实际吞吐量与存储量)、服务区数量或者特定数据库所关联之各服务区间的地理距离而受到影响。
在99% 的场景下提供低延迟保证
作为SLA 中的组成部分,Azure Cosmos DB 向客户作出99% 场景下的端到端低延迟保证。对于典型的1 KB 条目,Azure Cosmos DB 承诺在同一Azure 服务区内,在99% 的场景下实现端到端读取延迟低于10 毫秒、索引写入延迟则低于15 毫秒。其平均延迟通常比承诺低得多(低于5 毫秒)。通过为各项数据库事务设定的请求处理上限,Azure Cosmos DB 允许客户端明确区分各事务间的高延迟与不可用数据库。
SLA 支持下的多种经过良好定义的一致性模型
目前可用的商业分布式数据库可分为两类:(1)不提供经过良好定义且可证明的一致性选项的数据库 ; (2)提供两种极端一致性选项的数据库——即强一致性与最终一致性。前一种系统要求应用程序开发人员自行为其复制协议负责,这意味着开发者必须独力在一致性、可用性、延迟以及吞吐量之间作出艰难探索。后一种系统则以非黑即白的方式强迫开发者作出极端性选择。尽管目前已经出现众多关于一致性模型的研究与建议,但商业分布式数据库服务仍然没能在强一致性与最终一致性之外真正构建起可行的一致性实现途径。相比之下,Azure Cosmos DB 允许开发者根据一致性频谱(如图六所示)从五种经过良好定义的一致性模型当中作出选择——具体包括强一致性、有限过期一致性、会话一致性、一致性前缀以及最终一致性。
(点击放大图像)
图六:频谱中列出多种经过良好定义的一致性选项。
开发者们能够利用Azure Cosmos DB 在其数据库帐户当中对默认一改级别进行配置(随后新配置将覆盖特定读取请求的一致性设定)。从内部来看,默认一致性级别往往适用于跨服务区分区组内的数据。根据统计,我们的客户中有73% 使用会话一致性,而20% 倾向于选择有限过期一致性。我们发现,约有3% 的客户会首先实验我类一致性级别,而后才为应用程序作出特定级别选择。我们同时发现,平均只有2% 的客户会立足单一请求采用不同的一致性级别。为了向客户通报有违一致性SLA 的状况,我们采用一套线性检查器并保证其在所遥测的服务当中持续运行。在有限过期选项当中,我们会监控并报告一切有违k 与t 界限的状况。对于所有四种较为宽松的一致性选项,我们还特别对概率性有限过期(简称PBS)指标进行了追踪与报告。
全资源治理堆栈
Azure Cosmos DB 旨在允许客户以弹性方式根据应用流量模式跨越不同服务区实现吞吐量扩展,从而立足地理位置与时间因素支持波动性工作负载。要以具备成本效益的方式运营成千上万种不同类型的全球分布式工作负载,我们必须实现细粒度多租户机制,即由数百家客户共享同一设备,并由数千家客户共享同一集群。为了在保证运营成本效益的同时实现各客户间的性能隔离,我们从根本层面充分考量了系统的资源治理方式。作为一套资源治理系统,Azure Cosmos DB 属于一套包含众多级联组件的大规模分布式队列系统,且其中各组件皆通过精心调校以保证在系统资源预算配额范围之内提供可预测的吞吐能力。为了以最佳方式利用特定集群当中的系统资源(包括 CPU、内存、磁盘以及网络),集群中的每台设备都可以动态方式托管十余家到百余家客户。另外,从准入控制到全部 I/O 路径,整体堆栈内皆部署有速率限制与背压控制机制。我们的数据库引擎可实现细粒度并发性,并在尽可能节约系统资源的同时最大程度提供高吞吐量。
单位时间内发生的数据库操作数量(即吞吐量)属于系统资源预留与消费的基本单位。客户可以针对具体数据执行广泛的数据库操作。而根据实际操作类型与载荷(请求与响应),操作所消费的系统资源量亦有所区别。为了为计算请求所消耗的资源建立标准化模型,将系统资源预算同特定资源分区所需要交付的吞吐量相关联,同时为客户提供无关硬件形式的一致性数据库操作吞吐能力,我们为吞吐量定义出一种基于速率的抽象货币,并将其称为请求单位或者 RU(详见图七)。这一单位适用于两种基于时间粒度的维度——请求单位每秒(RU/s)以及请求单位每分(RU/m)。客户可以弹性方式通过编程配置容器上的 RU/s(及 / 或 RU/m),从而实现容器吞吐能力扩展。从内部来看,该系统管理各资源分区以为特定容器交付吞吐能力。要利用资源横向分区机制实现吞吐量的弹性扩展,要求各个资源分区能够根据特定系统资源预算交付整体吞吐量中的一部分。
(点击放大图像)
图七:RU/s(及RU/m)为各数据库操作吞吐量的标准化货币单位。
作为准入控制机制的一部分,每个分区则采用自适应速率限制规则。如果资源分区在一秒内接收到的请求数量超出了其经过校准的响应能力,则客户端将收到“请求速率过大”提示,并需要等待特定时间间隔方可进行重试。资源分区每秒对RU 备用容量(如果有)执行(限制)背景调查(例如对日志结构化数据库引擎进行背景调查、定期提取快照备份以及删除过期条目等)。一旦请求被核准,我们即会计算其中每项微操所消耗的RU 资源(例如分析条目、读取/ 写入页面或者执行查询运算等)。
结论
Azure Cosmos DB 将全球分布、弹性横向可扩展性以及多模型与模式中立式数据库引擎作为设计目标。作为一套云原生多租户数据库系统,Azure Cosmos DB 在设计上充分考虑到立足整体堆栈实现资源交叉治理。从初始设计开始,我们就要求 Azure Cosmos DB 必须具备全球数据分布、多种明确一致性水平选项、弹性跨地理服务区吞吐量扩展等能力,同时必须在自身综合性 SLA 当中涵盖全部客户对于吞吐量、一致性、延迟以及可用性的实际要求。
鸣谢
Azure Cosmos DB 于 2010 年以“Florence 项目”的形式正式诞生,期间被纳入 Azure DocumentDB 并最终逐步发展为现在 Azure Cosmos DB 的形式。我们对 Dave Campbell、Mark Russinovich、Scott Guthrie 以及 Gopal Kakivaya 提供的支持表示由衷感谢。我们也要感谢多年以来微软各团队多年以来对 Azure Cosmos DB 的广泛使用。我们站在了巨人的肩膀上——Azure Cosmos DB 当中众多组件技术正是前辈大德们辛勤耕耘的结果 ; 另外还要感谢 Service Fabric 团队为我们提供了强大的分布式系统基础设施以及支持与合作。我们感激 Leslie Lamport 博士带来的深刻启发,这亦不断影响着我们在分布式系统设计方法层面的理解方向。最后但同样重要的是,我们要感谢 Azure Cosmos DB 工程师团队作出的发展承诺以及为此投入的不懈努力。
评论