パフォーマンスのベストプラクティス
IBM Cloud 上で動作する Databases for MongoDB のデプロイメントにベストプラクティスを適用するために、この情報を使用してください。
パフォーマンス・トラブルシューティングのフローチャート
フローチャートを使用して、パフォーマンスのトラブルシューティング方法と次に取るべき手順を決定します。
┌─────────────────────────────────┐
│ Performance issue detected │
└────────────┬────────────────────┘
│
▼
┌─────────────────────────────────┐
│ Check IBM Cloud Monitoring │
│ - CPU > 80%? │
│ - Memory > 80%? │
│ - Disk latency high? │
└────────────┬────────────────────┘
│
┌────┴────┐
│ YES │
▼ │
┌──────────────┐ │
│ Scale │ │
│ resources │ │
└──────────────┘ │
│ NO
▼
┌─────────────────────┐
│ Check slow queries │
│ db.system.profile │
└─────────┬───────────┘
│
┌────┴────┐
│ Found? │
▼ │
┌─────────┐ │
│ Optimize│ │
│ queries │ │
│ & indexes│ │
└─────────┘ │
│ NO
▼
┌────────────────┐
│ Check Locks │
│ currentOp() │
└────────┬───────┘
│
┌────┴────┐
│ Locked? │
▼ │
┌─────────┐ │
│ Kill or │ │
│ optimize│ │
└─────────┘ │
│ NO
▼
┌────────────────┐
│ Check cache │
│ hit ratio │
└────────┬───────┘
│
┌────┴────┐
│ < 95%? │
▼ │
┌─────────┐ │
│ Scale │ │
│ memory │ │
└─────────┘ │
│ NO
▼
┌────────────────┐
│ Check │
│ replication │
└────────┬───────┘
│
┌────┴────┐
│ Lagging?│
▼ │
┌─────────┐ │
│ Scale │ │
│ or fix │ │
└─────────┘ │
│ NO
▼
┌────────────────┐
│ Contact IBM │
│ Support │
└────────────────┘
よくあるアンチパターン
パフォーマンスの問題につながる、よくある間違いを避けましょう。
クエリーのアンチパターン
1.インデックスの欠落
問題点:
// No index on 'email' field
db.users.find({ email: "user@example.com" })
解決策:
// Create index
db.users.createIndex({ email: 1 })
2.非効率な正規表現クエリ
問題点:
// Case-insensitive regex without index
db.users.find({ name: /john/i })
解決策:
// Use text index or exact match
db.users.createIndex({ name: "text" })
db.users.find({ $text: { $search: "john" } })
3.大きな skip() 操作
問題点:
// Skipping thousands of documents
db.collection.find().skip(10000).limit(10)
解決策:
// Use range queries with indexed field
db.collection.find({ _id: { $gt: lastSeenId } }).limit(10)
4.不要なフィールドの選択
問題点:
// Fetching entire documents
db.users.find({ status: "active" })
解決策:
// Use projection
db.users.find({ status: "active" }, { name: 1, email: 1 })
5.非効率なアグリゲーション・パイプライン
問題点:
// $match after $lookup
db.orders.aggregate([
{ $lookup: { ... } },
{ $match: { status: "completed" } }
])
解決策:
// $match first to reduce documents
db.orders.aggregate([
{ $match: { status: "completed" } },
{ $lookup: { ... } }
])
スキーマ設計の問題
1.束縛されない配列
問題点:
// Array grows indefinitely
{
userId: 123,
activities: [/* thousands of items */]
}
解決策:
// Use separate collection or bucketing
{
userId: 123,
month: "2024-01",
activities: [/* limited items */]
}
2.過度の埋め込み
問題点:
// Deeply nested documents
{
user: {
profile: {
settings: {
preferences: {
// many levels deep
}
}
}
}
}
解決策:
// Flatten or use references
{
userId: 123,
profileId: 456
}
3.大型書類
問題点:
// Documents approaching 16MB limit
{
data: "very large string...",
attachments: [/* large binary data */]
}
解決策:
// Store large data separately (GridFS or object storage)
{
dataRef: "s3://bucket/key",
attachments: [{ ref: "gridfs://id" }]
}
コネクション管理のミス
1.コネクション・プーリングを使用しない
問題点:
// Creating new connection per request
app.get('/api/users', async (req, res) => {
const client = await MongoClient.connect(uri);
// ...
await client.close();
});
解決策:
// Reuse connection pool
const client = new MongoClient(uri, { maxPoolSize: 50 });
await client.connect();
app.get('/api/users', async (req, res) => {
const db = client.db();
// ...
});
2.カーソルを閉じない
問題点:
// Cursor left open
const cursor = db.collection.find();
// Never closed
解決策:
// Always close cursors
const cursor = db.collection.find();
try {
await cursor.forEach(doc => { /* process */ });
} finally {
await cursor.close();
}
3.接続が多すぎる
問題点:
// One connection per user session
const connections = new Map();
users.forEach(user => {
connections.set(user.id, new MongoClient(uri));
});
解決策:
// Share connection pool across application
const client = new MongoClient(uri);
// All users share the same pool
インデックスの落とし穴
1.インデックスが多すぎる
問題点:
// Index on every field
db.collection.createIndex({ field1: 1 })
db.collection.createIndex({ field2: 1 })
db.collection.createIndex({ field3: 1 })
// ... 20+ indexes
影響書き込みが遅くなり、ストレージが増える。
解決策必要なインデックスだけを保持し、複合インデックスを使用する。
2.複合インデックスにおける誤ったインデックス順序
問題点:
// Query: { status: "active", createdAt: { $gt: date } }
// Index: { createdAt: 1, status: 1 } // Wrong order
解決策:
// Correct order: equality first, range second
db.collection.createIndex({ status: 1, createdAt: 1 })
3.カバード・クエリーを使用しない
問題点:
// Index exists but query not covered
db.users.createIndex({ email: 1 })
db.users.find({ email: "user@example.com" }, { name: 1, email: 1 })
// Still fetches documents
解決策:
// Include all projected fields in index
db.users.createIndex({ email: 1, name: 1 })
db.users.find({ email: "user@example.com" }, { name: 1, email: 1, _id: 0 })
付録:メトリクスのしきい値
主要業績評価指標の推奨しきい値。
| メトリック | 警告しきい値 | クリティカルしきい値 | 推奨処置 |
|---|---|---|---|
| CPU 使用率 | 75 | 90 | スケールCPUコア |
| メモリー使用率 | 80% | 95 | メモリ割り当ての拡大 |
| ディスク使用率 | 80% | 90 | ディスク容量の拡大 |
| ディスク IOPS | リミットの80 | 限界の95 | ディスクサイズを大きくしてIOPSを増やす |
| アクティブな接続 | リミットの80 | 限界の95 | コネクションプーリングのスケールプランと最適化 |
| レプリケーション・ラグ | 5秒 | 30秒 | 調査し、必要に応じて規模を拡大する |
| キャッシュ・ヒット率 | < 95% | < 90% | メモリの拡張やクエリの最適化 |
| クエリー実行時間 | 100ms (平均) | 1000ms (平均) | クエリとインデックスの最適化 |
| ロック待機時間 | ってね; 100ms | ってね; 1000ms | オペレーションを最適化し、長時間実行するクエリを停止する |
| ページ・フォールト | ってね; 100/sec | ってね; 1000/sec | スケールメモリー |
| ネットワーク待ち時間 | ってね; 10ms | ってね; 50ms | ネットワーク設定の確認 |
| バックアップ期間 | 1時間 | 4時間 | スケーリングまたは最適化を検討する |
モニタリング頻度の推奨
| メトリック・カテゴリー | 確認頻度 | 保存期間 |
|---|---|---|
| リソース使用 | 1分ごと | 30 日間 |
| 照会のパフォーマンス | 5分ごと | 14日間 |
| 複製状況 | 1分ごと | 30 日間 |
| 接続統計 | 5分ごと | 14日間 |
| バックアップ状況 | 1 時間ごと | 90 日間 |
| ディスクの成長 | 1 時間ごと | 90 日間 |
アラート設定例
CPUアラート
Condition: CPU > 80% for 10 consecutive minutes
Action: Send notification to ops team
Escalation: Page on-call if > 90% for 15 minutes
メモリー・アラート
Condition: Memory > 85% for 15 consecutive minutes
Action: Send notification to ops team
Escalation: Auto-scale if > 95% for 10 minutes
レプリケーション・ラグの警告
Condition: Lag > 10 seconds
Action: Send notification immediately
Escalation: Page on-call if > 60 seconds
ディスク容量警告
Condition: Disk > 80%
Action: Send notification to ops team
Escalation: Create incident if > 90%
ベストプラクティスのまとめ
| 領域 | 推奨 |
|---|---|
| インデックスの付与 | 使用されていないインデックスを定期的に見直し、削除する |
| モニター | CPU、メモリ、ディスク、レプリケーション・ラグのアラート設定 |
| キャパシティー・プランニング | ディスク使用率を80%以下に抑え、プロアクティブに拡張 |
| クエリーデザイン | 開発段階での計画説明 |
| スケーリング | 飽和する前に積極的に規模を拡大する |
| 接続プーリング | コネクションプールを使用し、リクエストごとの接続を避ける |
| 推薦文を読む | 読み取り負荷の高いワークロードにはセカンダリを使用する |
| 懸念事項を書く | 耐久性と性能ニーズのバランス |
| スキーマ設計 | 境界のない配列や過度の埋め込みを避ける |
| バックアップ計画 | 交通量の少ない時間帯にスケジュールを組む |
| ネットワーク | IBM Cloud ワークロードにはプライベート・エンドポイントを使用する |
| セキュリティ | クレデンシャルを定期的にローテーションし、IP許可リストを使用する |
| 資料 | ベースライン指標と通常のパターンを文書化 |
| テスト | パフォーマンスの変更は、まず非本番環境でテストする |
| サポート | サポートに連絡する前に診断結果を収集する |