接上次文,当MONGODB 在操作时脏的数据块达到一定程度的情况下,就需要将这些数据转移到磁盘中,我们可以称之为驱逐。驱逐实际上是一个正常的操作,但是如果是一个大的驱逐的操作,换而言之,当你要推入磁盘的数据太大的时候,就会产生一个叫拥塞的东西,也就是你产生的“食物”,无法一次性快速的赛道嘴里,然后还要强塞,那你就噎着了。
解决这个问题的方法很多,
1 你拥有更强大的带宽的磁盘设备,也就是你有一张大嘴。
2 进来不要让你产生的食物涨大道可以噎死你的地步。
代码语言:javascript复制var wtt=db.serverStatus().wiredTiger
var blockingEvictRate=wtt['thread-yield']['page acquire eviction blocked']*100 / wtt['cache']['eviction server evicting pages']
上面的公式主要的含义为,我从我驱逐的页面再次获得我要的信息,与我从内存中驱逐的页面之比
通过上面的方式来计算你的数据的页面的驱逐率,当你发现你的MONGODB BLOCKED 驱逐率逐步走高的情况下。除了上面的你可以从硬件方面可以做的。
还可以试一下,通过调整参数的方式来让你的MONGODB 的支持更快的刷新速度。
代码语言:javascript复制db.adminCommand({
... ... setParameter: 1,
... ... wiredTigerEngineRuntimeConfig:
... ... `eviction=(threads_min=4,threads_max=4),
... ... eviction_dirty_trigger=5,eviction_dirty_target=1,
... ... eviction_trigger=95,eviction_target=80`
... ... });
上面的调整为,对wiredTiger引擎的配置进行更改,其中将驱逐的线程进行固化 4个, 并且触发脏页刷新的触发机制提前,这就类似于提高数据库的checkpoint 的频率。可以解决一部分的问题,但如果你的硬件真的不怎么样,这样做也是徒劳。
其实徒劳的原因和下一个我们说的操作 CHECKPOINT 有关, 大量的数据写入到内存中,必须要找时间释放到磁盘上,将脏页刷新到磁盘,默认的刷新时间为60秒,
那么一个不好的checkpoint 会产生什么影响
1 大量的数据瞬间写入到磁盘,会影响当时时刻的整体的数据库的性能,可能会导致短暂的语句的处理的缓慢的情况 。
那么如果磁盘出现锯齿装的I/O 那么就值得来看看我们的问题了
这里有两个参数我们上面使用过了
eviction_dirty_trigger
eviction_dirty_target_settings
这里会牵扯几个问题,1 多少信息保留在cache中 2 什么情况下会触发将内存的数据刷到我们的磁盘上,减少这些参数的情况下,可以提高刷新脏页的频度。
eviction.threads_min
eviction.threads_max
这两个是针对多少线程来进行对CHECKPOINT 的操作,这个设置与我们的CPU 的核心数和繁忙度有关。
checkpoint的时间设置可以调整, 减少时间可以增加数据的刷新率,但是如果间隔过短,但是数据量过大,会造成磁盘的压力,导致系统卡顿。
代码语言:javascript复制db.adminCommand({
setParameter: 1,
wiredTigerEngineRuntimeConfig:
`eviction=(threads_min=10,threads_max=10),
checkpoint=(wait=500),
eviction_dirty_trigger=5,
eviction_dirty_target=1`
});
所以当你发现的你的系统的性能在每个一分钟发生性能的抖动,那么很幸运也不幸运,你发现了问题,但解决是一个难题。
通过下面的命令可以去查看当前MONGODB 的配置文件信息
db._adminCommand( {getCmdLineOpts: 1})
下面是查看你刚刚配置的MOGNODB 的配置信息
代码语言:javascript复制db.adminCommand({getParameter: 1, wiredTigerEngineRuntimeConfig: 1})
与内存有关的性能问题还有一个地方就是我们的读写中的concurrency, 我们通过 db.serverStatus().wiredTiger.concurrentTransactions 来查看当前的系统中的状态是如何的。
代码语言:javascript复制db.adminCommand({setParameter: 1, wiredTigerConcurrentWriteTransactions: '256'})
为什么要动这个值,实际上对于MONGODB 频繁写入的情况下,通过Mongostat 来查看系统的性能的情况下,qw会持续的走高,这说明写入在进行排队的操作,WiredTiger无法满足数据插入的情况,此时如果CPU 负载不高情况下,可以调整上面的参数看看是否有改善,但带来的问题就是内存会使用率上升,另外不建议扩展的过高,太高对于CPU的负载压力过大。