Mongodb 調校過程記錄

Mongodb




Mongodb簡介


  • NoSQL
  • 以json形式儲存資料
  • 效能高
    • 支援資料內部再嵌入資料
    • 索引可以讓搜尋更快速
      • 內嵌資料與陣列都可以成為索引
  • 豐富的查詢語言
    • 資料聚合
    • 文字搜索
    • 地理位置查詢


Mongodb的主機環境設定

以下主機環境都是以 Ubuntu 14.04

Mongodb預設建立起來的最大連線數只有819
所以如果只是單純建立起來之後沒去改設定的話
很容易造成
"connection refused because too many open connections mongodb"
這個錯誤
所以在啟動的時候可以多加 --maxConns這個參數並設定到適當數值

ex:
bin/mongod --auth --maxConns=640000 --dbpath ./db





註:

  • --dbpath 是指定資料庫檔案存放的地方
  • --auth 啟用驗證機制
  • --maxConns 最大連接數


但是 --maxConns 卻是跟主機的 ulimit -n 的值有關係

ulimit -n 預設最高好像是到1024或4096
若要再調高, 則需要做下列步驟

sudo vi /etc/security/limits.conf
在最底下新增
* soft nofile 64000
* hard nofile 64000
root soft nofile 64000
root hard nofile 64000













註:

  • * 無法套用到root
  • * 也可以改成自己常用的帳號, ex: ubuntu soft nofile 64000之類的


另外在
/etc/pam.d/common-session
/etc/pam.d/common-session-noninteractive
內的最底下都要加上
session required        pam_limits.so








建議在 /etc/profile 最底下新增 ulimit -HSn 64000





之後建議重新啟動, 這樣ulimit -n 就都會是64000了!

echo "262144" > /proc/sys/net/ipv4/tcp_max_syn_backlog
echo "2000000" > /proc/sys/net/ipv4/tcp_max_tw_buckets
echo "262144" > /proc/sys/net/core/netdev_max_backlog
vim /etc/sysctl.conf
net.core.somaxconn=32768
sysctl -p

Mongodb 效能問題

3.x版預設引擎是 WiredTiger
如果不是WiredTiger最好換到此搜尋引擎
wiredTiger可以避免collection-lock造成的問題
註:

  • 就是有人在寫相同的collection,其他人都不能讀;wiredTiger是document lock
  • 一筆一筆的資料就是document
  • Mongodb的collection 就好比是 MySQL的table


其實訣竅就是要建立 index
但是index也不是建立的越多越好
建立越多的index, 相對的, 寫入速度會越慢
所以要針對自己的 query 去建立 index

而且盡量所要查詢的欄位, 與要撈出的欄位, 都在index內!!
最好是單一個 operation都壓在 100ms 以下
當然, 越低越好!

其實可以透過 db.setProfilingLevel() 來紀錄哪些 operation是慢的
假設我們定義超過100ms就算慢的操作
可以設定 db.setProfillingLevel(1,100)
註:

  • 1代表只記錄效能比較差的操作
  • 100 代表 100ms

假設我只要找查詢動作超過 100ms 的語法

db.system.profile.findOne({op:'query',millis:{$gt: 100}})
然後便可以知道需要將哪些查詢語句做進一步的最佳化

那要如何查詢自己使用的 query 有沒有使用到 index呢?
使用 .explain()就可以看得出來

使用 .explain()會回傳一個物件






  • queryPlanner
    • queryPlanner模式下並不會去真正進行query語句查詢,而是針對query語句進行執行計劃分析並選出winning plan
  • explain.queryPlanner.namespace
    • 所查詢的 collection name
  • explain.queryPlanner.winningPlan
    • 查詢優化器針對該query所返回的最優執行計劃的詳細內容
  • explain.queryPlanner.winningPlan.stage
    • 最優執行計劃的stage, 這裡返回是FETCH, 可以理解為通過返回的index位置去檢索具體的文檔
  • explain.queryPlanner.winningPlan.inputStage
    • explain.queryPlanner.winningPlan.stage的child stage, 此處是IXSCAN, 表示進行的是index scanning
    • 如果是 COLLSCAN則是直接去從資料庫裡取, 而不是 index
所要做的就是不要出現 COLLSCAN, 最好都是 IXSCAN!

建立 index
db.collection.createIndex()

留言

這個網誌中的熱門文章

[MySQL] schema 與資料類型優化

[翻譯] 介紹現代網路負載平衡與代理伺服器