管理 Amazon DocumentDB 索引
Amazon DocumentDB 索引创建
在 Amazon DocumentDB 中创建索引需要做出一些决定:
需要多久完成?
在构建过程中无法访问该集合吗?
一个实例的计算能力有多少可以分配给构建?
应该创建什么类型的索引?
本节将帮助您回答这些问题,并提供用于在基于实例的集群集合上创建 Amazon DocumentDB 索引的命令和监控示例。
指南
以下指南包括创建新索引时的基本限制和配置权衡:
Amazon DocumentDB 版本支持 – 虽然所有版本的 Amazon DocumentDB 都支持单工作进程索引,但只有 Amazon DocumentDB 版本 4.0 和 5.0 支持多工作进程索引。
性能权衡 - 在索引创建过程中增加工作进程数量会增加 Amazon DocumentDB 数据库主实例上的 CPU 利用率和读取 IO。创建新索引所需的资源将无法用于正在运行的工作负载。
弹性集群 - Amazon DocumentDB 弹性集群不支持并行索引。
最大工作进程 - 您可以配置的最大工作进程取决于数据库集群中主实例的大小。其等于数据库集群中主实例上 vCPU 总数的一半。例如,在有 64 个 vCPU 的 db.r6g.16xlarge 实例上,你最多可以运行 32 个工作进程。
注意
2xlarge 及更低版本的实例类不支持并行工作进程。
最少工作进程 - 您可以配置的最小工作进程为 1。在基于实例的集群上创建索引的默认设置是两个工作进程。但是,您可以使用“工作线程”选项将工作进程减少到一个。这将使用单工作进程运行该进程。
索引压缩 - Amazon DocumentDB 不支持索引压缩。索引的数据大小可能比您使用其他选项时更大。
索引多个集合 - 数据库集群主实例上一半的 vCPU 可用于已配置的工作进程对多个集合执行索引创建。
索引类型 - 有关 Amazon DocumentDB 上支持的索引类型的完整说明,请参阅此博客文章
。
开始使用
要开始在集合上创建索引,请使用 createIndexes
命令。默认情况下,该命令将运行两个并行工作进程,可将索引创建过程的速度提高两倍。
例如,以下命令过程演示了如何为文档中的 “user_name” 字段创建索引,并将索引处理速度提至四个工作进程:
在集群上使用两个并行工作进程创建索引:
db.runCommand({"createIndexes":"test","indexes":[{"key": {"user_name":1}, "name":"username_idx"}]})
要优化索引创建过程的速度,您可以使用
db.runCommand createIndexes
命令中的“工作线程”选项("workers":<number>
)指定工作进程数。将处理速度提至四个并行工作进程:
db.runCommand({"createIndexes":"test","indexes":[{"key": {"user_name":1}, "name":"username_idx", "workers":4}]})
注意
工作进程数越多,则索引创建速度越快。但是,工作进程数增幅越大,主实例的 vCPU 的加载及 IO 的读取增速越快。确保您的集群配置充足,足以应对增加的负担,不会使其他工作负载降级。
索引进度状态
索引创建过程的工作原理是初始化、扫描集合、排序键,最后通过索引生成器插入键。在前台运行时,该过程最多有六个阶段,在后台运行时,则最多有九个阶段。您可以逐阶段查看状态指标,例如完成百分比、扫描的存储块总数、已排序键和已插入键。
使用 mongo Shell 中的db.currentOp()
命令监控索引过程进度。最后一个阶段的 100% 已完成表示所有索引都已成功创建:
db.currentOp({"command.createIndexes": { $exists : true } })
索引构建类型
索引构建的四种类型是:
前台 - 在创建索引之前,前台索引构建将阻止所有其他数据库操作。Amazon DocumentDB 前台构建由五个阶段组成。
前台(唯一) - 单个文档(唯一)前台索引构建将阻止其他数据库操作,例如常规前台构建。与基本前台构建不同,唯一构建使用额外的阶段(排序键 2)来查找重复的键。前台(唯一)构建由六个阶段组成。
后台 - 后台索引构建允许创建索引时在前台运行其他数据库操作。Amazon DocumentDB 后台构建由八个阶段组成。
后台(唯一) - 单个文档(唯一)后台索引构建允许在创建索引时在前台运行其他数据库操作。与基本背景构建不同,唯一构建使用额外的阶段(排序键 2)来查找重复的键。后台(唯一)构建由九个阶段组成。
索引构建阶段
舞台 | 前台 | 前台(唯一) | 背景 | 背景(唯一) |
---|---|---|---|---|
INITIALIZING |
1 |
1 |
1 |
1 |
构建索引:初始化 |
2 |
2 |
2 |
2 |
构建索引:扫描集合 |
3 |
3 |
3 |
3 |
构建索引:排序键 1 |
4 |
4 |
4 |
4 |
构建索引:排序键 2 |
5 |
5 |
||
构建索引:插入键 |
5 |
6 |
5 |
6 |
验证:扫描索引 |
6 |
7 |
||
验证:排序元组 |
7 |
8 |
||
验证:扫描集合 |
8 |
9 |
正在初始化 - createIndex 正在准备索引生成器。该阶段应该非常短暂。
构建索引:正在初始化 - 索引生成器正在准备创建索引。该阶段应该非常短暂。
构建索引:扫描集合 - 索引生成器正在执行集合扫描以收集索引秘钥。测量单位是“块”。
注意
如果为索引构建配置了多个工作进程,则在此阶段将显示该工作进程。“扫描集合”阶段是在索引构建过程中使用多个工作进程的唯一阶段。所有其他阶段将显示单工作进程。
构建索引:排序键 1 - 索引生成器正在排序已收集的索引键。测量单位是“键”。
构建索引:排序键 2 - 索引生成器正在对收集的与死元组相对应的索引键进行排序。此阶段仅适用于唯一索引构建。测量单位是“键”。
构建索引:插入键 - 索引生成器正在将索引键插入到新索引中。测量单位是“键”。
验证:扫描索引 - createIndex 正在扫描索引以查找需要验证的键。测量单位是“块”。
验证:排序元组 - createIndex 正在排序索引扫描阶段的输出。
验证:扫描集合 - CreateIndex 正在扫描集合以验证在前两个阶段中找到的索引键。测量单位是“块”。
索引构建输出示例
在如下输出示例(前台索引构建)中,显示了索引创建的状态。“msg”字段通过指示构建的阶段和完成百分比来汇总构建进度。“工作进程”字段表示在该索引构建阶段使用的工作进程数。“进度”字段显示用于计算完成百分比的实际数字。
注意
Amazon DocumentDB 版本 4.0 不支持 “currentIndexBuildName”、“msg”和“进度”字段。
{
"inprog" : [{
…
"command": {
"createIndexes": "test",
"indexes": [{
"v": 2,
"key": {
"user_name": 1
},
"name": "user_name_1"
}],
"lsid": {
"id": UUID(“094d0fba-8f41-4373-82c3-7c4c7b5ff13b”)
},
"$db": "test"
},
"currentIndexBuildName": user_name_1,
"msg": "Index Build: building index number_1, stage 6/6 building index: 656860/1003520 (keys) 65%",
"workers": 1,
"progress": {
"done": 656861,
"total": 1003520
},
…
],
"ok" : 1
}
使用 reIndex
进行 Amazon DocumentDB 索引维护
reIndex
是用于重建索引的命令。通常在索引损坏或效率低下时使用。随着时间的推移,索引会因为多次更新、插入或删除而积累未使用的空间,从而导致性能下降。重新编制索引有助于删除此类未使用的空间并恢复索引的效率。
reIndex
准则
reIndex
目前仅在 Amazon DocumentDB 5.0 上受支持。Amazon DocumentDB 支持在后台进行单个索引的
reindex
,以便多个工作人员操作。在reIndex
程序运行时,查询可以使用旧索引。Amazon DocumentDB 支持通过
currentOp
发布索引进度报告。您可以看到与创建索引时看到的 索引构建阶段 类似的索引构建阶段。唯一的区别是reIndex
始终有八个阶段,无论它是否唯一。没有“构建索引:排序键 2”阶段。reIndex
可以与同一个集合上的任何命令同时运行,但与索引相关的下列命令除外:createIndexes
、dropIndexes
、collMod
和renameCollection
。reIndex
目前不支持文本索引、地理空间索引、向量索引和部分索引。
reIndex
构建
使用以下命令来重建索引:
db.runCommand({ reIndex: "
collection-name
", index: "index-name
"})
您也可以选择控制分配给重建过程的工作人员的人数:
db.runCommand({ reIndex: "
collection-name
", index: "index-name
", workers:number
})