MONGODB 性能与调优 -- 内存调优 2 (怎么计算驱逐率与调整参数)

接上次文,当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的负载压力过大。