標籤:
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 NUMAsysctl -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 hugespagescase $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-startMongosudo chkconfig --add pro-startMongo 通過以下測試是否關閉了THPcat /sys/kernel/mm/transparent_hugepage/enabledcat /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 unlimitedmongod hard fsize unlimitedmongod soft cpu unlimitedmongod hard cpu unlimitedmongod soft as unlimitedmongod hard as unlimitedmongod soft nofile 64000mongod hard nofile 64000mongod soft nproc 64000mongod 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參數設定
MongoDB效能最佳化