栏目头部广告

MongoDB性能分析之WiredTiger引擎

一、WiredTiger引擎

MongoDB的WiredTiger引擎可以设置其可使用的最大内存,由cacheSizeGB参数控制,单位为G,表示WiredTiger引擎能够缓存的最大热数据量。每一个连接数都会消耗内存使用,可通过命令行db.serverStatus().connections查看当前连接数,如果连接数较大可通过连接池的方式控制mongodb的连接数。

1.1 WT cache重要监控指标

MongoDB性能分析之mongostat(图1)

MongoDB性能分析(图2)

【注】针对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可能会导致性能“尖刺”。

MongoDB性能分析(图3)

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

MongoDB性能分析(图2)

注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云平台推荐


UCloud新用户专属注册连接

UCloud CDN超值特惠专场

UCloud全球云主机(UHost/VPS)大促页面

UCloud快杰云主机大促页面

文章页广告

随便看看

栏目底部广告
`