為什么要監控?
監控及時獲得應用的運行狀態信息,在問題出現時及時發現。
監控什么?
CPU、內存、磁盤I/O、應用程序(MongoDB)、進程監控(ps -aux)、錯誤日志監控
1.4.1 MongoDB集群監控方式
db.serverStatus()
查看實例運行狀態(內存使用、鎖、用戶連接等信息)
通過比對前后快照進行性能分析
"connections" # 當前連接到本機處於活動狀態的連接數 "activeClients" # 連接到當前實例處於活動狀態的客戶端數量 "locks" # 鎖相關參數 "opcounters" # 啟動之后的參數 "opcountersRepl" # 復制想關 "storageEngine" # 查看數據庫的存儲引擎 "mem" # 內存相關
狀態:
db.stats()
顯示信息說明:
# 統計數據庫信息
db.stats()
{
"db" : "test", # 系統自帶測試數據庫
"collections" : 0, # 集合數量
"views" : 0, #
"objects" : 0, # 文檔對象的個數, 所有集合的記錄數之和
"avgObjSize" : 0, # 平均每個對象的大小, 通過 dataSize / Objects 得到
"dataSize" : 0, # 當前庫所有集合的數據大小
"storageSize" : 0, # 磁盤存儲大小
"numExtents" : 0, # 所有集合的擴展數據量統計數
"indexes" : 0, # 已建立索引數量
"indexSize" : 0, # 索引大小
"fileSize" : 0, #
"fsUsedSize" : 0, #
"fsTotalSize" : 0, #總大小
"ok" : 1
}
1.4.2 mongostat
mongostat是mongdb自帶的狀態檢測工具,在命令行下使用。它會間隔固定時間獲取mongodb的當前運行狀態,並輸出。如果你發現數據庫突然變慢或者有其他問題的話,你第一手的操作就考慮采用mongostat來查看mongo的狀態。
主要功能:
實時數據庫狀態,讀寫、加鎖、索引命中、缺頁中斷、讀寫等待隊列等情況。
每秒刷新一次狀態值,並能提供良好的可讀性,通過這些參數可以觀察到MongoDB系統整體性能情況。
常用命令格式:
mongostat --host 192.168.1.100:27017 -uroot -p123456 --authenticationDatabase admin
虛擬內存使用量,單位MB (這是 在mongostat 最后一次調用的總數據)
物理內存使用量,單位MB (這是 在mongostat 最后一次調用的總數據)
1.4.3 mongotop
mongotop命令說明:
[mongod@MongoDB oplog]$ mongotop -h 127.0.0.1:27017 2018-01-08T17:32:56.623+0800 connected to: 127.0.0.1:27017 ns total read write 2018-01-08T17:32:57+08:00 admin.system.roles 0ms 0ms 0ms admin.system.users 0ms 0ms 0ms admin.system.version 0ms 0ms 0ms app.user 0ms 0ms 0ms automationcore.automation.job.status 0ms 0ms 0ms automationcore.config.automation 0ms 0ms 0ms automationcore.config.automationTemplates 0ms 0ms 0ms automationcore.config.automationTemplates_archive 0ms 0ms 0ms automationcore.config.automation_archive 0ms 0ms 0ms automationstatus.lastAgentStatus 0ms 0ms 0ms
mongotop重要指標
ns:數據庫命名空間,后者結合了數據庫名稱和集合。 total:mongod在這個命令空間上花費的總時間。 read:在這個命令空間上mongod執行讀操作花費的時間。 write:在這個命名空間上mongod進行寫操作花費的時間。
1.4.3 mongosniff
此工具可以從底層監控到底有哪些命令發送給了MongoDB 去執行,從中就可以進行分析:以root 身份執行:
$./mongosniff --source NET lo
然后其會監控位到本地以localhost 監聽默認27017 端口的MongoDB 的所有包請求。
1.4.3 db級別命令
1、db.currentOp()
db.currentOp是個好東西,顧名思義,就是當前的操作。在mongodb中可以查看當前數據庫上此刻的操作語句信息,包括insert/query/update/remove/getmore/command等多種操作。直接執行
db.currentOp()一般返回一個空的數組,我們可以指定一個參數true,這樣就返回用戶connections與系統cmmand相關的操作。下面看個列子:
db.currentOp(true) 會返回很多信息:
db.currentOp()
查看數據庫當前執行什么操作。
用於查看長時間運行進程。
通過(執行時長、操作、鎖、等待鎖時長)等條件過濾。
重點關注以下幾個字段:
字段 | 說明 |
---|---|
client | 請求是由哪個客戶端發起的。 |
opid | 操作的opid,有需要的話,可以通過db.killOp(opid) 直接終止該操作。 |
secs_running/microsecs_running | 這個值重點關注,代表請求運行的時間,如果這個值特別大,請看看請求是否合理。 |
query/ns | 這個字段能看出是對哪個集合正在執行什么操作。 |
lock* | - 還有一些跟鎖相關的參數,需要了解可以看官網文檔,本文不做詳細介紹。 - db.currentOp文檔請參見:db.currentOp 。 |
示例:
gechongrepl:PRIMARY> db.currentOp() { "inprog" : [ { "opid" : 6222, "active" : true, "secs_running" : 3, "microsecs_running" : NumberLong(3662328), "op" : "getmore", "ns" : "local.oplog.rs", "query" : { }, "client" : "192.168.91.132:45745", "desc" : "conn5", "threadId" : "0x7f1370cb4700", "connectionId" : 5, "waitingForLock" : false, "numYields" : 0, "lockStats" : { "timeLockedMicros" : { "r" : NumberLong(141), "w" : NumberLong(0) }, "timeAcquiringMicros" : { "r" : NumberLong(16), "w" : NumberLong(0) } } } ] }
opid" : 6222,#進程號
"active" : true,#是否活動狀態
"secs_running" : 3,#操作運行了多少秒
"microsecs_running" : NumberLong(3662328),
"op" : "getmore",#操作類型,包括(insert/query/update/remove/getmore/command)
"ns" : "local.oplog.rs",#命名空間
"query" : {},#如果op是查詢操作,這里將顯示查詢內容;也有說這里顯示具體的操作語句的
"client" : "192.168.91.132:45745",#連接的客戶端信息
"desc" : "conn5",#數據庫的連接信息
"threadId" : "0x7f1370cb4700",#線程ID
"connectionId" : 5,#數據庫的連接ID
"waitingForLock" : false,#是否等待獲取鎖
"numYields" : 0,
"lockStats" : {
"timeLockedMicros" : {#持有的鎖時間微秒
"r" : NumberLong(141),#整個MongoDB實例的全局讀鎖
"w" : NumberLong(0)},#整個MongoDB實例的全局寫鎖
"timeAcquiringMicros" : {#為了獲得鎖,等待的微秒時間
"r" : NumberLong(16),#整個MongoDB實例的全局讀鎖
"w" : NumberLong(0)}#整個MongoDB實例的全局寫鎖
2、db.killOp(opid)
kill當前的操作 opid為具體的操作id號,當然了,只能kill正在進行中的。opid是通過db.currentOp()查詢返回的。如果發現一個操作太長,把數據庫卡死的話,可以用這個命令殺死他:> db.killOp(608605)
示例:
{ "inprog" :
[
{
"opid" : 3434473,//操作的id "active" : <boolean>,//是否處於活動狀態 "secs_running" : 0,//操作運行了多少秒 "op" : "<operation>",//具體的操作行為,包括(insert/query/update/remove/getmore/command) "ns" : "<database>.<collection>",//操作的命名空間,如:數據庫名.集合名 "query" : {//具體的操作語句 }, "client" : "<host>:<outgoing>",//連接的客戶端信息 "desc" : "conn57683",//數據庫連接描述 "threadId" : "0x7f04a637b700",//線程id "connectionId" : 57683,//數據庫連接id "locks" : {//鎖的相關信息 "^" : "w", "^local" : "W", "^<database>" : "W" }, "waitingForLock" : false,//是否在等待並獲取鎖, "msg": "<string>" "numYields" : 0, "progress" : { "done" : <number>, "total" : <number> } "lockStats" : { "timeLockedMicros" : {//此操作獲得以下鎖后,把持的微秒時間 "R" : NumberLong(),//整個mongodb服務實例的全局讀鎖 "W" : NumberLong(),//整個mongodb服務實例的全局寫鎖 "r" : NumberLong(),//某個數據庫實例的讀鎖 "w" : NumberLong() //某個數據庫實例的寫鎖 }, "timeAcquiringMicros" : {//此操作為了獲得以下的鎖,而耗費等待的微秒時間 "R" : NumberLong(),//整個mongodb服務實例的全局讀鎖 "W" : NumberLong(),//整個mongodb服務實例的全局寫鎖 "r" : NumberLong(),//某個數據庫實例的讀鎖 "w" : NumberLong()//某個數據庫實例的寫鎖 } } }, ..... ] }
1.4.3 MongoDB優化器profile
在MySQL 中,慢查詢日志是經常作為我們優化數據庫的依據,那在MongoDB 中是否有類似的功能呢?答案是肯定的,那就是MongoDB Database Profiler。
1.開啟profiling功能
有兩種方式可以控制 Profiling 的開關和級別,第一種是直接在啟動參數里直接進行設置。啟動MongoDB 時加上–profile=級別 即可。也可以在客戶端調用db.setProfilingLevel(級別) 命令來實時配置,Profiler 信息保存在system.profile 中。我們可以通過db.getProfilingLevel()命令來獲取當前的Profile 級別,類似如下操作:
db.setProfilingLevel(2);
上面profile 的級別可以取0,1,2 三個值,他們表示的意義如下:
0 – 不開啟
1 – 記錄慢命令 (默認為>100ms)
2 – 記錄所有命令
Profile 記錄在級別1 時會記錄慢命令,那么這個慢的定義是什么?上面我們說到其默認為100ms,當然有默認就有設置,其設置方法和級別一樣有兩種,一種是通過添加 –slowms 啟動參數配置。第二種是調用db.setProfilingLevel 時加上第二個參數:
db.setProfilingLevel( level , slowms )
db.setProfilingLevel( 1 , 10 );
2.查看 Profile的設置級別
db.getProfilingLevel()
> db.setProfilingLevel(1)
{ "was" : 2, "slowms" : 100, "sampleRate" : 1, "ok" : 1 } > db.getProfilingLevel() 1 >
3.查詢 Profiling 記錄
與MySQL的慢查詢日志不同,Mongo Profile 記錄是直接存在系統db里的,記錄位置 system.profile ,所以,我們只要查詢這個Collection的記錄就可以獲取到我們的 Profile 記錄了。
慢查詢(system.profile)說明
詳細信息見《MongoDB分析工具之二:MongoDB分析器Profile》
二、性能問題排查
2.1、mongodb client端報錯,感覺像連接數配置小了
mongoDB server端定位方法:
查看總的連接數,因為mongoDB 默認的最大連接數為820.
netstat -nat | grep -i "27017" | wc -l
netstat -nt|grep 27017|wc -l
或者:
到/data/mongodb/mongos/log
查看mongoDB的日志文件:
mongos.diagnostic.data mongos.log
2.2、設置mongoDB server的最大連接數
修改mongodb最大連接數
在啟動里邊加參數 --maxConns=20000或者在 /etc/mongod.cnf (我自己見的配置文件添加 maxConns=20000)
重啟mongodb
如果當前mongodb最大連接數沒有變成20000,排查你service mongodb啟動的腳本,如果腳本有 ulimit -n 12000,修改成30000,
如果修改成20000,貌似最大連接數也不到20000,這里具體原因沒查,我的腳本是 /etc/init.d/mongod
還有一個地方可能影響到mongodb最大連接數,Linux系統默認一個進程最大打開文件數目是1024,修改rc.local
vi /etc/rc.local
很好我這里的一個進程最大打開文件數目遠遠大於20000
2.3、報錯:because there was a socket exception raised by this connection.
回答1:
After few tries I've found out that it was a problem with the Azure's Load Balancer.
After 60s of inactivity it will disconnect any pending TCP connection.
After further digging I've found this post of the MongoDB diagnostics FAQ, and I've set the tcp keepalive to 120s:
sudo sysctl -w net.ipv4.tcp_keepalive_time=<value>
and I've also set the socketKeepAlive of the MongoClient to true:
MongoClientOptions.Builder options = MongoClientOptions.builder(); options.socketKeepAlive(true); mongoClient = new MongoClient(mongoAddress, options.build());
After these fixes the issue seems gone!
回答2:
If you experience socket errors between clients and servers or between members of a sharded cluster or replica set that do not have other reasonable causes, check the TCP keepalive value (for example, the tcp_keepalive_time value on Linux systems). A common keepalive period is 7200 seconds (2 hours); however, different distributions and macOS may have different settings.
For MongoDB, you will have better results with shorter keepalive periods, on the order of 120 seconds (two minutes).
where u have installed mongodb u have to simply run this command on Linux
sudo sysctl -w net.ipv4.tcp_keepalive_time=120
mtop – 針對 MongoDB 的 top 命令
這是一個基於MongoDB Python 客戶端 pymongo 的小程序,他使你可以像用操作系統的top命令一樣,實時觀察你的MongoDB 的狀態。
1.安裝 pymongo 及 mtop
下載安裝pymongo:http://api.mongodb.org/python/1.9%2B/installation.html
如果有easy_install 那安裝起來就比較easy了~只需要:
$ easy_install pymongo
下載安裝mtop:https://github.com/beaufour/mtop
2.運行mtop
./mtop.py -s localhost:27017 -d 2000
3.參數說明
- -s:表示MongoDB 所在的機器及端口
- -d:刷新的間隔,以毫秒計所以上面表示每兩秒一次。