データベースのパフォーマンスは組織のパフォーマンスに影響を与えるため、迅速な修正を探す傾向があります。 MongoDBのパフォーマンスを向上させる方法はたくさんあります。このブログでは、データベースのワークロードと、データベースに害を及ぼす可能性のある事項について理解を深めるのに役立ちます。限られたリソースの使用方法に関する知識は、本番データベースを管理するすべての人にとって不可欠です。
データベースのパフォーマンスを制限する要因を特定する方法を示します。データベースが期待どおりに機能することを確認するために、無料のMongoDBクラウド監視ツールから始めます。次に、ログファイルの管理方法とクエリの調査方法を確認します。ハードウェアリソースを最適に使用できるようにするために、カーネルの最適化やその他の重要なOS設定について見ていきます。最後に、MongoDBレプリケーションとパフォーマンスの調査方法について説明します。
パフォーマンスの無料モニタリング
MongoDBは、スタンドアロンインスタンスとレプリカセット用の無料のパフォーマンス監視ツールをクラウドに導入しました。有効にすると、監視対象データがベンダーのクラウドサービスに定期的にアップロードされます。追加のエージェントは必要ありません。機能は新しいMongoDB4.0以降に組み込まれています。このプロセスは、セットアップと管理が非常に簡単です。 1つのコマンドをアクティブ化すると、最近のパフォーマンス統計にアクセスするための一意のWebアドレスが取得されます。過去24時間以内にアップロードされた監視対象データにのみアクセスできます。
この機能を有効にする方法は次のとおりです。以下を使用して、実行時に無料の監視を有効/無効にできます。
-- Enable Free Monitoring
db.enableFreeMonitoring()
-- Disable Free Monitoring
db.disableFreeMonitoring()
構成ファイル設定cloud.monitoring.free.stateまたはコマンドラインオプション--enableFreeMonitoring
を使用して、mongodの起動中に無料の監視を有効または無効にすることもできます。db.enableFreeMonitoring()
アクティベーション後、実際のステータスを示すメッセージが表示されます。
{
"state" : "enabled",
"message" : "To see your monitoring data, navigate to the unique URL below. Anyone you share the URL with will also be able to view this page. You can disable monitoring at any time by running db.disableFreeMonitoring().",
"url" : "https://cloud.mongodb.com/freemonitoring/cluster/XEARVO6RB2OTXEAHKHLKJ5V6KV3FAM6B",
"userReminder" : "",
"ok" : 1
}
ステータス出力からブラウザにURLをコピーして貼り付けるだけで、パフォーマンス指標の確認を開始できます。
MongoDB Freeモニタリングは、次のメトリックに関する情報を提供します。
- 操作の実行時間(読み取り、書き込み、コマンド)
- ディスク使用率(すべてのドライブの最大UTIL%、すべてのドライブの平均UTIL%)
- メモリ(常駐、仮想、マップ済み)
- ネットワーク-入力/出力(BYTES IN、BYTES OUT)
- ネットワーク-リクエスト数(NUMリクエスト)
- カウンター(INSERT、QUERY、UPDATE、DELETE、GETMORE、COMMAND)
- カウンター-レプリケーション(INSERT、QUERY、UPDATE、DELETE、GETMORE、COMMAND)
- クエリターゲティング(SCANNED / RETURNED、SCANNED OBJECTS / RETURNED)
- キュー(リーダー、ライター、合計)
- システムCPU使用率(USER、NICE、KERNEL、IOWAIT、IRQ、SOFT IRQ、STEAL、GUEST)
無料の監視サービスの状態を表示するには、次の方法を使用します。
db.getFreeMonitoringStatus()
serverStatusおよびヘルパーdb.serverStatus()には、無料の監視フィールドに無料の監視統計も含まれています。
アクセス制御を使用して実行する場合、無料の監視を有効にしてステータスを取得するには、ユーザーは次の権限を持っている必要があります。
{ resource: { cluster : true }, actions: [ "setFreeMonitoring", "checkFreeMonitoringStatus" ] }
このツールは、コマンドラインから出力されたMongoDBサーバーのステータスを読み取るのが難しい場合に適しています。
db.serverStatus()
無料モニタリングは良いスタートですが、オプションが非常に限られています。より高度なツールが必要な場合は、MongoDBOpsManagerまたはClusterControlを確認することをお勧めします。
ログデータベース操作
MongoDBドライバーとクライアントアプリケーションは、サーバーログファイルに情報を送信できます。このような情報は、イベントの種類によって異なります。現在の設定を確認するには、管理者としてログインして実行します。
db.getLogComponents()
ログメッセージには多くのコンポーネントが含まれます。これは、メッセージの機能的な分類を提供するためです。コンポーネントごとに、異なるログの詳細度を設定できます。現在のコンポーネントのリストは次のとおりです。
ACCESS, COMMAND, CONTROL, FTD, GEO, INDEX, NETWORK, QUERY, REPL_HB, REPL, ROLLBACK, REPL, SHARDING, STORAGE, RECOVERY, JOURNAL, STORAGE, WRITE.
各コンポーネントの詳細については、ドキュメントを確認してください。
クエリのキャプチャ-データベースプロファイラー
MongoDB Database Profilerは、mongodインスタンスに対して実行される操作に関する情報を収集します。デフォルトでは、プロファイラーはデータを収集しません。すべての操作(値2)を収集するか、 slowmsの値よりも時間がかかる操作を収集するかを選択できます。 。後者は、mongodb構成ファイルを介して制御できるインスタンスパラメーターです。現在のレベルを確認するには:
db.getProfilingLevel()
すべてのクエリセットをキャプチャするには:
db.setProfilingLevel(2)
構成ファイルでは、次のように設定できます。
profile = <0/1/2>
slowms = <value>
この設定は単一のインスタンスに適用され、レプリカセットまたは共有クラスター全体に伝播されないため、すべてのアクティビティをキャプチャする場合は、すべてのノードに対してこのコマンドを繰り返す必要があります。データベースプロファイリングは、データベースのパフォーマンスに影響を与える可能性があります。このオプションは、慎重に検討した後でのみ有効にしてください。
次に、最新の10個を一覧表示します:
db.system.profile.find().limit(10).sort(
{ ts : -1 }
).pretty()
すべてを一覧表示するには:
db.system.profile.find( { op:
{ $ne : 'command' }
} ).pretty()
そして、特定のコレクションをリストするには:
db.system.profile.find(
{ ns : 'mydb.test' }
).pretty()
MongoDBロギング
MongoDBログの場所は、構成のログパス設定で定義され、通常は/var/log/mongodb/mongod.logです。 MongoDB構成ファイルは/etc/mongod.confにあります。
サンプルデータは次のとおりです:
2018-07-01T23:09:27.101+0000 I ASIO [NetworkInterfaceASIO-Replication-0] Connecting to node1:27017
2018-07-01T23:09:27.102+0000 I ASIO [NetworkInterfaceASIO-Replication-0] Failed to connect to node1:27017 - HostUnreachable: Connection refused
2018-07-01T23:09:27.102+0000 I ASIO [NetworkInterfaceASIO-Replication-0] Dropping all pooled connections to node1:27017 due to failed operation on a connection
2018-07-01T23:09:27.102+0000 I REPL_HB [replexec-2] Error in heartbeat (requestId: 21589) to node1:27017, response status: HostUnreachable: Connection refused
2018-07-01T23:09:27.102+0000 I ASIO [NetworkInterfaceASIO-Replication-0] Connecting to node1:27017
次のように設定することで、コンポーネントのログの詳細度を変更できます(クエリ例):
db.setLogLevel(2, "query")
ログファイルは重要である可能性があるため、プロファイリングの前にログファイルをクリアすることをお勧めします。 MongoDBコマンドラインコンソールから、次のように入力します。
db.runCommand({ logRotate : 1 });
オペレーティングシステムのパラメータを確認する
メモリ制限
ログインに関連する制限を確認するには、コマンドulimit-aを使用します。次のしきい値と設定は、mongodとmongosのデプロイにとって特に重要です。
-f (file size): unlimited
-t (cpu time): unlimited
-v (virtual memory): unlimited
-n (open files): 64000
-m (memory size): unlimited [1]
-u (processes/threads): 32000
新しいバージョンのmongod起動スクリプト(/etc/init.d/mongod)には、開始オプションに組み込まれたデフォルト設定があります:
start()
{
# Make sure the default pidfile directory exists
if [ ! -d $PIDDIR ]; then
install -d -m 0755 -o $MONGO_USER -g $MONGO_GROUP $PIDDIR
fi
# Make sure the pidfile does not exist
if [ -f "$PIDFILEPATH" ]; then
echo "Error starting mongod. $PIDFILEPATH exists."
RETVAL=1
return
fi
# Recommended ulimit values for mongod or mongos
# See http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings
#
ulimit -f unlimited
ulimit -t unlimited
ulimit -v unlimited
ulimit -n 64000
ulimit -m unlimited
ulimit -u 64000
ulimit -l unlimited
echo -n $"Starting mongod: "
daemon --user "$MONGO_USER" --check $mongod "$NUMACTL $mongod $OPTIONS >/dev/null 2>&1"
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/mongod
}
仮想メモリマネージャとも呼ばれるメモリ管理サブシステムの役割は、カーネル全体とユーザープログラムの物理メモリ(RAM)の割り当てを管理することです。これは、vm。*パラメーターによって制御されます。 MongoDBのパフォーマンスを調整するために最初に考慮すべき2つがあります-vm.dirty_ratio およびvm.dirty_background_ratio 。
vm.dirty_ratio すべてがディスクにコミットされる前にダーティページで満たされる可能性のあるシステムメモリの絶対最大量です。システムがこの時点に達すると、ダーティページがディスクに書き込まれるまで、すべての新しいI/Oブロックが実行されます。これは、多くの場合、長いI/O一時停止の原因になります。デフォルトは30で、通常は高すぎます。 vm.dirty_background_ratio 「ダーティ」ページ(ディスクに書き込む必要のあるメモリページ)で埋めることができるシステムメモリの割合です。良いスタートは、10から行ってパフォーマンスを測定することです。低メモリ環境の場合、20が適切な開始です。大容量データベースサーバーでのダーティレシオの推奨設定は、vm.dirty_ratio=15およびvm.dirty_background_ratio=5以下です。
ダーティレシオの実行を確認するには:
sysctl -a | grep dirty
これを設定するには、「/ etc/sysctl.conf」に次の行を追加します。
Swappiness
MongoDBが実行されている唯一のサービスであるサーバーでは、vm.swapiness =1に設定することをお勧めします。デフォルト設定は60に設定されており、データベースシステムには適していません。
vi /etc/sysctl.conf
vm.swappiness = 1
透明な巨大なページ
RedHatでMongoDBを実行している場合は、Transparent HugePagesが無効になっていることを確認してください。
これはcommnadで確認できます:
cat /proc/sys/vm/nr_hugepages
0
0は、透明な巨大ページが無効になっていることを意味します。
ファイルシステムオプション
ext4 rw,seclabel,noatime,data=ordered 0 0
NUMA(Non-Uniform Memory Access)
MongoDBはNUMAをサポートしていません。BIOSで無効にしてください。
ネットワークスタック
net.core.somaxconn = 4096
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_time = 120
net.ipv4.tcp_max_syn_backlog = 4096
NTPデーモン
NTPタイムサーバーデーモンをインストールするには、次のシステムコマンドのいずれかを使用します。
#Red Hat
sudo yum install ntp
#Debian
sudo apt-get install ntp
MongoDBのOSパフォーマンスの詳細については、別のブログをご覧ください。
計画を説明する
他の一般的なデータベースシステムと同様に、MongoDBは、データベース操作がどのように実行されたかを明らかにする説明機能を提供します。 Explainの結果は、クエリプランをステージのツリーとして表示します。各ステージは、そのイベント(つまり、ドキュメントまたはインデックスキー)を親ノードに渡します。リーフノードはコレクションまたはインデックスにアクセスします。explain('executionStats')をクエリに追加できます。
db.inventory.find( {
status: "A",
$or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
} ).explain('executionStats');
or append it to the collection:
db.inventory.explain('executionStats').find( {
status: "A",
$or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
} );
上記のコマンド実行の出力で値に注意する必要があるキー:
- totalKeysExamined:クエリを返すためにスキャンされたインデックスエントリの総数。
- totalDocsExamined:結果を見つけるためにスキャンされたドキュメントの総数。
- executeTimeMillis:クエリプランの選択とクエリの実行に必要な合計時間(ミリ秒)。
レプリケーションラグパフォーマンスの測定
レプリケーションラグは、プライマリでの操作と、oplogからセカンダリへのその操作の適用との間の遅延です。つまり、セカンダリがプライマリノードの背後にある距離を定義します。これは、最良のシナリオでは、可能な限り0に近づける必要があります。
レプリケーションプロセスは、さまざまな理由で影響を受ける可能性があります。主な問題の1つは、セカンダリメンバーのサーバー容量が不足していることである可能性があります。プライマリメンバーでの大規模な書き込み操作により、セカンダリメンバーがoplogを再生できなくなったり、プライマリメンバーでインデックスが作成されたりします。
現在のレプリケーションラグを確認するには、MongoDBシェルで実行します。
db.getReplicationInfo()
db.getReplicationInfo()
{
"logSizeMB" : 2157.1845703125,
"usedMB" : 0.05,
"timeDiff" : 4787,
"timeDiffHours" : 1.33,
"tFirst" : "Sun Jul 01 2018 21:40:32 GMT+0000 (UTC)",
"tLast" : "Sun Jul 01 2018 23:00:19 GMT+0000 (UTC)",
"now" : "Sun Jul 01 2018 23:00:26 GMT+0000 (UTC)"
レプリケーションステータスの出力を使用して、レプリケーションの現在の状態を評価し、意図しないレプリケーションの遅延があるかどうかを判断できます。
rs.printSlaveReplicationInfo()
これは、プライマリに対するセカンダリメンバー間の時間遅延を示しています。
rs.status()
レプリケーションの詳細が表示されます。これらのコマンドを使用して、レプリケーションに関する十分な情報を収集できます。うまくいけば、これらのヒントは、MongoDBのパフォーマンスを確認する方法の概要を示しています。何か見逃したことがあればお知らせください。