MongoDB性能分析之WiredTiger引擎
一、WiredTiger引擎
MongoDB的WiredTiger引擎可以设置其可使用的最大内存,由cacheSizeGB参数控制,单位为G,表示WiredTiger引擎能够缓存的最大热数据量。每一个连接数都会消耗内存使用,可通过命令行db.serverStatus().connections查看当前连接数,如果连接数较大可通过连接池的方式控制mongodb的连接数。
1.1 WT cache重要监控指标
【注】针对MongoDB业务集群,建议增加WT cache百分比监控,并设置告警。正常情况cachesize的比例为80%时,是一个比较健康的值。当WT cache 100%,会导致业务大量请求超时。
1.2 常见异常解决方案
cachesize使用率过高,绝大多数都是业务侧问题引起的,常见解决方案如下:
1)优化慢查询
2)升级内存,并修改配置文件提升cachesize
3)调高threads_max,命令参考db.adminCommand({setParameter: 1, wiredTigerEngineRuntimeConfig: "eviction=(threads_min=8,threads_max=20)"})
官网MongoDB WiredTiger介绍:https://docs.mongodb.com/v4.0/core/wiredtiger/index.html
1.3 WT cache回收过程
WT cache回收主要是从WiredTiger 缓存中删除最近最少使用的页,以便为需要很快访问的其他页腾出空间。与大多数数据库一样,有专门的后台线程执行这项工作。
(1)理解 WiredTiger Checkpoints
从MongoDB4.2开始,WiredTiger引擎每60秒执行一个完整的checkpoint(由checkpoint=(wait=60)控制)。这意味着WiredTiger 缓存中的所有的脏页必须每60秒落盘一次。WiredTiger 缓存默认值是可用内存的50%,因此我们必须限制脏页的数量,完整checkpoint可能会导致性能“尖刺”。
Snapshots and Checkpoints :Checkpoint触发时机,设置检查点,时间间隔60s或写入了2G日志数据。wiredtiger journal 记录“checkpoint” 和 “checkpoint”之间的日志记录。
为什么默认的WiredTiger 缓存值只有可用内存的50%,而不是80%-90%。原因是MongoDB利用了操作系统的缓冲。在WiredTiger 缓存中,仅保存未压缩的页,而操作系统在将(压缩)页写入数据库文件时候对其进行缓存。通过为操作系统留下足够的可用内存,我们提高了从操作系统缓冲获取页的机会,而不是在页fault时,从磁盘读取。
(2)控制WiredTiger 缓存大小
eviction_trigger=95,eviction_target=80
上述参数表示为全部WiredTiger 缓存的百分比,并控制整个缓存的使用情况。使用量是指干净页和脏页的总和。让我们看一个示例:假设服务器内存为200G,WiredTiger 缓存设置为100G。回收线程将尝试将内存使用量保持在80G左右(eviction_target)。如果压力太大,缓存使用增加到高达95G(eviction_trigger),那么应用程序/客户端线程将被限流。怎样做的?它们将被要求在被允许执行自身任务之前帮助后台线程执行回收,帮助缓解一些压力,代价是增加客户端的延迟。如果这还不够,而且缓存达到了100%配置的缓存大小,操作将会阻塞。
(3)限制脏页的数量
eviction_dirty_trigger=20,eviction_dirty_target=5
上述参数控制缓存中脏页的数量。基本上,当脏页的数量是整个缓存的5%或更多时,回收线程就会参与。当数量增加到20%时,再次调用应用程序线程请求帮助,代价是增加了客户端的延时。在急剧或完全checkpoint中,所有脏页都必须落盘。这将尽可能长时间地使用磁盘所有的写IO。这就解释了为什么这些参数的默认值这么“低”,因为我们希望限制数据库在每个checkpoint必须执行的工作量。
上述参数表示为总的WiredTiger 缓存使用的百分比。我们可以得到的最小值是1%(不允许使用浮点值)。在一个大内存的服务器上,1%仍然是很多的!现在256G的缓存并不少见,其中1%是2.5G。一次全部落盘,一次花费一分钟。这对您的磁盘来说可能太多了,这取决于您使用的硬件类型。进一步减少这个数量的唯一方法是减少WiredTiger 缓存的大小,这将产生其他瓶颈。
(4)优化回收线程
默认情况下,MongoDB会分配后台线程来执行回收,我们可以指定最小值和最大值。因此,为了最小化停机时间,我们需要做的是控制脏页的数量,以便checkpoint花费的时间是“合理的”。记住,更多的线程意味着更多的IO带宽和更多的CPU资源(由于压缩)。
将回收线程数量增加到最大20,减少脏页阈值为1%-5%,同时设置WiredTiger 缓存的1G,这将限制脏页的数量为10-50M。
[root@ansible ~]# db.adminCommand( { "setParameter": 1, "wiredTigerEngineRuntimeConfig": "eviction=(threads_min=20,threads_max=20),checkpoint=(wait=60),eviction_dirty_trigger=5,eviction_dirty_target=1,eviction_trigger=95,eviction_target=80"})
注:此命令完成前客户端线程将被阻塞,为了安全期间,建议在业务窗口期操作。
(5)配置调整
# 查看WiredTiger内部缓存占用了多少内存 PRIMARY> db.runCommand( { serverStatus: 1 } ).wiredTiger.cache["bytes currently in the cache"] 138242 # 在线修改WT大小 PRIMARY> db.adminCommand({setParameter: 1, wiredTigerEngineRuntimeConfig: "cache_size=1G"}) { "was" : "", "ok" : 1, "operationTime" : Timestamp(1648895621, 1), "$clusterTime" : { "clusterTime" : Timestamp(1648895621, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }
二、mongostat工具性能分析
2.1 参数解读
字段名称 解释描述
insert 每秒插入次数
query 每秒查询次数
update 每秒更新次数
delete 每秒删除次数
getmore 每秒执行getmore次数
command 每秒的命令数,除了插入、查找、更新、删除命令统计外,还统计了别的命令
flushes 对于WiredTiger引擎来说,是指checkpoint的触发次数在一个轮询间隔期间
对于MMAPv1 引擎来说,是指每秒执行fsync将数据写入硬盘的次数
一般flushes都是0,间断性会是1, 通过计算两个1之间的间隔时间,可以大致了解多长时间flush一次。
flush开销是很大的,如果频繁的flush,就需要排查一下原因了[每秒执行fsync将数据写入硬盘的次数]
mapped 所的被mmap的数据量
vsize 虚拟内存使用量(在mongostat最后一次调用的总数据)
res 物理内存使用量(在mongostat最后一次调用的总数据)
vsize一般不会有大的变动, res会慢慢的上升,如果res经常突然下降,就需要排查一下是否存在其他的程序正在消费内存
faults 每秒访问失败数,与内存swap有关
qrw 客户端读写等待队列数量,高并发时,一般队列值会升高
arw 客户端读写活跃个数
net_in 网络带宽压力,MongoDB实例的网络进流量
net_out 网络带宽压力,MongoDB实例的网络出流量
conn 打开连接的总数,是qr,qw,ar,aw的总和
MongoDB为每一个连接创建一个线程,线程的创建与释放也会有开销,所以尽量要适当配置连接数的启动参数maxIncomingConnections
time 时间戳
2.2 案例讲解
[root@ansible ~]# mongostat -h192.168.0.224 --port 27017 --authenticationDatabase admin -uroot -p123456
注1:正常情况mongostat输出used部分不建议超出80%,当内存used超过80%时,说明内存压力过大,进而会引起SQL查询性能下降。(现象:正常的SQL变成慢查询)这个时候,就需要考虑升级内存,缓解内存压力!!!
注2:dirty是cachesize里的脏页,写入量或者QPS比较高的情况,这个比例会增大。
三、mongotop工具性能分析
3.1 参数解读
字段名出 解释说明
ns 全称namespace,由库名+点号+集合名组成
total 指定周期内每次统计mongod实例的读写总耗时时长
read 指定周期内每次统计的读操作耗时时长
write 指定周期内每次统计的写操作耗时时长
3.2 案例展示
[root@ansible ~]# mongotop -h192.168.0.224 --port 27017 --authenticationDatabase admin -uroot -p123456 2021-09-30T06:32:31.733+0000 connected to: 192.168.0.224 ns total read write 2021-09-30T06:32:32Z admin.system.roles 0ms 0ms 0ms admin.system.users 0ms 0ms 0ms admin.system.version 0ms 0ms 0ms local.me 0ms 0ms 0ms local.oplog.rs 0ms 0ms 0ms local.replset.minvalid 0ms 0ms 0ms local.startup_log 0ms 0ms 0ms local.system.replset 0ms 0ms 0ms
作者:UStarGao
链接:https://www.starcto.com/mongodb/247.html
来源:STARCTO
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
UCloud云平台推荐
随便看看
- 2021-07-17开源EyouCms博客安装教程
- 2021-09-24Postfix邮件服务器安装部署
- 2021-09-07Linux远程拷贝数据-限速和断点续传
- 2022-08-04MySQL RPM包方式安装教程
- 2021-09-04Linux磁盘UUID冲突解决方案