Mongodb 調校過程記錄
Mongodb
Mongodb簡介
Mongodb的主機環境設定
以下主機環境都是以 Ubuntu 14.04
Mongodb預設建立起來的最大連線數只有819
所以如果只是單純建立起來之後沒去改設定的話
很容易造成
"connection refused because too many open connections mongodb"
這個錯誤
所以在啟動的時候可以多加 --maxConns這個參數並設定到適當數值
ex:
bin/mongod --auth --maxConns=640000 --dbpath ./db
註:
但是 --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
註:
另外在
/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造成的問題
註:
其實訣竅就是要建立 index
但是index也不是建立的越多越好
建立越多的index, 相對的, 寫入速度會越慢
所以要針對自己的 query 去建立 index
而且盡量所要查詢的欄位, 與要撈出的欄位, 都在index內!!
最好是單一個 operation都壓在 100ms 以下
當然, 越低越好!
其實可以透過 db.setProfilingLevel() 來紀錄哪些 operation是慢的
假設我們定義超過100ms就算慢的操作
可以設定 db.setProfillingLevel(1,100)
註:
假設我只要找查詢動作超過 100ms 的語法
db.system.profile.findOne({op:'query',millis:{$gt: 100}})
然後便可以知道需要將哪些查詢語句做進一步的最佳化
那要如何查詢自己使用的 query 有沒有使用到 index呢?
使用 .explain()就可以看得出來
使用 .explain()會回傳一個物件
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
留言
張貼留言