每种数据库本身都有自身的特性,同时面临的业务不同,也会导致每种数据库需要进行调节,来满足某种业务的需求.
大部分场景下,对于MONGODB的配置上都比较粗暴,这当然是相对于 PG, MYSQL 而言的,各种细微的调整,对于某些参数的琢磨. 那么实际上MONGODB 本身的参数也并不是不需要琢磨,他就能适应各种情况, 量变到质变的道理大家都懂.
这里重温一下文档的内容
1 在MONGODB 3.4 默认使用 50%的内存在数据库中有1G 内存及以上的情况,而如果在不足1G 内存的情况下使用 256MB的方式为MONGODB 提供内存服务.
问题,为什么是50% , 而不是和MYSQL 一样的60% - 80%,也就是说越大越好,这里如果使用过POSTGRESQL 则可能会理解MONGODB 的为什么要50%而不是更大,因为他们都要基于LINUX 的缓冲机制来进行相关的数据处理工作.
PG就不在赘述,而MONGODB 主要使用LINUX的缓冲技术的主要原因是数据压缩,使用过MONGODB的人都知道MONGODB对数据压缩后和实际数据的大小之间的比率还是比较大的,这样会节省数据的存储空间和以及相关的处理数据的成本.
但任何数据在进行处理之前都需要解压缩,而解压缩如果是从磁盘到内存则速度和相关的性能消耗都不会太低,则MONGODB选择了LINUX 的缓冲cache作为解压缩和压缩的一个环境.
问题1 MONGODB 到底多长时间checkpoint一次,下面做一个 test 来回答这个问题
从图中就可以很明确的看到这个问题,时间是1分钟,1分钟进行一次checkpoint 的操作.
这边通过程序,对MONGODB 进行压力测试,产生3000个连接,每个连接写入200000 行数据.
这里就会产生一个矛盾,如果我内存大,例如512G ,并且使用一半的内存256G,然后进行脏页的刷新,每隔60秒将数据刷入到磁盘.
那么我们会有几个问题需要考虑,大量的数据写入,我们有没有时间将这些内存的数据在1分钟内刷入到磁盘中,如果刷不完会怎样.磁盘的压力在此刻是不是会压力山大. 那这个是不是算一个在某些MONGODB 数据库中在承受大量写时需要进行相关的调优需要考虑的事情.
其中重要的eviction_trigger 是保证当使用内存达到多少百分比,开始将内存的数据刷入到磁盘中, eviction_target 则是当内存的占比只要大于设置的值默认80% 就一直将数据刷入到磁盘中.
eviction_target | continue evicting until the cache has less total memory than the value, as a percentage of the total cache size. Must be less than eviction_trigger. | an integer between 10 and 99; default 80. |
---|---|---|
eviction_trigger | trigger eviction when the cache is using this much memory, as a percentage of the total cache size. |
在高并发写入,并且内存不足的情况下,主库崩溃了,下面是相关的崩溃前的日志
那可以试想如果你拥有了大内存,还使用默认的参数,并且还持续大量的写入,你的磁盘性能 还是一般般的水平, 呵呵.
所以这篇文字的目的就是要怎么在上面的情况下,调整参数,来优化一下当下的问题.
当然如果你的磁盘是SSD 并且写入数量不大,当然可以忽略这里所探讨的一切.
db.adminCommand( { "setParameter": 1, "wiredTigerEngineRuntimeConfig": "eviction=(threads_min=3,threads_max=6),checkpoint=(wait=120),eviction_trigger=80,eviction_target=50"})
在调整完后,继续3000个并发每个并发20万的数据,可以从下图对比文章中的第一个图,可以看到 dirty 相对于第一张图来比较,
所以对于大内存的MONGODB ,如果在高并发高写入的情况下,适当的调整一下 eviction_trigger 和 eviction_target 可能对系统的性能会有提升.
另外上面的调整的参数需要根据自己的系统进行调整,不要按照文中的参数调整.