MongoDB是一個高性能可擴展基於文檔的NoSQL數據庫,高性能也須要在多個關鍵維度的配置,包括硬件、應用模式、模式設計、索引、磁盤I/O等。
存儲引擎
WiredTiger是3.0之後的默認存儲引擎,細粒度的併發控制和數據壓縮提供了更高的性能和存儲效率。3.0之前默認的MMAPv1也提升了性能。在MongoDB複製集中能夠組合多鍾存儲引擎,各個實例實現不一樣的應用需求。
硬件
MongoDB初衷是採用水平擴展構建集羣,而不是價格更高的硬件升級。採用複製保證高可用,自動分片使數據均勻分佈在各節點服務器上;in-memory計算提供更高的計算性能,該引擎只有企業版有
硬件配置要求
- 確保內存設置能知足性能需求:確保內存>索引容量+高頻訪問數據容量,經過storage.wiredTiger.engineConfig.cacheSizeGB或--wiredTigerCacheSizeGB進行設置。經過監控db.serverStatus()命令查看並評估
- 寫操做負載高的應用採用SSD:SATA接口的SSD提供強大的順序寫性能,能提升MongoDB數據和jounal日誌文件的寫入速度;同時最爲強大的是隨機讀取性能,這點符合MongoDB的數據訪問vi 模式。部署採用RAID-10,比RAID-5/RAID-6減小不少限制,並提供更高性能。
- 存儲引擎配置數據壓縮和I/O-intensive worloads:WiredTiger存儲引擎支持本地壓縮,可以更好的使用多核新處理器資源。
- 爲每一個MongoDB服務提供專用服務器:在單一服務器上安裝多個MongoDB實例,系統會計算每一個實例合適的緩存,併爲每一個實例分配默認的cache_size。經過storage.wiredTiger.engineConfig.cacheSizeGB參數調整。
- 使用多路查詢路由:在不一樣服務器上使用多個mongos,最好將mongos部署在應用服務器上。
- 利用多核心:WiredTiger存儲引擎是多線程且能夠充分利用CPU多核心。MMAPv1存儲引擎由於其併發模型,因此並不要求更多的CPU核心。
- 開啓NTP時間同步服務
- 禁用NUMA:MongoDB運行在NUMA系統上會致使操做問題,禁用NUMA須要配置mermory interleave policy
編寫腳本/etc/init.d/pro-startMongo
...
# disable NUMA
sysctl -w vm.zone_reclaim_mode=0
啓動時必須指定numactl方式
numactl --interleave=all <path> <options>
- 禁用THP:Transparent Huge Pages(THP)是Linux內存管理策略會佔用大量的內存
編寫腳本/etc/init.d/pro-startMongoDB,加入了前面禁用NUMA部分
# disable transparent hugespages
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
# disable NUMA
sysctl -w vm.zone_reclaim_mode=0
;;
esac
更改腳本權限並加入自啓動
sudo chmod 755 /etc/init.d/pro-startMongo
sudo chkconfig --add pro-startMongo
經過如下測試是否關閉了THP
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag
以下顯示錶示成功
always madvise [never]
- 設置ulimit:默認的ulimit設置過小,如下是推薦設置
-f (file size): unlimited
-t (cpu time): unlimited
-v (virtual memory): unlimited
-n (open files): 64000
-m (memory size): unlimited
-u (processes/threads): 64000
我是新建/etc/security/limits.d/99-mongodb-nproc.conf文件,加入以下配置:
mongod soft fsize unlimited
mongod hard fsize unlimited
mongod soft cpu unlimited
mongod hard cpu unlimited
mongod soft as unlimited
mongod hard as unlimited
mongod soft nofile 64000
mongod hard nofile 64000
mongod soft nproc 64000
mongod hard nproc 64000
應用、模式設計
- 模式設計:關聯模式和嵌套模式,見下圖,根據應用設計最合理的模式。
- 文檔的key命名儘可能短,好比ParkingId能夠改成pid。超過16MB,大文檔儘可能使用GridFS
- 在集羣環境下,避免scatter-gather查詢。其實這依賴於sharding的方式和sharding key的選擇,要儘可能知足大部分的業務需求。
- 讀寫分離設計:在讀延遲容許範圍內,進行讀寫分離是個不錯的選擇,能夠大大下降主節點壓力。
- 相似關係型數據庫,一些優化建議:只查詢和更新須要的字段,減小帶寬;避免使用否認條件查詢;合理使用覆蓋索引並考慮最左前綴匹配原則;
硬盤I/O
- 預讀設置:使用blockdev --setra <value>命令設置預讀,單位是512B(扇區大小),很多於32kb,也不要設置太大,浪費I/O,設置大的預讀有助於順序讀,具體的配置根據業務需求設定。
- 使用EXT4或者XFS文件系統。不要使用EXT3哦。
- 禁止Access Time設置。操做系統會維護文件最後的訪問時間metadata,對於數據庫意味着每次文件系統每訪問一個頁就會提交一個寫操做,這將下降整個數據庫的性能。
編輯/etc/fstab文件,指定noatime和nodiratime
/dev/sdb /data ext4 defaults,noatime,nodiratime 1 2
- 禁用Huges Pages虛擬內存頁,MongoDB使用普通虛擬內存頁性能更好,這個前面提到過。
- 使用RAID10,性能高於RAID-5或RAID-6
- swap設置:設置充足的swap空間防止OOM程序殺掉mongod進程,對於Linux下的MMAPv1存儲引擎,不會使用swap空間,能夠少許設置swap空間;Windows下的MMAPv1存儲引擎須要設置swap空間;WiredTiger存儲引擎,須要設置較大的swap空間。使用WiredTiger測試過程當中,發現對於大查詢,沒有足夠的swap空間甚至會報錯。在/etc/sysctl.conf設置vm.swappiness爲0,儘可能使用內存。swap分區儘量大些,如下是一些建議。測試過程當中是128G內存,我設置交換分區內存大小也是128G。
- 日誌和數據文件分開存儲,日誌存儲在普通SAS盤上,數據存儲在SSD上。數據庫的讀通常都是隨機讀,SSD在隨機讀性能上表現很是好;日誌文件主要是順序寫,速度自己較高,而SSD在順序讀寫上的表現很是糟糕,並且比普通SATA性能還要低。Mongodb的日誌有journal和syslog,journal日誌只能放在dbPath下面的journal目錄中,而系統日誌能夠指定日誌路徑。journal能夠掛載個SATA硬盤設備。這樣作到日誌和數據分離。
- 多路徑設置:設置storage.wiredTiger.engineConfig.directoryForIndexes使索引和數據分離,設置該參數爲true後,會在dbPath下面創建一個index目錄,在index目錄下掛載一個硬盤設備,使索引和數據作到分離。設置directoryPerDB每一個數據庫不一樣目錄,對於每一個目錄最好掛載到不一樣的硬盤設備上。
- 壓縮:WiredTiger提供snappy和zlib兩種數據壓縮方式。snappy提供壓縮比低可是性能損耗低,zlib壓縮比高但性能損耗較高,經過storage.wiredTiger.collectionConfig.blockCompressor參數設置