本文介绍如何使用 Azure 活动日志监视 Azure Cosmos DB 中的分区拆分和合并操作。
Background
在 Azure Cosmos DB 中,每个物理分区最多支持 10,000 RU/秒的吞吐量。 将数据库或容器的预配吞吐量增加到超出当前物理分区容量时,Azure Cosmos DB 必须拆分这些分区以适应额外的吞吐量。
分区拆分将现有物理分区划分为新分区。 每个新分区都会占用原始数据的一部分。 此过程允许容器提供更高的总吞吐量,因为每个新分区最多可提供 10,000 RU/秒的容量。 Azure Cosmos DB 还可以合并分区,以优化布局,以获得最佳性能和数据分布。
根据数据大小和吞吐量请求,拆分和合并分区可能需要几个小时才能完成。 Azure 门户中的活动日志显示这些弹性操作的状态 - 吞吐量增加(分区拆分)和减少(分区合并)。
有关分区拆分的工作原理和缩放最佳做法的更多详细信息,请参阅 有关缩放预配吞吐量的最佳做法。
监视活动日志中的弹性操作
分区拆分和合并都遵循相同的活动日志模式。 监视弹性操作的进度:
- 在 Azure 门户中,导航到你的 Azure Cosmos DB 帐户。
- 在左侧菜单中,选择 “活动日志”。
- 按数据库或容器的资源名称进行筛选。
- 查找与弹性操作相关的日志条目。 每个条目都包含操作名称、状态和时间戳。
- 展开日志条目以查看嵌套在主条目下的链接缩放操作。 主条目反映缩放操作的最新总体状态。 每个嵌套操作也有其自己的状态。
- 选择单个日志以打开右侧的详细信息窗格。 在 JSON 选项卡下,“properties”部分包含有关操作的详细信息。
每个操作都通过三种状态进行。 每个状态中的特定详细信息在拆分和合并之间有所不同,如下一节中所述。
| 地位 | Description |
|---|---|
| Started | 在 Azure Cosmos DB 确定哪些分区将拆分或合并之后,在操作开始时发出。 |
| 正在进行中 | 在操作持续时间内以 30 分钟的间隔发出,在工作进行时提供更新的详细信息。 如果操作在 30 分钟内完成,则可能不会看到此状态。 |
| 成功 | 操作完成时发出一次。 |
以下示例演示了活动日志中显示的纵向扩展操作,演示了上面所述的布局。
提升吞吐量/拆分分区
示例:假设你有一个具有 1 个物理分区的容器,处理 5,000 RU/秒。 然后将吞吐量增加到 15,000 RU/秒。 现有分区最多只能支持 10,000 RU/秒 , 不足以满足所请求的 15,000 RU/秒。 Azure Cosmos DB 将其拆分,以创建可分配更高吞吐量的更多分区。
主活动日志
吞吐量拆分操作启动后,您将看到的主要条目为:“主要条目”
“吞吐量拆分操作——扩展到 15,000 的吞吐量”
该数字反映新的目标吞吐量。 此主条目包含与拆分相关的所有嵌套操作。 展开它以查看操作进行时的各个状态更新。
嵌套活动日志
启动状态 - 活动日志条目显示新的目标吞吐量以及将被分割以到达此目标吞吐量的分区。 这表明缩放操作正在进行中。 对于此示例,新吞吐量为 15,000 RU/秒,分区“0”将被拆分。
正在进行状态 - 大约每 30 分钟发出一次。 此状态提供拆分中涉及的每个分区的详细细分。 每个分区都表示为跟踪中的一个操作,使你可以在粒度级别跟踪进度。
下面的细目包括示例的值以及每个属性的说明。
| 财产 | 检查点 1 示例 | 示例检查点 2 | Description |
|---|---|---|---|
| 所需操作总数 | 1 |
1 |
需要拆分才能满足所请求吞吐量的分区总数。 |
| 正在进行操作 | 1 |
0 |
正在主动拆分的分区。 |
| WaitingToBeScheduled 操作 | 0 |
0 |
分区已准备好分割,但被同一分区的其他操作暂时阻止。 这些操作将自动继续。 |
| 已完成的操作 | 0 |
1 |
拆分完成的分区现在以新的吞吐量处理流量。 |
| 失败的操作 | 0 |
0 |
遇到错误的分区。 这些操作将在新的操作ID下被自动重新排队,并作为单独的操作显示出来。 |
下图显示了这些属性如何显示在 Azure 门户中活动日志条目的 JSON 选项卡中。
成功状态 - 拆分已完成,所有新分区都处于联机状态,并且完整的预配吞吐量可用。
活动日志状态 JSON
以下 JSON 属性在分区拆分操作的每个阶段发出。 检查点 1 和检查点 2 展示了随着分区完成其工作,进行中状态如何随着时间进行更新。
| 地位 | JSON 属性 (检查点 1) | JSON 属性 (检查点 2) |
|---|---|---|
| Started | { "isSharedThroughput": "False", "resourceRid": "<id>", "databaseName": "database1", "collectionName": "container1", "targetThroughput": "15000", "status": "Will split partitions 0 into different partitions" } |
|
| 正在进行中 | { "isSharedThroughput": "False", "resourceRid": "<id>", "databaseName": "database1", "collectionName": "container1", "targetThroughput": "15000", "Total Operations Required": "1", "In Progress Operations": "1", "WaitingToBeScheduled Operations": "0", "Completed Operations": "0", "Failed Operations": "0" } |
{ "isSharedThroughput": "False", "resourceRid": "<id>", "databaseName": "database1", "collectionName": "container1", "targetThroughput": "15000", "Total Operations Required": "1", "In Progress Operations": "0", "WaitingToBeScheduled Operations": "0", "Completed Operations": "1", "Failed Operations": "0" } |
| 成功 | { "isSharedThroughput": "False", "resourceRid": "<id>", "databaseName": "database1", "collectionName": "container1", "targetThroughput": "15000", "status": "Completed splits operation" } |
多轮拆分
对于更大的吞吐量增加,拆分过程在多个轮中发生。 每一轮会将上一轮创建的分区进一步拆分,直到有足够的分区来满足所请求的吞吐量。 每个回合都有自己的“开始”和“正在进行”日志条目。 完成所有回合后,主日志条目上会显示单个“成功”状态。
在每个回合中,活动日志大约每 30 分钟捕获一次定期检查点。 每个检查点显示为“正在进行”条目,其中包含操作状态的更新快照。 根据轮次花费的时间,你可能会看到多个“正在进行”条目。 如果回合快速完成(例如 30 分钟或更少),您可能只能看到“开始”状态,而不会看到任何“正在进行”报表。
示例:假设有一个容器,其中包含 1,000 RU/秒和 1 个物理分区,并将吞吐量增加到 30,000 RU/秒。
第 1 轮 - 分区 0 拆分为分区 1 和分区 2。
第 2 轮 - 分区 1 拆分为分区 3 和分区 4。
最后,有 3 个分区(分区 2、3 和 4)提供 30,000 RU/秒。 完成第 2 轮后,主日志条目会显示“成功”。
Main log status: Started
┌─────── Round 1: Split ───────┐
Partition 0
1,000 RU/s
▼ ▼
Partition 1 Partition 2
✓ final partition
┌─────── Round 2: Split ───────┐
Partition 1
▼ ▼
Partition 3 Partition 4
✓ final partition ✓ final partition
─────── Final Partitions ───────
Partition 2 Partition 3 Partition 4
from Round 1 from Round 2 from Round 2
✔ RESULT: 3 partitions serving 30,000 RU/s
Main log status: Succeeded
“活动日志”显示门户上堆叠的条目,顶部是最新的条目。 每个回合都以自己的起始条目开头。 在一个“开始”和下一个“开始”之间的所有“正在进行”条目属于同一轮。
在此示例视图中,拆分的第 1 轮被蓝色框包围,并显示“开始”状态,后跟 2 个“正在进行”条目。 第 2 轮遵循类似的模式,并用紫色框括起来。
活动日志状态 JSON
以下 JSON 内容直接从活动日志条目中提取。 为清楚起见,将省略通用 JSON 字段,并且仅保留状态。
第 1 轮:拆分
| 地位 | JSON 属性 (检查点 1) | JSON 属性 (检查点 2) |
|---|---|---|
| Started | { "status": "Will split partitions 0 into different partitions" } |
|
| 正在进行中 | { "Total Operations Required": "1", "In Progress Operations": "1", "WaitingToBeScheduled Operations": "0", "Completed Operations": "0", "Failed Operations": "0" } |
{ "Total Operations Required": "1", "In Progress Operations": "0", "WaitingToBeScheduled Operations": "0", "Completed Operations": "1", "Failed Operations": "0" } |
分区 0 已完成拆分,显示为从“进行中”操作变为“已完成”操作。 现在,我们继续拆分分区 2。
第 2 轮:拆分
| 地位 | JSON 属性 (检查点 1) | JSON 属性 (检查点 2) |
|---|---|---|
| Started | { "status": "Will split partitions 2 into different partitions" } |
|
| 正在进行中 | { "Total Operations Required": "1", "In Progress Operations": "1", "WaitingToBeScheduled Operations": "0", "Completed Operations": "0", "Failed Operations": "0" } |
{ "Total Operations Required": "1", "In Progress Operations": "0", "WaitingToBeScheduled Operations": "0", "Completed Operations": "1", "Failed Operations": "0" } |
| 成功 | { "status": "Completed splits operation" } |
分区合并
大幅减少数据库或容器的预配吞吐量时,可能不再需要现有的物理分区数。 可以启动分区合并以减少物理分区计数并优化 RU/s 和数据分布。 合并可减少维护未使用的分区的开销,并使系统能够以降低的吞吐量更高效地运行。
合并操作将多个现有分区合并为单个新分区。 例如,如果合并了分区 2、3 和 4,则结果为一个新的分区 5。 合并创建的每个新分区都表示为活动日志中的一个操作。 合并遵循与吞吐量拆分相同的状态更新模式。
示例:假设已将一个容器扩展到 100,000 RU/秒,以便进行大型数据迁移,这需要 10 个物理分区。 虽然 10 个物理分区可以容纳 500 GB 的数据,但引入的数据只有 50 GB,而所需的稳定状态 RU/秒仅为 10,000 RU/秒。
将预配的吞吐量减少到 10,000 RU/秒后,可以将 10 个分区合并到 1 个分区并优化 RU/秒的使用情况。
主活动日志
分区合并操作启动后,你将看到一个主条目,标题为:
“Container 的 PartitionCoalescer 合并操作”
此条目充当与合并相关的所有嵌套操作的父级。 在操作持续时间内使用此条目来跟踪其进度。 下面可能还链接了其他与合并相关的日志,例如“合并 SQL 容器的物理分区”,但它们不包含状态信息。
以下示例显示主条目下的多个与合并相关的日志。 只有 PartitionCoalescer 容器合并操作条目 是相关的。
嵌套活动日志
启动状态 — 活动日志条目显示合并中涉及的容器以及要合并的分区。 容器反映它是使用预配吞吐量还是共享吞吐量。 此操作类型没有目标吞吐量,因为不会纵向扩展。 在此示例中,所有 10 个分区合并到 1 个分区中。
正在进行 中 - 大约每 30 分钟发出一次。 此状态提供每个合并操作的详细细分。 每个合并都表示为跟踪中的一个操作,因此可以在粒度级别跟踪进度。
下面的细目包括示例的值以及每个属性的说明。
| 财产 | 检查点 1 示例 | 示例检查点 2 | Description |
|---|---|---|---|
| 所需操作总数 | 1 |
1 |
达到目标分区计数所需的分区合并总数。 |
| 正在进行操作 | 1 |
0 |
正在积极运行的合并。 |
| WaitingToBeScheduled 操作 | 0 |
0 |
合并准备继续,但暂时被同一分区上的另一个操作阻止。 |
| 已完成的操作 | 0 |
1 |
已完成的合并。 |
| 失败的操作 | 0 |
0 |
遇到错误的合并操作。 这些操作在新的操作 ID 下自动重新排队。 |
下图显示了这些属性如何显示在 Azure 门户中活动日志条目的 JSON 选项卡中。
成功 - 合并已完成,其余分区正在为流量提供服务。
活动日志状态 JSON
以下 JSON 属性在合并操作的每个阶段发出。 检查点 1 和检查点 2 展示了随着分区完成其工作,进行中状态如何随着时间进行更新。
| 地位 | JSON 属性 (检查点 1) | JSON 属性 (检查点 2) |
|---|---|---|
| Started | { "isSharedThroughput": "False", "resourceRid": "<id>", "databaseName": "database3", "collectionName": "container3", "status": "Collection <id> will merge partitions 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 into a new partition" } |
|
| 正在进行中 | { "isSharedThroughput": "False", "resourceRid": "<id>", "databaseName": "database3", "collectionName": "container3", "Total Operations Required": "1", "In Progress Operations": "1", "WaitingToBeScheduled Operations": "0", "Completed Operations": "0", "Failed Operations": "0" } |
{ "isSharedThroughput": "False", "resourceRid": "<id>", "databaseName": "database3", "collectionName": "container3", "Total Operations Required": "1", "In Progress Operations": "0", "WaitingToBeScheduled Operations": "0", "Completed Operations": "1", "Failed Operations": "0" } |
| 成功 | { "isSharedThroughput": "False", "resourceRid": "<id>", "databaseName": "database3", "collectionName": "container3", "status": "Completed merge operation." } |