在这篇文章中,我们将介绍Azure Cosmos DB的基本情况,并了解其可用的配置选项。
我们将涵盖资源管理概念、数据模型、API和配置选项:
1.什么是Azure Cosmos DB?
Azure Cosmos DB是一种文档数据库服务,使我们能够在一个高度可用、全球一致和可扩展的基于云的NoSQL数据库中存储、查询和索引我们的数据。
它是完全管理的,这意味着可用性、可靠性和安全性都是为我们处理的。
Cosmos DB APIs
Cosmos DB的突出特点是,你可以将其配置为使用SQL或NoSQL来与你的数据进行交互。它通过为你要存储的每种类型的数据提供不同的API来实现。
这些API是:
- SQL API- 用于存储和查询数据,使用类似SQL的语法。这是默认和推荐的API。
- Gremlin API- 如果我们想使用类似图形数据库的语法与数据进行交互。
- 表API- 用于从Azure表存储迁移到Cosmos DB的应用。
- Cassandra API- 用于处理为Cassandra数据库设计的数据。
- MongoDB API- 用于处理为MongoDB数据库设计的数据。
通过提供这些API,Cosmos DB使我们能够很容易地从现有的数据存储迁移到Cosmos DB。当我们探讨如何以编程方式连接到Cosmos DB时,会有更多关于这方面的内容。
请注意,这些API并不决定数据的存储方式。数据被存储在一个NoSQL数据库中。
为什么选择Cosmos DB?
由于有其他基于云的数据库,你可以用来存储数据,重要的是要了解为什么你可能想迁移到Cosmos DB。
Cosmos DB提供了一些其他基于云的数据库可能不具备的优质功能:
- 轻松实现数据的全球分布--通过多区域的写和读操作提高可用性和速度。
- 专用的吞吐量
- 个位数毫秒的延迟。
- 保证可用性
- 先进的索引和分区
以及更多。
除此以外,API使得在不同的数据库方法之间切换更加容易,而不需要物理迁移数据。
2.Azure Cosmos DB的基本概念
我们来看看Azure Cosmos DB的一些基本概念。
资源层次结构
下面是Azure Cosmos DB的资源层次结构:
Cosmos DB资源层次结构
让我们来了解每个层次和层次结构中不同级别的可用配置。
宇宙账户
宇宙账户是Azure Cosmos DB的最高级别资源。它是我们Cosmos DB实例的入口。
以下功能是在Cosmos账户层次定义的:
- 用于连接数据库实例的唯一DNS名称,如https://{account}.document.azure.com/。
- 全球分布能力--你可以定义你想在多少个地区分布你的数据。
- 账户中所有资源的默认一致性级别。你可以为个别资源覆盖这一点。
数据库和容器
一个账户可以包含多个数据库,这些数据库有相同的分发需求。每个数据库可以包含多个容器。你也可以使用数据库来管理用户、权限和底层容器的吞吐量。
****每个容器类似于SQL中的表,MongoDB中的集合,Gremlin中的图,等等。****容器是存储和吞吐量的基本可扩展单位。它们在账户定义的多个区域内进行水平分区和复制。
容器的吞吐量可以通过两种方式定义:
- 专用配置的吞吐量模式- 每个容器实例可以被分配一个固定的吞吐量。成本较高,并有SLA支持。
- 共享配置的吞吐量模式- 在共享模式下运行的所有容器实例的总吞吐量保持不变,而单个容器可以有不同的实时吞吐量。
在容器级别,我们还可以选择配置索引策略和默认TTL。
容器的内容
类似于一个SQL表,一个容器可以包含多种资源。最重要的资源是项目(Item(s))。
****一个项目是一个单一的记录单位。****例如,表中的一行,集合中的一个文档,图中的一个节点,等等。
其他一些资源包括基于JavaScript的:
- 存储程序
- 用户定义的函数
- 触发器
一致性水平
数据可以被复制到多个区域,并且可以允许写入。在这种情况下,确定数据的一致性要求是很重要的。
让我们看看Azure Cosmos DB中可用的不同一致性级别及其含义:
- 强大的- 数据在所有区域保持完全相同。这意味着写操作是昂贵的,在所有区域都有数据时才会完成。
- 有界限的呆滞性- 写操作的延迟是由各区域之间的固定时间间隔来约束的。例如,在进行了一次写操作后,数据保证在接下来的t秒内可用。
- 会话- 在会话中写入的数据在同一会话中进行读取时将可被读取。当一个用户会话中,所有的读和写都由一个区域负责时,这就很好。
- 一致性前缀- 数据将按照写入的相同顺序被读取。例如,如果在区域1中我们先写数据A,然后写B,那么在区域2中,A将在B之前可用。
- 最终的- 顺序和呆滞性都不重要,唯一重要的是数据最终会在所有区域都可用。工作速度快,但一致性最差。
探索- 需要不同一致性级别的场景。
请求单位(RUs)
根据Microsoft Learn上的定义:z
做一次点读,也就是通过ID和分区键值来获取一个单一的项目,对于一个1KB的项目,其成本是1RU。
这个成本是基于系统资源,例如执行数据库操作所需的CPU、IOPS和内存。我们的应用所消耗的RU最终会计入账户。有不同的模式可以设置Cosmos账户,这将影响计费。
- 规定的吞吐量模式- 以每秒的RU为单位设置预期的吞吐量。模式是在账户层面上选择的,但RU可以在数据库或容器层面上进行配置。
- 无服务器模式- 为实际消耗的单位付费。
- 自动规模模式- 账户被设置为根据使用情况自动扩展。这对具有可变或不可预测的使用量的应用是很好的。
数据库分区
正如前面在容器部分提到的,一个容器可以被划分为多个分区。你可以通过设置分区键来做到这一点。
分区和索引
- 逻辑分区
一个逻辑分区是共享相同分区键值的项目的集合。例如,如果一个名为 "Users "的容器被一个键 "State "所分割,那么一个逻辑分区就是共享相同 "State "值的项目的集合。
- 索引
索引被用来提高查询的性能。在普通的SQL数据库中,默认情况下,索引是基于主键创建的。Cosmos DB的项目也包含一个独特的字段,称为项目ID。
Cosmos DB的默认索引是分区键和项目ID的组合。分区键用于定位逻辑分区,项目ID用于定位特定的项目。因此,为了加快访问速度,选择一个好的分区键是很重要的,它可以将数据均匀地分配到各个分区。
- 物理分区
物理分区的作用是提供水平可扩展性。一个物理分区是一个或多个逻辑分区的集合。一个逻辑分区的数据不能存在于一个以上的物理分区。
用户对数据在物理分区上的分布方式没有任何控制。****Cosmos DB是一个可管理的服务,当需要可扩展性时,系统将自动在物理分区上分配数据。
这构成了另一条准则的基础,即分区键应导致更小的逻辑分区。如果逻辑分区过大,将影响系统的扩展极限。
如何选择一个分区键
至此,我们知道了什么是分区键。但我们如何选择一个好的分区键呢?下面是一些准则:
- 不变的- 分区键在数据创建后不能被改变。
- 高度的卡片性- 分区键的大量可能值将导致大量的小逻辑分区。有利于索引和可扩展性。
- 均匀分布- 除了高cardinality之外,每个可能的值都有同样的可能性也很重要。这有利于数据在各分区的均匀分布。
- 读取重的容器- 对于读取量大的容器,选择一个在读取查询中经常出现的分区键很重要。否则,基于分区键的索引的好处就会丧失。同样有利的是,大多数查询可以从一个分区读取数据,跨分区查询被最小化了。
- 使用项目ID作为分区键- Cosmos DB支持一个独特的字段,称为项目ID。这个字段是自动生成的,并保证是唯一的。这是对分区键的一个很好的选择。
探索- 为什么不使用项目ID作为分区键?
这里有一些关于选择分区键的更多信息。
合成的分区键
- 将多个字段串联起来,创建一个分区密钥。
- 使用哈希函数来创建一个分区密钥的后缀。
- 使用一个随机字符串来创建一个分区密钥后缀。
3.Cosmos DB的数据模型
如前所述,CosmosDB的所有数据都是以NoSQL方式存储的。让我们看一下数据模型的一些方面。
文档数据模型
在文档数据模型中,每个条目被称为一个文档。在Cosmos DB的术语中,文档可以被称为项目。
一个面向文档的数据库将具有以下特点。
- 非关系型- 每个项目都是一个独立的实体。
- 易于扩展- 可以为数据创建物理分区,以提高性能和扩展存储。
- 没有模式- 数据库本身不会强制执行任何模式。这就为存储不同数据格式的实体提供了灵活性。它也有助于结构随着时间的推移而不断发展。
项目
Cosmos DB中的每个项目都是一个JSON文档。对这些文件的写操作是原子性的。项目包含一个唯一的项目ID和一个分区键,用于在多个逻辑分区中划分数据。
分区键也可以是嵌套字段。例如,在下面的JSON中,city字段可以被用作分区键,即使它不在根级别:
{
"id": "1",
"name": "John",
"address": {
"street": "1 Main St",
"city": "New York"
}
}
在创建容器时,必须提供分区键的路径。在上面的例子中,路径将是/address/city 。
4.如何配置Cosmos DB
在Cosmos DB中,SQL API是一种查询语言,它允许我们使用类似SQL的语法来查询文档数据库中的数据。有很多理由选择SQL API而不是其他API:
- 低延迟
- 自动扩展
- 有SLA支持的99.999%的可用性
它非常适用于高性能的应用,比如。
- 从物联网设备收集和查询数据--产生大量的数据,需要快速处理。
- 零售应用--具有不同的使用模式,可以从弹性扩展中受益。
- 多平台应用--可以从文件结构的灵活性中受益。
吞吐量配置
在配置Azure Cosmos DB时,我们可以在数据库和容器层面上配置吞吐量,或者同时配置。
容器级别的吞吐量
在容器级别提供的吞吐量只适用于该容器。它不影响数据库的其他容器。例如,在下面的图片中,每个容器都有不同的吞吐量。
容器级的吞吐量配置
这是推荐的配置吞吐量的方式。如果每个容器都被映射到一个单独的应用功能,那么在容器级别配置吞吐量是有意义的。
数据库级别的吞吐量
我们也可以在数据库级别上配置吞吐量。这将在数据库的所有容器中共享。
数据库级别的吞吐量供应
如果所有的容器都有类似的负载模式,这样做是可以的,但在大多数情况下,它会导致不可预测的结果。
混合吞吐量
混合容器和数据库级别的吞吐量配置是可能的。要做到这一点,我们首先在数据库级别定义一个吞吐量。然后,在创建一个容器时,我们可以指定使用哪种吞吐量模式。
在共享吞吐量模式下配置的容器将共享在数据库级别配置的吞吐量。在专用吞吐量模式下配置的容器将在容器级别上有自己的吞吐量配置。
混合吞吐量的配置
请注意,我们不能将一个容器从共享模式转换为专用吞吐量模式,反之亦然。要改变这一点,我们需要删除该容器并创建一个新的。
存储
要估计存储需求,我们可以使用Azure Cosmos DB容量计算器。
Cosmos DB容量计算器
在输入估计的负载、复制策略和存储要求后,该计算器可以提供这种设置的估计成本。
存活时间(TTL)
可以对容器中的文档设置一个生存时间(TTL)。这对那些预计会在短时间内被删除的文件很有用。它可以在容器级别配置,也可以在文档级别重写。最大的TTL值是2147483647。
在容器级别,TTL需要被设置为以下值之一:
- 不存在- 没有TTL,即使试图在一个文件上设置TTL也不会过期。
- -1- 默认没有TTL,但可以在文档级别添加。
- 秒的数量- 默认的TTL是提供的秒数。这可以在文档级别上被重写。
过期的文件和优化消耗的存储可以带来更好的性能和更低的成本。因此,决定使用哪个TTL值以及哪些项目要过期是很重要的。
一些解决方案可能需要Cosmos DB作为中间存储来执行查询并将结果传递给最终存储。在这种情况下,你应该使用TTL来尽快使文件过期,以尽量减少成本。
Cosmos DB消费模型
让我们来详细了解一下不同的消费模式。
无服务器
在无服务器模式中,服务是根据实际消耗的RU数量来收费的。当消费模式是不可预测的,并且可能取决于活动、功能发布、一天中的时间、季节性销售、假期等因素时,这是很好的。
它在以下情况下也很好:
- 一个新的应用程序被推出,我们没有太多的负载可以开始。我们也不知道负载会如何增长。
- 该数据库支持托管在Azure Functions上的无服务器应用程序。随着应用程序获得更多的用户,DB也将获得更多的请求。
- 开始使用Cosmos DB,在配置和成本方面没有很多经验。
- 该服务预计不会扩展,而且消耗的资源可能会少于可配置的最低RU。
供给式与无服务器式
在Serverless和Provisioned消费模式之间做出决定,是对成本和性能的权衡。使用以下几点来帮助你决定。
- 工作负载--可预测的、足够大的工作负载有利于配置型消费模式。
- RU限制--配置的吞吐量不会超过决定的最大RU,而无服务器可以扩展到Cosmos DB中允许的最大可能的RU/s。当预期出现突发情况时,你可以使用Serverless。
- 全球分布 - 这是一个重要的因素。Serverless模型不跨区域分布,所以可以用于单个区域。Provisioned模型是跨区域分布的,可以用于多个区域。
- 存储限制 - Serverless每个容器只能存储50GB的数据,而Provisioned每个容器可以存储无限的数据。
自动规模模型
Auto-Scale模型在provisioned和serverless消费模型之间找到了平衡。它的工作方式是根据需要动态地配置资源,但要在指定的范围内进行。
让我们来看看自动规模和配置的吞吐量之间的比较:
- 工作负载--自动规模的吞吐量在可接受的最低性能和我们希望产生的最大成本之间摇摆不定。如果工作负载是可预测的,那么配置仍然是更好的,因为我们既不想失去性能,也不想在长期内产生更多成本。
- RU消耗- 通过自动规模,我们可以设置一个RU限制,这与配置的情况相同。不同的是,调配式计费总是根据指定的RU进行,但自动规模计费是基于--实时消耗的RU或调配式RU的10%,以较高者为准。考虑到这一点,建议只有在实际消耗量超过66%的时候,才可以使用配置的消耗模式,接近配置的限制。
也可以将容器从自动规模迁移到配置的吞吐量,反之亦然。在迁移过程中,系统会自动选择一个RU值,迁移后必须进行验证或手动设置。
总结
谢谢你的阅读。这应该让你对Azure的CosmosDB服务如何工作以及如何配置它有一些了解。如果你想和我联系,你可以在Twitter上找到我。