Azure Cosmos DB 中的更改源设计模式
适用范围: NoSQL
Azure Cosmos DB 更改源可以高效处理具有大量写入的大型数据集。 更改源还提供用于查询整个数据集以确定更改内容的替代方法。 本文重点介绍常用的更改源设计模式、设计优缺点和更改源的限制。
Azure Cosmos DB 非常适合用于 IoT、游戏、零售和操作日志记录应用程序。 这些应用程序中的一种常见设计模式是使用数据更改来触发其他操作。 此类操作示例包括:
- 插入、更新或删除项时触发通知或 API 调用。
- 对 IoT 的实时流式处理或对运营数据的实时分析处理。
- 数据移动,例如与缓存、搜索引擎、数据仓库或冷存储进行同步。
使用 Azure Cosmos DB 中的更改源,可针对每种模式构建高效、可缩放的解决方案,如下图所示:
事件计算和通知
Azure Cosmos DB 更改源可以简化需要基于特定事件触发通知或发送对 API 的调用的方案。 可以使用更改源处理器自动轮询容器的更改,并在每次发生写入、更新或删除操作时调用外部 API。
还可以基于特定的条件,有选择性地触发通知或发送对 API 的调用。 例如,如果要使用 Azure Functions 从更改源中读取数据,可以在函数中放置逻辑,以便仅在满足条件时发送通知。 虽然每次更改都会执行 Azure 函数代码,但只有满足条件时才会发送通知。
实时流处理
Azure Cosmos DB 更改源可用于 IoT 的实时流处理,或者基于操作数据进行实时分析处理。 例如,可以接收和存储来自设备、传感器、基础结构和应用程序的事件数据,然后使用 Spark 实时处理这些事件。 下图显示了如何借助 Azure Cosmos DB 更改源实现 lambda 体系结构:
在许多情况下,流处理实现首先会将大量传入数据接收到 Azure 事件中心或 Apache Kafka 等临时消息队列中。 由于 Azure Cosmos DB 能够支持持续较高的数据引入速率,并保证较低的读取和写入延迟,因此,更改源是极佳的替代方案。 基于消息队列的 Azure Cosmos DB 更改源的优势包括:
数据持久性
写入 Azure Cosmos DB 的数据显示在更改源中。 如果使用最新版本模式进行读取,则数据将保留在更改源中,直到它被删除。 消息队列通常具有最长的保留期。 例如,Azure 事件中心提供的最长数据保留期为 90 天。
查询功能
除了能够从 Azure Cosmos DB 容器的更改源中读取数据,你还可以对 Azure Cosmos DB 中存储的数据运行 SQL 查询。 更改源不是对容器中已有的数据进行复制,它只是一种不同的数据读取机制。 因此,如果从更改源中读取数据,数据始终与同一 Azure Cosmos DB 容器的查询一致。
高可用性
Azure Cosmos DB 提供高达 99.999% 的读取和写入可用性。 与许多消息队列不同,Azure Cosmos DB 数据可轻松地进行多区域分布,并配置零恢复时间目标 (RTO)。
处理更改源中的项后,可以生成具体化视图,并将聚合值存回到 Azure Cosmos DB 中。 例如,若要使用 Azure Cosmos DB 构建游戏,可使用更改源,根据已完成的游戏的分数实时更新排行榜。
数据移动
还可以从更改源中读取数据,以实现实时数据移动。
例如,更改源可帮助你有效执行以下任务:
使用 Azure Cosmos DB 中存储的数据更新缓存、搜索索引或数据仓库。
零停机迁移到其他 Azure Cosmos DB 帐户或其他具有不同逻辑分区键的 Azure Cosmos DB 容器。
实现应用程序级数据分层和存档。 例如,可将“热数据”存储在 Azure Cosmos DB 中,并将陈旧的“冷数据”存储在 Azure Blob 存储等其他存储系统中。
如果必须反规范化各个分区和容器中的数据,可以从容器的更改源(用作此数据复制操作的源)中读取数据。 使用更改源的实时数据复制只能保证最终一致性。 在 Azure Cosmos DB 容器中处理更改时,可以监视更改源处理器的滞后程度。
事件溯源
事件溯源模式涉及使用仅限追加的存储来记录对该数据执行的整个操作系列。 在所有数据引入都建模为写入(无更新或删除)的事件溯源体系结构中,Azure Cosmos DB 的更改源非常适合用作中心数据存储。 在这种情况下,对 Azure Cosmos DB 的每次写入都是一个“事件”,你可以在更改源中获得以往事件的完整记录。 中心事件存储发布的事件的典型用途是用于与外部系统的集成。 由于更改源中不存在保留时间限制,因此可以通过从 Cosmos 容器更改源的开头部分进行读取,来重放所有以往的事件。
可以让多个更改源使用者订阅同一个容器的更改源。 使用更改源只需支付租用容器的预配吞吐量费用,此外不会产生其他费用。 不管是否使用更改源,都会在每个容器中提供更改源。
由于 Azure Cosmos DB 在横向可伸缩性和高可用性方面具有优势,因此在事件溯源模式中,它是极佳的仅限追加的中心持久数据存储。 此外,更改源处理器提供“至少一次”的保证,确保不会遗漏任何事件的处理。
当前限制
更改源具有多种模式,每种模式都有你应了解的重要限制。 设计在最新版本模式或所有版本和删除模式下使用更改源的应用程序时,需要考虑多个方面。
中间更新
在最新版本模式中,更改源中仅包含最近对特定项所做的更改。 处理更改时,会读取最新可用的项版本。 如果在短时间内对同一项进行了多次更新,可能会遗漏中间更新的处理。 如果想要重放以往对某项的单个更新,可以改为将这些更新建模为一系列写入,或使用所有版本和删除模式。
Deletes
更改源最新版本模式不会捕获删除。 如果删除容器中的某个项,也会从更改源中移除该项。 处理删除的最常用方法是在要删除的项上添加一个软标记。 可以添加名为“deleted
”的属性,并在删除时将其设为“true
”。 此文档更新会在更改源中显示。 可以在此项上设置生存时间 (TTL),以便之后可以自动删除它。
保留
最新版本模式下的更改源不存在保留时间限制。 只要容器中存在某个项,它就在更改源中可用。
保证顺序
所有更改源模式在单个分区键值内(而不是多个分区键值内)具有顺序保证。 应该选择可以提供有意义的顺序保证的分区键。
例如,假设某个零售应用程序使用事件溯源设计模式。 在此应用程序中,每个不同的用户操作都是一个“事件”,这些事件建模为对 Azure Cosmos DB 的写入。 假设按以下顺序发生了一些示例事件:
- 客户将商品 A 添加到其购物车。
- 客户将商品 B 添加到其购物车。
- 客户从购物车中删除商品 A。
- 客户结帐,然后卖家寄送购物车内容。
将为每个客户保留当前购物车内容的具体化视图。 此应用程序必须确保按事件的发生顺序处理这些事件。 例如,如果在移除商品 A 之前处理购物车结帐,则可能会将商品 A 发给客户,而不是客户想要的商品 B。为了保证这四个事件按发生顺序得到处理,它们应该位于同一个分区键值中。 如果选择 username
(每个客户都有唯一的用户名)作为分区键,则可以保证这些事件按照它们写入到 Azure Cosmos DB 的顺序显示在更改源中。
示例
下面是一些真实的最新版本模式更改源代码示例,这些示例超出了所提供的示例的范围: