MongoDB效能優化
阿新 • • 發佈:2018-12-31
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
- 禁用THP:Transparent Huge Pages(THP)是Linux記憶體管理策略會佔用大量的記憶體
# 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設定太小,以下是推薦設定
- 模式設計:關聯模式和巢狀模式,見下圖,根據應用設計最合理的模式。
- 文件的key命名儘量短,比如ParkingId可以改為pid。超過16MB,大文件儘量使用GridFS
- 在叢集環境下,避免scatter-gather查詢。其實這依賴於sharding的方式和sharding key的選擇,要儘量滿足大部分的業務需求。
- 讀寫分離設計:在讀延遲允許範圍內,進行讀寫分離是個不錯的選擇,可以大大降低主節點壓力。
- 類似關係型資料庫,一些優化建議:只查詢和更新需要的欄位,減少頻寬;避免使用否定條件查詢;合理使用覆蓋索引並考慮最左字首匹配原則;
- 預讀設定:使用blockdev --setra <value>命令設定預讀,單位是512B(扇區大小),不少於32kb,也不要設定太大,浪費I/O,設定大的預讀有助於順序讀,具體的配置根據業務需求設定。
- 使用EXT4或者XFS檔案系統。不要使用EXT3哦。
- 禁止Access Time設定。作業系統會維護檔案最後的訪問時間metadata,對於資料庫意味著每次檔案系統每訪問一個頁就會提交一個寫操作,這將降低整個資料庫的效能。
- 禁用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引數設定