本文介绍云数据库MongoDB 8.0版本推出的新特性和优化项。
速览
本文将从以下方面介绍云数据库MongoDB 8.0版本:
MongoDB 8.0 的更多新特性以及优化项,请参见MongoDB 8.0 release-notes。
升级版TCMalloc
MongoDB 8.0版本开始使用升级版的TCMalloc:
缓存机制调整:升级版TCMalloc会使用每个CPU的缓存(而不是每个线程的缓存),以减少内存碎片并使数据库更能适应高压力工作负载。
内存释放机制:升级版TCMalloc使用时会在后台创建一个线程,每秒尝试将内存释放回操作系统。
tcmallocReleaseRate
参数用于控制内存释放的速率,单位为bytes/s
(取值不再是之前版本1-10
的模糊设定)。tcmallocReleaseRate
参数在云数据库MongoDB中的默认值为10485760
(即10MB。该参数值即使是0,也会释放一定内存),您可以根据业务情况自定义调整。
复制性能优化
Majority写
从MongoDB 8.0版本开始,writeConcern
为majority
时,MongoDB会在大多数副本集成员已经写入了相关的oplog后就返回确认,而不是等待应用这个更改后才返回,此更改提高了majority
模式下写入的性能。
因此如果应用程序在收到majority
写确认后,立刻到Secondary节点上读取数据,返回的结果可能不包含这次写操作更改的内容。
Oplog缓冲区
Secondary节点会并行写入和应用每个批次的oplog内容。当Writer线程从主节点读取新的oplog条目并将其写入本地oplog时,Applier线程会异步将这些更改应用到本地数据库。此更改提高了Secondary节点的复制吞吐量。
因此,serverStatus
下的相关指标也发生了变化,变成metrics.repl.buffer.write
和metrics.repl.buffer.apply
两个缓冲区。
reshard性能优化
reshardCollection
性能改进,您可以通过此命令改变集合的分片键并改变数据的分布。
MongoDB 8.0版本支持了forceRedistribution
选项,允许使用和之前相同的分片键对集合进行重新分片,将数据重新分配到新的分片上。这个过程相比Chunk进行范围迁移要快很多,还可以与zones
选项搭配将数据迁移到特定区域。操作示例如下:
db.adminCommand({
reshardCollection: "db.coll",
key: { shard_key: "hashed" },
forceRedistribution: true
})
重新分片过程中若进行索引构建,可能导致索引构建失败且无显式报错。您应避免在重新分片期间构建索引,或确保索引构建完成后再重新分片。
在追赶增量oplog阶段时,如果预估剩余操作时间在两秒以内,源分片才会阻止此集合的写入,等待目标分片追赶完成。但如果业务上可接受更长时间的阻塞,即停服或运维窗口,您可以使用commitReshardCollection命令提前对此集合进行禁写操作,帮助更快地完成重新分片。
分片
除reshard性能优化外,分片还有以下优化内容:
哈希分片会默认为每个分片创建1个Chunk(MongoDB 8.0版之前是默认2个)。
dbhash
命令可以直接在分片上运行。findAndModify
和deleteOne
命令可以使用部分Shard Key作为查询条件。在一个已经分片的集合上使用
upsert
为true
的updateOne
命令时,查询条件中可以不包含所有的Shard Key。支持通过
unshardCollection
命令或sh.unshardCollection()
方法取消现有集合的分片,此操作会将集合中的所有文档移动到指定的分片或数据量最少的分片上。支持通过
moveCollection
命令将某一个未分片的集合移动到指定的分片上,不必约束于Primary Shard。但时间序列集合和可查询加密集合不可移动,且可能会有2秒左右的集合写入阻塞。提供了新的数据库命令和mongosh帮助函数:
命令
mongosh帮助函数
说明
moveCollection
sh.moveCollection()
将一个未分片的集合移至某个Shard。
unshardCollection
sh.unshardCollection()
取消对现有分片集合的分片,并将集合数据移至某个Shard。
abortMoveCollection
sh.abortMoveCollection()
停止正在进行的
moveCollection
操作。abortUnshardCollection
sh.abortUnshardCollection()
停止正在进行的
unshardCollection
操作。无
sh.shardAndDistributeCollection()
对集合进行分片,并使用提供的分片键立即重新分配数据。
运行该帮助函数与连续运行
shardCollection
和reshardCollection
的结果相同,目的是加快数据移动速度。
日志记录
慢日志中添加了workingMillis
字段,用于展示实际执行操作所花费的时间。
区别于之前的durationMillis
操作总延迟,workingMillis
不会包含锁等待或流量控制等因素消耗的时间。
聚合
BinData转换
您可以使用$convert运算符执行以下转换:
字符串值转换为binData值。
binData值转换为字符串值。
另外,$toUUID表达式提供了将字符串转换为UUID值的简化语法。
$queryStats
$queryStats阶段会返回已记录查询的统计数据,且优化了在Change Stream中的跟踪和报告指标。
安全
可查询加密:范围查询
可查询加密支持使用$lt
、$lte
、$gt
、$gte
对加密字段进行范围查询。
入口队列
MongoDB 8.0引入了一个新的队列用于入口准入控制(ingressAdmissionControllerTicketPoolSize
),即从网络进入数据库的操作将进入入口队列。
入口队列默认情况下不进行限制,您可以自定义队列最大值使得请求进行排队。
其他优化
引入了一种新的Query Shape,此前的Query Shape被称为Plan Cache Query Shape,同时查询优化器会将Query Settings作为附加的输入信息,影响最终的查询计划选择。
setQuerySettings添加查询设置:
可用于指定索引选择,8.0版本弃用了使用
planCacheSetFilter
来设置index filter
的方式。可用于限流设置,您可以通过
reject
选项设置拒绝某个Query Shape。
removeQuerySettings
用于删除查询设置。$querySettings
用于查看查询设置。
explain()
命令现在会通过queryPlanner.optimizationTimeMillis
返回查询计划用在优化上的时间,单位为毫秒。新增
defaultMaxTimeMS
参数,用于指定单个读取操作完成的默认时间限制,单位为毫秒。适用的操作:
find
aggregate
(不包括$merge
和$out
阶段)count
distinct
dbHash
如果客户端指定了
maxTimeMS
,那么defaultMaxTimeMS
对此操作将不再生效。
新增
bulkWrite
命令,可以在一个请求中对多个集合执行多条插入、更新、删除操作。updateOne
支持对sort
选项进行排序。支持在Capped Collection上创建TTL索引。
非事务的批量插入不会再生成单独的oplog,而是放到一个oplog中进行批处理,所有插入的文档在Change Stream事件中有相同的
clusterTime
。此改动提高了批量插入的性能,避免从节点回放多条oplog可能导致的复制延迟。支持对同一数据库下的不同集合并发执行DDL操作。
在集群执行DDL操作(如
reshardCollection
这种会修改集合的命令)的过程中添加或删除分片会被阻塞,您只能在DDL操作后执行。改进了索引构建,返回错误报告的速度更快,故障恢复能力更强。
行为
MongoDB 8.0版本
MongoDB 8.0之前版本
发现错误停止构建索引的时机
在收集扫描阶段发现的索引错误(重复键错误除外)会立即返回,然后索引构建停止。
MongoDB 8.0可帮助您快速诊断索引错误。例如,如果发现不兼容的索引值格式,则会立即将错误返回给您。
MongoDB 8.0之前版本在收集扫描阶段发现的索引错误会在提交阶段返回错误,提交阶段发生在索引构建的末尾。
与MongoDB 8.0相比,索引构建错误可能需要很长时间才能返回,因为错误是在提交阶段索引构建结束时返回的。
弹性部署
提高部署的弹性。如果发生索引构建错误,辅助成员可以请求主成员停止索引构建,并且辅助成员不会崩溃。
停止索引构建的请求并不总是可行的,如果成员已经投票提交索引,则辅助成员无法请求停止索引构建,并且辅助成员会崩溃(类似于MongoDB 7.0及更早版本)。
索引构建错误可能导致辅助成员崩溃。
磁盘空间
改进了索引构建的磁盘空间管理。如果可用磁盘空间低于
indexBuildMinAvailableDiskSpaceMB
参数中指定的最小值,索引构建可能会自动停止。如果成员已经投票同意提交索引,则索引构建不会停止。
可用磁盘空间不足时,也会停止索引构建。