1. 程式人生 > >MongoDB效能優化

MongoDB效能優化

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引數設定