Meilleures pratiques pour la performance
Utilisez ces informations pour appliquer les meilleures pratiques à votre déploiement de Databases for MongoDB sur IBM Cloud.
Organigramme de dépannage des performances
Utilisez l'organigramme pour déterminer comment dépanner les performances et les étapes à suivre.
┌─────────────────────────────────┐
│ 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 │
└────────────────┘
Antimodèles courants
Évitez ces erreurs courantes qui entraînent des problèmes de performance.
Antimodèles de requête
1. Index manquants
Problème :
// No index on 'email' field
db.users.find({ email: "user@example.com" })
Solution :
// Create index
db.users.createIndex({ email: 1 })
2. Requêtes regex inefficaces
Problème :
// Case-insensitive regex without index
db.users.find({ name: /john/i })
Solution :
// Use text index or exact match
db.users.createIndex({ name: "text" })
db.users.find({ $text: { $search: "john" } })
3. Grandes opérations skip()
Problème :
// Skipping thousands of documents
db.collection.find().skip(10000).limit(10)
Solution :
// Use range queries with indexed field
db.collection.find({ _id: { $gt: lastSeenId } }).limit(10)
4. Sélection de champs inutiles
Problème :
// Fetching entire documents
db.users.find({ status: "active" })
Solution :
// Use projection
db.users.find({ status: "active" }, { name: 1, email: 1 })
5. Pipelines d'agrégation inefficaces
Problème :
// $match after $lookup
db.orders.aggregate([
{ $lookup: { ... } },
{ $match: { status: "completed" } }
])
Solution :
// $match first to reduce documents
db.orders.aggregate([
{ $match: { status: "completed" } },
{ $lookup: { ... } }
])
Questions relatives à la conception des schémas
1. Tableaux non bornés
Problème :
// Array grows indefinitely
{
userId: 123,
activities: [/* thousands of items */]
}
Solution :
// Use separate collection or bucketing
{
userId: 123,
month: "2024-01",
activities: [/* limited items */]
}
2. Encastrement excessif
Problème :
// Deeply nested documents
{
user: {
profile: {
settings: {
preferences: {
// many levels deep
}
}
}
}
}
Solution :
// Flatten or use references
{
userId: 123,
profileId: 456
}
3. Documents volumineux
Problème :
// Documents approaching 16MB limit
{
data: "very large string...",
attachments: [/* large binary data */]
}
Solution :
// Store large data separately (GridFS or object storage)
{
dataRef: "s3://bucket/key",
attachments: [{ ref: "gridfs://id" }]
}
Erreurs de gestion des connexions
1. Ne pas utiliser la mise en commun des connexions
Problème :
// Creating new connection per request
app.get('/api/users', async (req, res) => {
const client = await MongoClient.connect(uri);
// ...
await client.close();
});
Solution :
// 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. Ne pas fermer les curseurs
Problème :
// Cursor left open
const cursor = db.collection.find();
// Never closed
Solution :
// Always close cursors
const cursor = db.collection.find();
try {
await cursor.forEach(doc => { /* process */ });
} finally {
await cursor.close();
}
3. Trop de connexions
Problème :
// One connection per user session
const connections = new Map();
users.forEach(user => {
connections.set(user.id, new MongoClient(uri));
});
Solution :
// Share connection pool across application
const client = new MongoClient(uri);
// All users share the same pool
Les pièges de l'indexation
1. Trop d'index
Problème :
// Index on every field
db.collection.createIndex({ field1: 1 })
db.collection.createIndex({ field2: 1 })
db.collection.createIndex({ field3: 1 })
// ... 20+ indexes
Impact : Ralentit les écritures et augmente l'espace de stockage.
Solution : Ne conserver que les index nécessaires et utiliser des index composés.
2. Mauvais ordre d'indexation dans les index composés
Problème :
// Query: { status: "active", createdAt: { $gt: date } }
// Index: { createdAt: 1, status: 1 } // Wrong order
Solution :
// Correct order: equality first, range second
db.collection.createIndex({ status: 1, createdAt: 1 })
3. Ne pas utiliser de requêtes couvertes
Problème :
// 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
Solution :
// 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 })
Annexe : seuils de mesure
Seuils recommandés pour les principaux indicateurs de performance.
| Métrique | Seuil d'avertissement | Seuil critique | Action recommandée |
|---|---|---|---|
| Utilisation de l'UC |
|
|
Augmenter le nombre de cœurs de l'unité centrale |
| Utilisation de mémoire |
|
|
Allocation de mémoire à l'échelle |
| Utilisation du disque |
|
|
Augmenter l'espace disque |
| IOPS de disque |
|
|
Augmenter la taille du disque pour plus d'IOPS |
| Connexions actives |
|
|
Planification de l'échelle ou optimisation de la mise en commun des connexions |
| Décalage de réplication |
|
|
Enquêter et échelonner si nécessaire |
| Taux de réussite en cache | < 95 % | < 90 % | Augmenter la mémoire ou optimiser les requêtes |
| Temps d'exécution de la requête |
|
|
Optimiser les requêtes et les index |
| Temps d'attente sur verrouillage |
|
|
Optimiser les opérations et supprimer les requêtes de longue durée |
| Défauts de page |
|
|
Mémoire d'échelle |
| Temps d'attente du réseau |
|
|
Vérifier la configuration du réseau |
| Durée de la sauvegarde |
|
|
Envisager une mise à l'échelle ou une optimisation |
Recommandations sur la fréquence des contrôles
| Catégorie de métrique | Fréquence de vérification | Durée de conservation |
|---|---|---|
| Utilisation des ressources | Toutes les 1 minutes | 30 jours |
| Performances des requêtes | Toutes les 5 minutes | 15 jours |
| Statut de la réplication | Toutes les 1 minutes | 30 jours |
| Statistiques de connexion | Toutes les 5 minutes | 15 jours |
| Statut de la sauvegarde | Toutes les heures | 90 jours |
| Croissance du disque | Toutes les heures | 90 jours |
Exemples de configuration des alertes
Alerte CPU
Condition: CPU > 80% for 10 consecutive minutes
Action: Send notification to ops team
Escalation: Page on-call if > 90% for 15 minutes
Alerte mémoire
Condition: Memory > 85% for 15 consecutive minutes
Action: Send notification to ops team
Escalation: Auto-scale if > 95% for 10 minutes
Alerte au retard de réplication
Condition: Lag > 10 seconds
Action: Send notification immediately
Escalation: Page on-call if > 60 seconds
Alerte sur l'espace disque
Condition: Disk > 80%
Action: Send notification to ops team
Escalation: Create incident if > 90%
Résumé des bonnes pratiques
| Zone | Recommandation |
|---|---|
| Indexation | Examiner régulièrement les index inutilisés et les supprimer |
| Monitoring | Configurer des alertes pour le CPU, la mémoire, le disque et la réplication |
| Planification de la capacité | Maintenir l'utilisation du disque en dessous de 80 % et évoluer de manière proactive |
| Conception des requêtes | Utiliser des plans d'explication pendant le développement |
| Mise à l'échelle | Réduire l'échelle de manière proactive avant la saturation |
| regroupement de connexions | Utiliser des pools de connexion et éviter les connexions par requête |
| Lire les préférences | Utiliser des systèmes secondaires pour les charges de travail à forte intensité de lecture |
| Ecriture d'une préoccupation | Équilibrer la durabilité avec les besoins de performance |
| Conception des schémas | Éviter les tableaux non bornés et l'encastrement excessif |
| Planification de la sauvegarde | Programmation pendant les périodes de faible affluence |
| Réseau | Utiliser des points d'extrémité privés pour les charges de travail IBM Cloud |
| Sécurité | Rotation régulière des informations d'identification et utilisation d'une liste d'adresses IP autorisées |
| Documentation | Documenter les mesures de référence et les schémas normaux |
| Tests | Tester les changements de performance dans la première phase de non-production |
| Support | Réaliser des diagnostics avant de contacter le service d'assistance |