2016-12-12 27 views
2

我是MongoDB的新用戶,我希望能夠指出正確的方向。隨着這個問題的發展,我會提供任何進一步需要的信息。MongoDB高CPU使用率/讀取時間長

我正在使用Perl程序通過MongoDB cpan模塊上載和註釋/修改文件到/在MongoDB數據庫中。我正在使用索引(我相信)這個程序,但是我遇到的問題是從MongoDB中讀取的時間越來越長。基於mongotop,讀取需要大約500毫秒,寫入只需要10-15毫秒。允許程序運行相當長的時間之後,讀取時間會顯着增加,運行數小時後需要超過3000毫秒以上。

在使用top運行時監控程序,Perl的CPU使用率約爲10-20%,MongoDB的CPU使用率從70-90%開始。運行時,幾分鐘內Perl下降5%以下,mongoDB爲90-95%。在運行了更長時間(12小時以上)之後,MongoDB的CPU使用率約爲98%,而Perl約爲0.3%,但每隔5-10秒鐘就會彈出一次。

基於這種趨勢,索引問題似乎很有可能,但我不知道如何檢查這一點,而我所知道的是,至少已經制定了適當的索引,但未必使用。

其他信息:

$ ulimit -a  
core file size   (blocks, -c) 0  
data seg size   (kbytes, -d) unlimited 
scheduling priority    (-e) 0  
file size    (blocks, -f) unlimited  
pending signals     (-i) 19209  
max locked memory  (kbytes, -l) 64  
max memory size   (kbytes, -m) unlimited  
open files      (-n) 1024 
pipe size   (512 bytes, -p) 8  
POSIX message queues  (bytes, -q) 819200  
real-time priority    (-r) 0  
stack size    (kbytes, -s) 8192  
cpu time    (seconds, -t) unlimited  
max user processes    (-u) 19209 
virtual memory   (kbytes, -v) unlimited  
file locks      (-x) unlimited 
  • 在程序運行時,我看到indexSize和(在蒙戈外殼通過db.stats())數據尺寸的變化,這讓我覺得他們至少在某種程度上被使用
  • 這是否會受到我電腦的威力?我覺得索引應該使很多這個過程對於計算機來說是非常易於管理的
+0

對每個單位時間內程序的處理數據量以及處理數據的粗略估計是很好的 - 例如格式化和加密處理可以產生巨大的性能差異。此外,[這](http://stackoverflow.com/questions/34951683/mongodb-constantly-high-cpu-usage)*可能*幫助。 –

+0

我實際上發現問題的根源: 我正在運行的程序是模塊化的,除了1個索引外,在我使用的程序的組件內創建。一旦發現索引問題,我就可以解決問題,並且讀/寫時間總計保持約50ms,並且沒有像以前那樣線性增加。 – cookersjs

+0

很高興你明白了! –

回答

1

這聽起來很像它可以做集合掃描而不是使用索引。即隨着你的收藏增長,閱讀速度會變慢。

如果您使用的是find方法,則可以在得到的遊標上運行explain以獲取有關如何執行查詢的信息。

這裏有一個簡單的例子:

use MongoDB; 
use JSON::MaybeXS; 

my $coll = MongoDB->connect->ns("test.foo"); 
$coll->drop(); 
$coll->insert_one({x => $_}) for 1 .. 1000; 

my $cursor = $coll->find({x => 42}); 
my $diag = $cursor->explain; 

my $json = JSON::MaybeXS->new(
    allow_blessed => 1, convert_blessed => 1, pretty => 1, canonical => 1 
); 

print $json->encode($diag->{queryPlanner}{winningPlan}); 

看着眼前你可以看到輸出的「winningPlan」部分「COLLSCAN」:

{ 
    "direction" : "forward", 
    "filter" : { 
     "x" : { 
     "$eq" : 42 
     } 
    }, 
    "stage" : "COLLSCAN" 
} 

現在,我會再次這樣做,但首先在插入前用'$coll->indexes->create_one([x => 1])'創建索引。您可以在輸出中看到查詢計劃現在使用索引(IXSCAN)。

{ 
    "inputStage" : { 
     "direction" : "forward", 
     "indexBounds" : { 
     "x" : [ 
      "[42, 42]" 
     ] 
     }, 
     "indexName" : "x_1", 
     "indexVersion" : 2, 
     "isMultiKey" : false, 
     "isPartial" : false, 
     "isSparse" : false, 
     "isUnique" : false, 
     "keyPattern" : { 
     "x" : 1 
     }, 
     "multiKeyPaths" : { 
     "x" : [] 
     }, 
     "stage" : "IXSCAN" 
    }, 
    "stage" : "FETCH" 
} 

您可以從完整的'explain'輸出中找到更多信息。您可以觀看來自MongoDB World 2016的精彩視頻,瞭解更多信息:Deciphering Explain Output