MongoDB性能の最適化と監視

10733 ワード

MongoDBは、分散ファイルに基づいて格納されるデータベースです.C++言語で作成されます.WEBアプリケーションに拡張性の高い高性能データストレージソリューションを提供することを目的としています.
MongoDBはリレーショナル・データベースと非リレーショナル・データベースの間に介在する製品で、非リレーショナル・データベースの中で最も機能が豊富で、最もリレーショナル・データベースに似ています.
一、索引
MongoDBは多様性のインデックスサポートを提供する、インデックス情報はsystemに保存される.indexesで、デフォルトは常に_idは、基本的にMySQLなどのリレーショナル・データベースと同じインデックスを使用するインデックスを作成します.実際には、インデックスはデータストレージシステムを凌駕する別の階層システムであるため、様々な構造の異なるストレージが同じまたは類似のインデックス実装およびインタフェースの使用を行うことは珍しくない.
1.ベースインデックス
フィールドageにインデックスを作成します.1(昇順);-1(降順):

db.users.ensureIndex({age:1}) 

_idは、テーブルの作成時に自動的に作成されるインデックスであり、このインデックスは削除できません.システムに大量のデータがある場合、インデックスの作成は非常に時間のかかる作業であり、バックグラウンドで「backgroud:true」を指定するだけで実行できます.

db.t3.ensureIndex({age:1} , {backgroud:true}) 

2.文書索引
インデックスは、任意のタイプのフィールド、さらにはドキュメントを使用できます.

db.factories.insert( { name: "wwl", addr: { city: "Beijing", state: "BJ" } } );
// addr       
db.factories.ensureIndex( { addr : 1 } );
//                   
db.factories.find( { addr: { city: "Beijing", state: "BJ" } } );
//               ,                  
db.factories.find( { addr: { state: "BJ" , city: "Beijing"} } ); 

3.結合インデックス
他のデータベース製品と同様に、MongoDBにも組み合わせインデックスがあります.次にaddr....stateにコンビネーションインデックスを作成します.コンビネーションインデックスを作成すると、フィールドの後ろの1が昇順、-1が降順、1が主にソート時または指定範囲内のクエリー時に関係します.

db.factories.ensureIndex( { "addr.city" : 1, "addr.state" : 1 } );
//              
db.factories.find( { "addr.city" : "Beijing", "addr.state" : "BJ" } );
db.factories.find( { "addr.city" : "Beijing" } );
db.factories.find().sort( { "addr.city" : 1, "addr.state" : 1 } );
db.factories.find().sort( { "addr.city" : 1 } ) 

4.一意のインデックス
ユニークなインデックスを作成するには、ensureIndexコマンドで「unique:true」を指定します.例えば、表t 4に2つのレコードを挿入する.

db.t4.ensureIndex({firstname: 1, lastname: 1}, {unique: true}); 

5.索引の強制使用
hintコマンドは、インデックスを強制的に使用できます.

db.t5.find({age:{$lt:30}}).hint({name:1, age:1}).explain() 

6.索引の削除

//  t3        
db.t3.dropIndexes()
//  t4    firstname   
db.t4.dropIndex({firstname: 1}) 

二、explain実行計画
MongoDBはexplainコマンドを提供し、システムがクエリーリクエストをどのように処理するかを知ることができます.explainコマンドを使用すると、インデックスを迅速に取得するためにシステムがどのように使用されているかをよく観察でき、インデックスを的確に最適化できます.

db.t5.ensureIndex({name:1})
db.t5.ensureIndex({age:1})
db.t5.find({age:{$gt:45}}, {name:1}).explain()
{
"cursor" : "BtreeCursor age_1",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"age" : [
[45,1.7976931348623157e+308]
]
}
} 


フィールドの説明:
•cursor:戻りカーソルタイプ(BasicCursorまたはBtreeCursor)•nscanned:スキャンされたドキュメント数•n:戻りドキュメント数•millis:時間(ミリ秒)•indexBounds:使用するインデックス
三、オプティマイザprofile
MySQLでは、遅いクエリー・ログがデータベースの最適化の根拠としてよく使われていますが、MongoDBでは似たような機能がありますか?答えは肯定的です.それはMongoDB Database Profilerです.
1.profiling機能を起動する
Profilingのスイッチとレベルを制御するには2つの方法があります.1つ目は、起動パラメータに直接設定することです.MongoDB起動時に、Cprofile=レベルを付ければいい.クライアントでdbを呼び出すこともできる.setProfilingLevel(レベル)コマンドはリアルタイムで構成する、Profiler情報はsystemに保存する.profileで.dbを通じてgetProfilingLevel()コマンドは、次のように現在のProfileレベルを取得します.

db.setProfilingLevel(2); 

上記のprofileのレベルは0,1,2の3つの値を取ることができ、彼らが表す意味は以下の通りです.
1.0�Cは2.1�Cレコードスローコマンドをオンにしない(デフォルトは>100 ms)3.2�Cすべてのコマンドを記録する
Profileがレベル1に記録されるとスローコマンドが記録されますが、このスロー定義は何ですか?デフォルトは100 msですが、デフォルトはもちろん設定されています.設定方法はレベルと同じ2種類あります.1つはCslowmsを追加してパラメータ構成を開始することです.2つ目はdbを呼び出す.setProfilingLevelに2番目のパラメータを追加します.

db.setProfilingLevel( level , slowms )
db.setProfilingLevel( 1 , 10 ); 

2.プロファイルレコードの照会
MySQLのスロークエリーログとは異なり、MongoDB Profileレコードはシステムdbに直接存在し、記録位置system.Profileなので、このCollectionのレコードを検索するだけでProfileのレコードを取得できます.実行時間が限度(5 ms)より長いProfileレコードをリストします.

db.system.profile.find( { millis : { $gt : 5 } } ) 

MongoDB Shellは、最近の5つの実行時間が1 msを超えるProfileレコードをリストできる比較的簡潔なコマンドshow profileも提供しています.
四、常用性能最適化方案
1.索引の作成
2.戻り結果数の制限
3.使用したフィールドのみを問合せ
4.capped collectionを採用
5.Server Side Code Executionの採用
6.Hintを使用し、インデックスを強制的に使用
7.プロファイルの採用
五、性能監視ツール
1. mongosniff
このツールは、どのコマンドがMongoDBに送信されたのかを最下位から監視し、rootとして実行することができます.

$./mongosniff --source NET lo 

次に、デフォルトの27017ポートのMongoDBのすべてのパケット要求をlocalhostでローカルに監視します.
2.Mongostat
このツールでは、実行中のMongoDBインスタンスのセットの統計フィールドの説明をすばやく表示できます.•insert:挿入/秒•query:クエリー/秒•update:更新/秒•delete:削除/秒•locked:ロック/qr|qw:クライアントクエリキュー長(読み取り/書き込み)•ar|aw:アクティブクライアント・エンド・ボリューム(読み取り/書き込み)•conn:接続数•time:現在時刻
1秒ごとにステータス値をリフレッシュし、良好な可読性を提供し、これらのパラメータによって全体的なパフォーマンスを観察することができます.
3. db.serverStatus
このコマンドは、インスタンスの実行状態を表示する最も一般的で最も基礎的なコマンドの1つです.
4.db.stats
mongodbのモニタリングをご紹介します
mongodbはprofileでデータを監視し、最適化することができます.
現在profile機能用コマンドがオンになっているかどうかを確認します
db.getProfilingLevel()はlevelレベルを返し、値は0|1|2で、それぞれ意味を表します:0は閉じることを表し、1は遅いコマンドを記録することを表し、2はすべてprofile機能を開始することを表します
db.setProfilingLevel(level); #レベルレベル、値が上レベルと1の場合、スローコマンドのデフォルト値は100 ms、dbに変更されます.setProfilingLevel(level,slowms)例えばdb.setProfilingLevel(1,50)は、dbを通過する50ミリ秒に変更する.system.profile.find()現在のモニタリングログを表示します.次のようになります.

> db.system.profile.find({millis:{$gt:500}}) 
{ "ts" : ISODate("2011-07-23T02:50:13.941Z"), "info" : "query order.order reslen:11022 nscanned:672230 
query: { status: 1.0 } nreturned:101 bytes:11006 640ms", "millis" : 640 } { "ts" : ISODate("2011-07-23T02:51:00.096Z"), "info" : "query order.order reslen:11146 nscanned:672302
query: { status: 1.0, user.uid: { $gt: 1663199.0 } } nreturned:101 bytes:11130 647ms", "millis" : 647 }

ここで値の意味は
ts:コマンド実行時間info:コマンドの内容query:クエリーorderを表す.order:クエリーを表すライブラリとコレクションreslen:返される結果セットサイズ、byte数nscanned:スキャンレコード数nquery:クエリー条件nreturned:レコード数と使用時間millisを返す
発見時間が長い場合は最適化が必要です.
たとえばnscannedの数が大きいか、レコードの総数に近い場合は、インデックスクエリが使用されない可能性があります.reslenは大きく、不要なフィールドを返す可能性があります.nreturnedは大きいので、クエリー時に制限がない可能性があります.
mongoはdbを通ることができます.serverStatus()mongodの運転状態の表示


> db.serverStatus() 
{ 
"host" : "baobao-laptop",#    
"version" : "1.8.2",#    
"process" : "mongod",#    
"uptime" : 15549,#     
"uptimeEstimate" : 15351, 
"localTime" : ISODate("2011-07-23T06:07:31.220Z"),     
"globalLock" : { 
"totalTime" : 15548525410,#     (ns) 
"lockTime" : 89206633, #     (ns) 
"ratio" : 0.005737305027178137,#    
"currentQueue" : { 
"total" : 0,#          
"readers" : 0,#    
"writers" : 0#    
}, 
"activeClients" : { 
"total" : 0,#            
"readers" : 0,#     
"writers" : 0#     
} 
}, 
"mem" : {#     
"bits" : 32,#32    
"resident" : 337,#        
"virtual" : 599,#       
"supported" : true,#         
"mapped" : 512 
}, 
"connections" : { 
"current" : 2,#      
"available" : 817#      
}, 
"extra_info" : { 
"note" : "fields vary by platform", 
"heap_usage_bytes" : 159008,#        
"page_faults" : 907 #     
}, 
"indexCounters" : { 
"btree" : { 
"accesses" : 59963, #       
"hits" : 59963, #      
"misses" : 0,#      
"resets" : 0,#    
"missRatio" : 0#     
} 
}, 
"backgroundFlushing" : { 
"flushes" : 259, #     
"total_ms" : 3395, #        
"average_ms" : 13.108108108108109, #     
"last_ms" : 1, #       
"last_finished" : ISODate("2011-07-23T06:07:22.725Z")#       
}, 
"cursors" : { 
"totalOpen" : 0,#      
"clientCursors_size" : 0,#        
"timedOut" : 16#     
}, 
"network" : { 
"bytesIn" : 285676177,#    (byte) 
"bytesOut" : 286564,#    (byte) 
"numRequests" : 2012348#    
}, 
"opcounters" : { 
"insert" : 2010000, #      
"query" : 51,#      
"update" : 5,#      
"delete" : 0,#      
"getmore" : 0,#         
"command" : 148#        
}, 
"asserts" : {#        
"regular" : 0, 
"warning" : 0, 
"msg" : 0, 
"user" : 2131, 
"rollovers" : 0 
}, 
"writeBacksQueued" : false, 
"ok" : 1 
} 

db.stats()           

> db.stats() 
{ 
"db" : "order",#   
"collections" : 4,#    
"objects" : 2011622,#    
"avgObjSize" : 111.92214441878245,#         
"dataSize" : 225145048,#       
"storageSize" : 307323392,#         
"numExtents" : 21,#    
"indexes" : 1,#    
"indexSize" : 74187744,#     
"fileSize" : 1056702464,#     
"ok" : 1 
} 

コレクションレコードの表示

> db.order.stats() 
{ 
"ns" : "order.order",#     
"count" : 2010000,#    
"size" : 225039600,#   
"avgObjSize" : 111.96, 
"storageSize" : 307186944, 
"numExtents" : 18, 
"nindexes" : 1, 
"lastExtentSize" : 56089856, 
"paddingFactor" : 1, 
"flags" : 1, 
"totalIndexSize" : 74187744, 
"indexSizes" : { 
"_id_" : 74187744#   _id_      
}, 
"ok" : 1 
}

mongostatコマンドは、1秒あたりのリアルタイム実行回数を示す実行中のリアルタイム統計を表示します.
mongodbはhttpの監視ページにもアクセスできるチャンスを提供していますhttp://ip:28017見てみると、このページは基本的に上記のコマンドを統合しているので、ここでは詳しく説明しません.