MongoDB 生產環境筆記
在生產環境中,我們配置MongoDB
需要注意點有很多,而不是一安裝就可以使用。我們需要配置一些內核和系統參數。因為這些參數是會影響到我們 MongoDB
的性能的。
如果你的MongoDB
實例所在的服務器還有其它業務和應用,那么修改下面的參數需要注意是否會影響其它應用的性能和運行狀態。
官方文檔鏈接:https://docs.mongodb.com/manual/administration/production-notes/
需要配置的點有:
- [vm.zone_reclaim_mode](#一、vm.zone_reclaim_mode 參數)
- [添加swap分區](#二、添加 swap 分區)
- 設置 swappiness 參數
- 內核和文件系統版本
- [禁用 Transparent Huge Pages (THP)](#五、禁用 Transparent Huge Pages (THP))
- [ulimit 設置](#六、ulimit 設置)
- tcp_keepalive_time
- 同步時間
一、vm.zone_reclaim_mode 參數
設置內核參數 vm.zone_reclaim_mode
,該參數是設置當一個內存區域的內存耗盡的時候,是從內部回收,還是去下一個內存區域尋找,0為去下一個區域尋找,非0表示當前區域回收。
# 修改,重啟后失效
sysctl -w vm.zone_reclaim_mode=0
# 永久修改
echo "vm.zone_reclaim_mode = 0" >> /etc/sysctl.conf
sysctl -p
# 查詢當前參數配置
sysctl -a |grep vm.zone_reclaim_mode
二、添加 swap 分區
如果內存空間不是那么充足的話,我們可以為系統配置 swap 分區。具體配置見文章 linux系統添加swap(虛擬內存)分區。
對於 WiredTiger 儲存引擎,在壓力比較大的情況下,WiredTiger 會將數據放置在 swap 分區里。
三、設置 swappiness 參數
在 Linux 系統中,可以通過查看 /proc/sys/vm/swappiness 內容的值來確定系統對 SWAP 分區的使用原則。當swappiness 內容的值為 0 時,表示最大限度地使用物理內存,物理內存使用完畢后,才會使用 SWAP 分區。當swappiness 內容的值為 100 時,表示積極地使用 SWAP 分區,並且把內存中的數據及時地置換到 SWAP 分區。
默認值為 0,表示需要在物理內存使用完畢后才會使用 SWAP 分區,
如果我們運行的主機系統 RHEL / CentOS 的內核版本在 2.6.32-303 及以上,我們可以把該值設置為 1。
# 臨時修改
sysctl -w vm.swappiness=1
# 永久修改
cat "vm.swappiness = 1" >> /etc/sysctl.conf
sysctl -p
# 查看配置參數
sysctl -a |grep vm.swappiness
四、內核和文件系統版本
在 Linux 系統上運行 MongoDB ,我們建議使用 Linux內核版本2.6.36或者更高版本,使用 XFS 或者是 EXT4 文件系統,強烈建議使用 XFS 文件系統。因為 EXT4 和 WiredTiger 一起使用會有可能出現性能問題。
MongoDB 需要使用 glibc 庫,最好版本至少是 2.13 上。
五、禁用 Transparent Huge Pages (THP)
在啟動的時候我們可以看到類似的日志:
2019-04-12T10:11:26.665+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2019-04-12T10:11:26.665+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2019-04-12T10:11:26.665+0800 I CONTROL [initandlisten]
2019-04-12T10:11:26.665+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2019-04-12T10:11:26.665+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
上面的警告就是意味着我們需要設置 /sys/kernel/mm/transparent_hugepage/defrag
和/sys/kernel/mm/transparent_hugepage/enabled
兩個參數設置為 never ,上面參數的設置就是代表着 Transparent Huge Pages(THP)
, 在了解 THP 前,我們需要先了解下 Huge Pages(標准頁),Huge Pages是從Linux Kernel 2.6后被引入的。目的是使用更大的內存頁面(memory page size) 以適應越來越大的系統內存,讓操作系統可以支持現代硬件架構的大頁面容量功能。而THP(Transparent Huge Pages) 是從RHEL6 開始引入的一個功能,THP 是一個抽象層, 可以自動創建、管理和使用傳統大頁的大多數方面。
Huge pages can be difficult to manage manually, and often require significant changes to code in order to be used effectively. As such, Red Hat Enterprise Linux 6 also implemented the use of transparent huge pages(THP). THP is an abstraction layer that automates most aspects of creating, managing, and using huge pages.
THP hides much of the complexity in using huge pages from system administrators and developers. As the goal of THP is improving performance, its developers (both from the community and Red Hat) have tested and optimized THP across a wide range of systems, configurations, applications, and workloads. This allows the default settings of THP to improve the performance of most system configurations. However, THP is not recommended for database workloads.
在官方文檔中最后一行寫到: THP is not recommended for database workloads.
也就是 THP 不適用於在數據庫上。因為數據庫是不連續的內存訪問模式,我們需要禁用THP以確保使用MongoDB獲得最佳性能。
詳細的有關 Huge Pages 和Transparent Huge Pages的介紹見 :文章
查看 Transparent Huge Pages 狀態
cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
cat /sys/kernel/mm/transparent_hugepage/defrag
[always] madvise never
#如果輸出結果為[always]表示 THP 啟用了。[never]表示 THP 禁用、[madvise]表示(只在MADV_HUGEPAGE標志的VMA中使用THP
腳本禁用 THP
創建 init.d 腳本 /etc/init.d/disable-transparent-hugepages
#!/bin/bash
### BEGIN INIT INFO
# Provides: disable-transparent-hugepages
# Required-Start: $local_fs
# Required-Stop:
# X-Start-Before: mongod mongodb-mms-automation-agent
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Disable Linux transparent huge pages
# Description: Disable Linux transparent huge pages, to improve
# database performance.
### END INIT INFO
case $1 in
start)
if [ -d /sys/kernel/mm/transparent_hugepage ]; then
thp_path=/sys/kernel/mm/transparent_hugepage
elif [ -d /sys/kernel/mm/redhat_transparent_hugepage ]; then
thp_path=/sys/kernel/mm/redhat_transparent_hugepage
else
return 0
fi
echo 'never' > ${thp_path}/enabled
echo 'never' > ${thp_path}/defrag
re='^[0-1]+$'
if [[ $(cat ${thp_path}/khugepaged/defrag) =~ $re ]]
then
# RHEL 7
echo 0 > ${thp_path}/khugepaged/defrag
else
# RHEL 6
echo 'no' > ${thp_path}/khugepaged/defrag
fi
unset re
unset thp_path
;;
esac
chmod 755 /etc/init.d/disable-transparent-hugepages # 設置具有可執行權限
chkconfig --add disable-transparent-hugepages # 設置開機自啟
上面的配置需要重啟主機才能生效。
生效配置
/etc/init.d/disable-transparent-hugepages start
配置 tuned 和 ktune
tuned
和ktune
是Red Hat和CentOS上可用的動態內核調優工具,可以禁用 THP 。
要在 tuned
和ktune
中禁用 THP, 需要我們將配置文件的THP值設置為 never,否則 tuned 或者 ktune 會更改我們設置的值。
When RHEL 7 / CentOS 7 run in a virtual environment, the
tuned
tool automatically invokes a performance profile derived from performance throughput, which automatically sets the readahead settings to 4MB. This can negatively impact performance.
CentOS 6
cp -r /etc/tune-profiles/default /etc/tune-profiles/no-thp
echo "set_transparent_hugepages never" >>/etc/tune-profiles/no-thp/ktune.sh
tuned-adm profile no-thp
CentOS 7
mkdir /etc/tuned/no-thp
cat << EOF >>/etc/tuned/no-thp/tuned.conf
[main]
include=virtual-guest
[vm]
transparent_hugepages=never
EOF
tuned-adm profile no-thp
測試修改是否生效
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag
生效配置:
always madvise [never]
六、ulimit 設置
通常系統默認給用戶的最大進程數和最大可以打開的文件數是比較低的,所以在啟動 MongoDB
的時候我們會看到以下警告。
WARNING: soft rlimits too low. rlimits set to 4096 processes, 65535 files. Number of processes should be at least 32767.5 : 0.5 times number of files.
官網的推薦配置是:
# 推薦配置
-f (file size): unlimited
-t (cpu time): unlimited
-v (virtual memory): unlimited [1]
-l (locked-in-memory size): unlimited
-n (open files): 64000
-m (memory size): unlimited [1] [2]
-u (processes/threads): 64000
我們可以直接更改用戶的默認配置,也可以通過配置 systemd
服務,並參數寫入 Service
。
cat <<EOF >>/usr/lib/systemd/system/mongodb.service
[Unit]
Description= mongodb service manager
[Service]
# Other directives omitted
# (file size)
LimitFSIZE=infinity
# (cpu time)
LimitCPU=infinity
# (virtual memory size)
LimitAS=infinity
# (locked-in-memory size)
LimitMEMLOCK=infinity
# (open files)
LimitNOFILE=64000
# (processes/threads)
LimitNPROC=64000
Type=forking
User=mongodb
Group=mongodb
PIDFile=/opt/mongodb/logs/mongod.pid
ExecStart= /opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.conf
ExecStop= /opt/mongodb/bin/mongod --shutdown --dbpath /opt/mongodb/data
Restart=always
[Install]
WantedBy=multi-user.target
EOF
七、tcp_keepalive_time
該參數用於 TCP 發送 keepalive 探測消息的間隔時間(秒),用於確認 TCP 連接是否有效。
查看系統的默認值:
# 通過sysctl 查看
sysctl net.ipv4.tcp_keepalive_time
# 通過查看文件的值
cat /proc/sys/net/ipv4/tcp_keepalive_time
# 一般系統的默認值是 7200
Mongodb 官網建議將該值設置為 300 。
臨時更改
systemctl -w net.ipv4.tcp_keepalive_time=300
永久更改,
echo "net.ipv4.tcp_keepalive_time = 300" >> /etc/sysctl.conf
sysctl -p
八、同步時間
如果我們部署的是副本集群,我們需要配置腳本,讓這幾台節點的的時間同步。