-
cache_size
指定WT存储引擎内部cache的内存用量上限。
需要注意的是,仅作用于WiredTiger cache,而非mongod进程的内存用量上限。MongoDB同时使用WT cache和文件系统cache,往往mongod进程的内存用量高于该值。cache_size相对于物理内存总量不要设置的太满,需要留有一定内存为操作系统所用,否则有OOM潜在风险。
默认情况下,cache_used超过80%将触发eviction,如果物理内存充足,建议设置足够大的cache_size,以加载全部数据,避免不必要的eviction。
个人经验值 cache_size = (data + index) / 0.8
cache_size支持在不停服的情况下动态调整,比如将cache_size设置为80GB,执行如下命令:
db.adminCommand({setParameter: 1, wiredTigerEngineRuntimeConfig: "cache_size=80G"})
-
eviction
cache_used是很关键的指标,超过80%将触发eviction,类似LRU算法,淘汰冷数据,避免cache用量持续增长。
一个健康的MongoDB服务,其cache_used应该不超过80%,即使超过,能在短时间内降到80%也是没问题的。如果长时间高于80%则需要重视起来,因为cache_used过高会导致数据库性能下降,体现在慢操作(读写请求耗时长)、qr/qw高(读写请求排队)等方面。所以我们要极力保证cache_used在一个健康的范围内。
eviction包括很多参数,比如
eviction_trigger
、eviction_target
、eviction_dirty_target
等,指定在什么条件下触发和停止cache eviction,这里,我更关心的是eviction线程数量。对于eviction线程,MongoDB默认配置是
eviction=(threads_min=1,threads_max=4)
,根据cache使用情况,创建1-4个eviction线程去淘汰冷数据。如果cache体积较大 数据量大、读写频繁,那么需要更多的eviction线程。
如果调高threads_max仍然无法降低cache_used,建议设置更大的cache_size
动态调整配置:
db.adminCommand({setParameter: 1, wiredTigerEngineRuntimeConfig: "eviction=(threads_min=1,threads_max=8)"})
-
wiredTigerConcurrentWriteTransactions
指定最大并发写事务数。
对于写频繁的服务,通过mongostat查看运行状态,如果qw持续较高、aw经常是128(默认值),说明写请求发生排队,同时WT无法提供更高的并发写。
此时观察CPU负载,如果负载不高(相对于核数,CPU未充分利用),尝试调高此参数,能够一定程度上缓解问题,即使出现qw高,往往也是短暂的,可能下一秒恢复正常。
调高此参数,相当于压榨CPU,CPU负载较之前会有一定增加,如果负载在合理范围内,可以接受;负载过高的话,建议扩容。
建议根据实际情况动态调整,并持续观察效果,找到一个合理的值。
查看当前配置:
db.adminCommand({getParameter: 1, wiredTigerConcurrentWriteTransactions: 1}) or db.adminCommand({getParameter: '*'}).wiredTigerConcurrentWriteTransactions
动态调整配置:
db.adminCommand({setParameter: 1, wiredTigerConcurrentWriteTransactions: 512})
tcmalloc
tcmalloc提供了释放速度字段来调节缓存的释放速度tcmallocReleaseRate,官方建议是0-10,0表示永不释放,默认是1。实际为0~1000
db.adminCommand({setParameter:1, tcmallocReleaseRate:500})
释放太过激进的内存占用,配合tcmallocReleaseRate使用。这2个配置可以让MongoDB尽快释放内存。
db.adminCommand({setParameter:1,tcmallocAggressiveMemoryDecommit:1})
读写并发设置
wiredTigerConcurrentReadTransactions
允许并发读取的最大值,默认128。
db.adminCommand( { setParameter: 1, wiredTigerConcurrentReadTransactions: <num> } )
wiredTigerConcurrentWriteTransactions
允许并发写入的最大值,默认128。
db.adminCommand( { setParameter: 1, wiredTigerConcurrentWriteTransactions: <num> } )
Checkpoint刷盘
db.adminCommand({setParameter: 1, wiredTigerEngineRuntimeConfig:`checkpoint=(wait=30,log_size=1GB)`})
环境变量设置
WIREDTIGER_CONFIG=checkpoint=(wait=30,log_size=1GB)
如果写入数据还没到Evict的比例,只能通过checkpoint定时刷盘。通过调整checkpoint的wait时间,即时把脏数据写入磁盘,避免用户线程参与evict数据。减少checkpoint的wait时间可以提高磁盘IO的利用率
IO优化
网络压缩
networkMessageCompressors
是MongoDB配置中的一个关键参数,用于启用网络数据传输时的压缩功能。通过设置这个参数,MongoDB可以在数据传输过程中对消息进行压缩,减少数据在网络上传输的大小,从而提高网络I/O性能。
在mongod.conf
或启动mongo实例时的配置文件中,你可以指定networkMessageCompressors
参数来指定要使用的压缩算法。例如,你可以将其设置为zlib
表示使用zlib压缩算法。除了zlib
之外,MongoDB还支持snappy
和zstd
等压缩算法。
示例配置:
net: compression: compressors: zlib
通过启用数据压缩,MongoDB可以减少数据在网络传输时的大小,降低网络带宽的消耗,并且能够提高MongoDB集群在网络I/O方面的性能表现
除MongoDB本身的配置外,操作系统的配置也会影响数据库的性能
实现所有MongoDB Server的时间同步
减少时间戳记录
关闭磁盘预读值(read-ahead)
关闭内存管理
禁用非同意内存访问(non-uniform memory access)
实现所有MongoDB Server的时间同步
集群是由多台Server 配置而成的,不能存在时间不同步的情况。因此,我们通过操作系统的NTP 服务来实现所有MongoDB Server的时间同步。
了解时间同步(NTP )
NTP ( network time protocol )是用来对网络中的Server进行时间同步的协议。在局域网中,时间同步的精确度可达到0.1ms;在互联网中,时间同步的精确度可达到150ms。因此,对时间同步有要求的系统,都可以使用NTP来实现。
我们先对操作系统的时间有一个初步的了解:
软件时间是指, Linux 操作系统从1970-01-01到当下计算出来的总秒数。
硬件时间是指,以BIOS内部的时间为主要的时间依据。
如果BIOS内部芯片出现问题,则会造成BIOS时间与标准时间不一致。
在使用NTP服务时,不允许Server与同步源之间的误差时间超过1000s,因此需要先手动将时间与同步源同步,再设定NTP服务。
设定时间同步有两种方式: -种方式是手动命令设定时间同步,另一种方式是通过服务自动实行时间同步。
手动设定时间同步
手动设定时间同步是通过命令来指定同步源的IP地址或域名。这种同步是单次同步。手动设定时间同步的格式如下:
手动与某台Server (以IP地址“10.10.10.10" 为范例)同步
ntpdate 10.10.10.10
手动与中国公共NTP服务器同步
ntpdate cn.pool.ntp.org
通过服务自动实现时间同步
通过NTP服务可实现实时的时间自动同步。需在服务文件中设定同步源的IP地址。
通过NTP的文件ntp.conf来设定想要与哪台Server同步。
编辑ntp文件,命令如下:
vim /etc/ntp.conf
文件内容如下:
#server 0.centos.pool.ntp.org
#server 1.centos.pool.ntp.org
#server 2.centos.pool.ntp.org
#允许10.10.10.10连接本NTP服务器
restrict 10.10.10.10
#设定时间同步来源主机10.10.10.10
server 10.10.10.10
当此台主机为NTP服务器时restrct用来管理哪些主机可以连到此比台服务器实现时间同步,server用来设定从哪台NTP服务器同步时间。
设定完NTP服务后,启动NTP服务,命令如下:
systemctl start ntpd
查看NTP服务是否正常运行,命令如下:
systemctl stalus ntpd
执行的结果如下:
ntpd.service - Network Time Service
Loaded : loaded (usrlib/systemdisystemintpd .service ; disabled )
Active : active (running) since Sat 2018-03-24 11:02:57 CST ;2 weeks 5days ago
Process : 46232 Execstar-/usr/sbin/ntped - u ntp:ntp $OPTIONS ( code=exited, status=0/SUCCESS ) Main PID: 46232 ( ntpd )
查看使用哪台Server进行时间同步。
ntpstat
ntpq -P
可在操作系统中使用"date" 命令查看同步之后的时间。
减少时间戳记录
在默认情况下,Linux文件系统文件在被访问,创建、修改时都会记录时间戳,例如文件的创立时间、最后一次修改时间、最近一一次访问时间等。
在系统运行时,如果大量存取磁盘文件,则会使设备-直处于忙碌的状态,从而影响性能。如果能减少一些磁盘存取的动作(如减少时间戳的记录),则可以降低磁盘I/O的负载。
时间戳的选项
时间戳包含以下几个选项。
atime: 记录文件系统中每个文件的最后访问时间。即使只读取数据,时间戳也会被写入硬盘。
noatime:不记录任何文件的访问时间。但这样可能会造成有前后访问时间关系的程序失常。
relatime:在以下两种情况记录时间戳。
如果文件的最后访问时间早于最后更改时间,则记录文件的最后访问时间。
如果访问时间超过定义的间隔(RHEL,默认为1天),则记录文件的最后访问时间
设定时间戳记录
设定时间戳记录,需在/etc/fstab 这个文件中修改系统参数。
找到MongoDB准备放置数据的目录
本书的范例将数据放在/data目录下,所以将/data 目录进行修改,将其设为noatime.
注意:①MongoDB不一定要安装在/data这个目录下,这个目录默认是不存在的:②也不一定要为这个目录挂载一个单独的卷,这并非必要的配置。
编辑/etc/fstab文件
命令如下:
vim /etc/fstab
修改文件内容如下:
/dev/sda1 /data xfs defaults,noatime 00
修改完毕后需要重新挂载,才能使设置生效
mount -o remount/
在进行建些提置时需要特别小心,图为是时破盘做操作,如果推作错遇到 可能导致整台Senver 死机
关闭磁盘预读功能
磁盘预读是指Linux内核对系统文件进行预先读取,即将文件从磁盘预先读到内存缓存中。因为读取内存的速度比读取磁盘的速度快很多,所以,磁盘预读不仅可以提高文件读取的效率,也可以减少磁盘的访问量及I/0的等待时间。
因为MongoDB不一定是按照因定的顺序将数据存进磁盘、而里大多就时候MonpoDB不会按照磁盘顺序来读取数据。所以磁盘预读的文件与MongoDB直接读取磁盘的文件不同。因此,磁盘预读对MongoDB并没有真正的帮助,反而可能影响了性能。
如果磁盘预读值被设定为0,则表示不使用磁盘预读功能。
手动关闭
关闭磁盘预读有两种方法:
手动关闭
让系统自动关闭
查看存放数据目录所挂载的磁盘分区
不论是手动设定还是让系统自动设定,都需要提前知道MongoDB数据所在目录挂权的磁盘分区。
我们存放数据的目录为/dalta,使用命令可以知道/data挂载的磁盘分区为/dev/mapper/centos-home。具体方法如下。
查看存放数据目录所挂载的磁盘分区
df -h
手动关闭磁盘预读功能
使用以下命令查看磁盘预读大小:
/sbin/blockdev --getra ldev/mapper/centos-home
关闭磁盘预读命令(设定为0),命令如下:
/sbin/blockdev -- setra 0/dev/mapper/centos-home
若想确定blockdev的绝对路径,可以使用“which blockdev"命令来查看。
一般来说, 都是在“/usr/sbi/blockdev" 路径下,而“/usr/sbin" 是挂载在“/usr” 下,因此使用 “/usr/sbin/blockdev” 与“/sbin/blockdev" 是一一样的。
让系统自动关闭
也可以设定排程,让系统自动关闭磁盘预读。具体方法如下。
在本地初始化的程序中加入修改磁盘预读为0的命令。
编辑本地初始程序文件,具体命令如下:
vim /etc/rc.local
/usr/sbin/blockdev --setra 0/dev/mapper/centos-home
设定/etc/rc.d/rc.local的执行权限( "a+x"表示全部角色都可以执行)
chmod a+x /etc/rc.d/rc.local
查看/etc/rc.d/rc.local的权限状态:
/etc/rc.d/rc.local
其中,第1个字母"d"代表文件类型。然后是三组“rwx” (r代表读: w代表写; x代表可执行)
第1组"rwx"代表的是所属者的权限。
第2组"rwx" 代表的是同群组成员的权限。
第3组“rwx"代表的是其他人的权限。
如果没有某个权限,则用“-”代替。
上面代码中“-rwxr-xr-x" 表示:
第1个字母为“-” ,表示这不是文件类型的文件。
所属者的权限是“rwx" ,可以读写/执行。
同群组成员的权限是 “r-x"可以读/执行,没有写权限(“写”权限用“-”代替了)。
其他人的权限是“r-x",可以读/执行。
如将权限设定为“a+x", 则表示全部角色都可执行。
执行这个本地初始化的程序有以下两种做法:
将本地初始化的程序作为服务启动。
启动服务命令:
systemctl start rc-local
查看服务状态命令:
systemctl status rc-local
查看到的结果如下:
rc-local.service -letc/rc.drc.local Compatibility
Loaded : loaded (usilib/systemnd/system/rc local.service ;static )_ 成功启动 Active Lactive ( exited) since Fni 2017-09 -29 10:53:36 CST ;7s ago
Process:15803 ExecStart/etclrc.dIrc localstart (code=exited,ited.status=0/SUCCESS)
建立排程来定时执行命令。
编辑排程文件:
vim /etc/crontab
文件内容如下:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MALTO=root
00 01 * * * root /etc/rc.d/rc.local
完成设定后,可以使用以下命令来查看一下磁盘预读的大小:
/sbin/blockdev --getra /dev/mapper/centos-home
查询到的结果如下:
0
关闭内存管理
在Linux操作系统中,内存是由CPU的内存管理单元来管理的。操作系统使用映像表(即“内存页条目")来记录虚拟内存页及物理内存页的对应关系。如果内存页较小,则需要较大的映像表来记录对应关系:如果内存页较大,则可以用较小的映像表来记录对应关系。
了解标准大页和透明大页
在了解内存页与映射表的关系后,将继续介绍管理内存页的机制,分为两种:大页(Huge Pages, HP)和透明大页( Transparent Huge Pages, THP )。
大页(Huge Pages )
大页就是一种很大的内存页。使用它可以减少映射表的大小,以提高CPU检索内存映射表的命中率。
透明大页(THP )
在系统运行时,THP会动态地调整内存,且配置后不需要重启操作系统即可生效( MongoDB进程需要重启)。为动态分配,在系统运行时内存分配会有延迟的情况。
透明大页是以Centos/RedHat6.0开始使用的,Centos7.0版本开始为默认启用对数据库而言,访问内存并非连续的,因此启用透明大页并没有实际上的效益,反而会造成性能上的影响,因此需要将其英闭
在CentOS 7.0中配置THP
暂时配置
在执行命令之后,可以手工将THP调整为关闭状态,但在重新启动后会还原设定。
禁用THP,命令如下:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
只禁用THP的碎片整理功能,命令如下:
cho never > sys/kernel/mm/transparent_hugepage/defrag
永久配置
创建新的Profile文件,命令如下:
sudo mkdir /etc/tuned/no-thp
编辑tuned.conf文件,命令如下:
vim /etc/tuned/ho-thp/tuned.conf
文件内容如下:
[mian]
include=virtual-guest
[vm]
transparent_hugepages_never
启动profile,命令如下:
sudo tuned-adm profile no-thp
检查结果是否关闭THP
查询THP的状态,命令如下:
cat /sys/kernel/mm/transparent_hugepage/enabld
查询THP碎片整理的状态,命令如下:
cat /sys/kernel/mm/transparent_hugepage/defrag
禁用“非统一内存访问”( NUMA )
首先先来了解一下什么是非统 -内存访问 ( non-uniform memory access ),介绍它在硬件资源使用上有什么好处,并告诉大家为什么要禁用NUMA机制。
NUMA 的工作原理
NUMA是当服务器为多核时,在内存使用上的设计方式。此设计会将CPU与内存平均分配在多个逻辑节点(node)上。
每个节点上均有独立的CPU与内存,可以解决硬件资源扩展问题。当程序或进程在某节点上使用本地内存时会有比较好的性能,但使用其他节点的内存时性能会比较差。
节点的数量取决于CPU的数量-般来说通常为两个节点,最多不超过4个。如CPU为16核、内存32G、物理CPU为2,则会有两个节点(node0、node1),每个节点会有8核16GB内存。
查看硬件的NUMA分配节点资源的情况
可使用以下命令查看NUMA机制分配节点资源分配的情况:
numactl -hardware
禁用NUMA机制
在内存大且多CPU的环境下,采用NUMA机制确实能提升不少性能。但是对于内存需求较大的数据库来说,若本地节点的内存用尽,则不会使用其他节点的内存,而是默认优先将内存数据置换到磁盘中的swap空间,井回收本地节点的内存。此换动作会造成性能变差。因此,数据库若是在NUMA机制上运行,则在硬件的内存还没完全用尽时就会使用到swap置换,从而造成性能变差。
解决此问题需要两个步骤:首先禁用内存回收的功能,然后设定MongoDB可以使用全部节点的内存。
禁用内存回收的功能,命令如下:
echo 0|sudo tee/proc/sys/vm/zone_reclaim_mode
或文章来源:https://www.toymoban.com/news/detail-804054.html
sudo sysctl -w vm.zone_reclaim_mode=0
使用numactl启动MongoDB服务,使得MongoDB可以使用全部节点的内存,命令如下:
numactl --interleave=all mongod -f /etc/mongod.conf
至此,禁用NUMA机制的操作就完成了。文章来源地址https://www.toymoban.com/news/detail-804054.html
到了这里,关于MongoDB系统性能调优(持续更新)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!