优化 Azure Cosmos DB for MongoDB 中的写入性能
适用对象: MongoDB
优化写入性能有助于充分利用 Azure Cosmos DB for MongoDB 的无限缩放能力。 与其他托管的 MongoDB 服务不同,API for MongoDB 可自动以透明方式将集合分片(使用分片集合时),以便能够无限缩放。
你写入数据的方式需要考虑到这一点。为此可将数据并行化并分散到多个分片,以充分利用数据库和集合在写入方面的优势。 本文将介绍优化写入性能的最佳做法。
将负载分散到多个分片
将数据写入到分片的 API for MongoDB 集合时,数据将拆分(分片)为微小的切片,并根据分片键字段的值写入到每个分片。 可将每个切片视为虚拟机的一小部分,其中仅存储了包含一个唯一分片键值的文档。
如果应用程序将大量数据写入单个分片,则这种做法是低效的,因为该应用只会最大程度地利用一个分片的吞吐量,而不会将负载分布到所有分片。 写入负载将通过并行写入到多个包含唯一分片键值的文档,在整个集合中均匀分布。
这种做法的一个例子是根据类别字段分片的产品目录应用程序。 此类应用程序不应该是每次写入到一个类别(分片),而最好是同时写入到所有类别,以实现最大写入吞吐量。
减少索引数
索引编制是一个很好的功能,可以显著减少查询数据所需的时间。 为了获得最灵活的查询体验,API for MongoDB 默认将对数据启用通配符索引,以便能够极快地针对所有字段进行查询。 但是,在写入数据时,包含通配符索引的所有索引会造成额外的负载,因为写入操作会更改集合与索引。
将索引数减少至支持查询所需的索引数能使写入速度变得更快且开销更低。 通常,我们建议采取以下做法:
- 用作筛选依据的任何字段应有相应的单字段索引。 这种做法还会启用多字段筛选。
- 用作排序依据的任何字段组应有其组合索引。
在 MongoDB 驱动程序中将 ordered 设置为 false
默认情况下,在写入数据时,MongoDB 驱动程序会将 ordered 选项设置为“true”,即,按顺序逐个写入每个文档。 此选项会降低写入性能,因为每个写入请求必须等待上一个写入请求完成。 写入数据时,将此选项设置为 false 可提高性能。
db.collection.insertMany(
[ <doc1> , <doc2>, ... ],
{
ordered: false
}
)
进行优化以使用最佳批大小和线程计数
在多个线程/进程之间并行化写入操作是缩放写入操作的关键所在。 对于每个进程/线程,API for MongoDB 接受按批(一批最多包含 1,000 个文档)进行写入。
如果每个进程/线程一次写入 1,000 个以上的文档,则应将 insertMany()
等客户端函数限制为大约 1,000 个文档。 否则,客户端将等待每个批次提交,然后再转到下一批。 在某些情况下,将批拆分为包含少于或者略多于 1,000 个文档可以提高速度。
后续步骤
- 详细了解如何在 API for MongoDB 中编制索引。
- 详细了解 Azure Cosmos DB 的分片/分区。
- 详细了解如何排查常见问题。
- 正在尝试为迁移到 Azure Cosmos DB 进行容量计划? 可以使用有关现有数据库群集的信息进行容量规划。
- 如果只知道现有数据库群集中的 vCore 和服务器数量,请阅读使用 vCore 或 vCPU 估算请求单位
- 若知道当前数据库工作负载的典型请求速率,请阅读使用 Azure Cosmos DB 容量计划工具估算请求单位