Module 6 : Performance et Administration
Analyser les performances
explain() - Plan d'exécution
// Modes explain
db.users.find({ ville: "Paris" }).explain() // queryPlanner
db.users.find({ ville: "Paris" }).explain("executionStats")
db.users.find({ ville: "Paris" }).explain("allPlansExecution")
// Points clés à analyser
{
"queryPlanner": {
"winningPlan": {
"stage": "IXSCAN", // IXSCAN = index, COLLSCAN = full scan
"indexName": "ville_1"
}
},
"executionStats": {
"nReturned": 100, // Documents retournés
"totalDocsExamined": 100, // Documents examinés
"totalKeysExamined": 100, // Entrées d'index
"executionTimeMillis": 5 // Temps (ms)
}
}
// Ratio optimal: nReturned == totalDocsExamined
Profiler
// Activer le profiler
db.setProfilingLevel(1, { slowms: 100 }) // Log queries > 100ms
db.setProfilingLevel(2) // Log toutes les queries
db.setProfilingLevel(0) // Désactiver
// Voir les requêtes lentes
db.system.profile.find().sort({ ts: -1 }).limit(10)
// Requêtes lentes > 100ms
db.system.profile.find({ millis: { $gt: 100 } })
currentOp - Operations en cours
// Voir les opérations en cours
db.currentOp()
// Filtrer les opérations longues
db.currentOp({ "secs_running": { $gt: 10 } })
// Killer une opération
db.killOp(opid)
Monitoring
// Stats serveur
db.serverStatus()
// Stats base de données
db.stats()
// Stats collection
db.users.stats()
// Métriques importantes
db.serverStatus().connections // Connexions
db.serverStatus().opcounters // Operations
db.serverStatus().mem // Mémoire
db.serverStatus().wiredTiger // Storage engine
MongoDB Atlas Monitoring
Atlas fournit :
- Dashboard temps réel
- Alertes configurables
- Query Profiler
- Performance Advisor (recommandations index)
- Data Explorer
Optimisation des requêtes
// 1. Utiliser des index appropriés
db.users.createIndex({ ville: 1, age: 1 })
// 2. Projeter seulement les champs nécessaires
db.users.find({ ville: "Paris" }, { nom: 1, email: 1 })
// 3. Utiliser limit() pour grandes collections
db.users.find({ ville: "Paris" }).limit(100)
// 4. Eviter $regex sans ancre
// Mauvais (full scan):
db.users.find({ nom: { $regex: /dupont/i } })
// Bon (utilise index):
db.users.find({ nom: { $regex: /^Dupont/i } })
// 5. Eviter $where (JavaScript)
// Mauvais:
db.users.find({ $where: "this.age > 30" })
// Bon:
db.users.find({ age: { $gt: 30 } })
// 6. Utiliser hint() pour forcer un index
db.users.find({ ville: "Paris" }).hint({ ville: 1, age: 1 })
Replica Sets
+----------------------------------------------------------+
| REPLICA SET |
+----------------------------------------------------------+
| |
| +----------+ +----------+ +----------+ |
| | PRIMARY | |SECONDARY | |SECONDARY | |
| | (R/W) |--->| (R) |--->| (R) | |
| +----------+ +----------+ +----------+ |
| | |
| v Replication asynchrone |
| Ecritures |
| |
+----------------------------------------------------------+
// Configuration replica set
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo1:27017", priority: 2 },
{ _id: 1, host: "mongo2:27017", priority: 1 },
{ _id: 2, host: "mongo3:27017", priority: 1 }
]
})
// Status du replica set
rs.status()
// Ajouter un membre
rs.add("mongo4:27017")
// Retirer un membre
rs.remove("mongo4:27017")
Read Preference
// Où lire les données ?
primary // Seulement PRIMARY (défaut)
primaryPreferred // PRIMARY, sinon SECONDARY
secondary // Seulement SECONDARY
secondaryPreferred // SECONDARY, sinon PRIMARY
nearest // Plus proche (latence)
// Utilisation
db.users.find().readPref("secondaryPreferred")
// Connection string
mongodb://host1,host2,host3/?replicaSet=rs0&readPreference=secondaryPreferred
Write Concern
// Niveau d'acquittement des écritures
w: 0 // Pas d'acquittement
w: 1 // PRIMARY seulement (défaut)
w: "majority" // Majorite des membres
w: 3 // 3 membres spécifiques
j: true // Journal écrit sur disque
// Utilisation
db.users.insertOne(
{ nom: "Test" },
{ writeConcern: { w: "majority", j: true, wtimeout: 5000 } }
)
Sharding
+----------------------------------------------------------+
| SHARDED CLUSTER |
+----------------------------------------------------------+
| |
| +--------+ +--------+ +--------+ |
| | mongos | | mongos | | mongos | Routeurs |
| +--------+ +--------+ +--------+ |
| | | | |
| v v v |
| +------------------------------------------+ |
| | Config Servers | |
| +------------------------------------------+ |
| | | | |
| v v v |
| +--------+ +--------+ +--------+ |
| | Shard1 | | Shard2 | | Shard3 | Données |
| +--------+ +--------+ +--------+ |
| |
+----------------------------------------------------------+
// Activer le sharding sur une base
sh.enableSharding("folab")
// Choisir une shard key et sharder une collection
sh.shardCollection("folab.users", { region: 1 }) // Range
sh.shardCollection("folab.logs", { _id: "hashed" }) // Hashed
// Status du cluster
sh.status()
// Distribution des chunks
db.users.getShardDistribution()
Choisir une shard key
Critères d'une bonne shard key :
- Cardinalité élevée - Beaucoup de valeurs distinctes
- Distribution uniforme - Éviter les hotspots
- Non-monotone - Pas toujours croissante (éviter timestamps seuls)
- Présente dans les requêtes - Pour le routage efficace
// Bonnes shard keys
{ region: 1, date: 1 } // Compound
{ _id: "hashed" } // Distribution uniforme
{ userId: "hashed" } // Pour données par utilisateur
// Mauvaises shard keys
{ createdAt: 1 } // Monotone, hotspot sur dernier shard
{ status: 1 } // Cardinalité faible
Backup et restauration
# mongodump - Backup
mongodump --uri="mongodb://localhost:27017" --out=/backup/
# Collection spécifique
mongodump --uri="mongodb://..." --db=folab --collection=users
# mongorestore - Restauration
mongorestore --uri="mongodb://localhost:27017" /backup/
# Collection spécifique
mongorestore --uri="mongodb://..." --db=folab --collection=users /backup/folab/users.bson
# Export JSON/CSV
mongoexport --uri="mongodb://..." --db=folab --collection=users --out=users.json
mongoexport --uri="mongodb://..." --db=folab --collection=users --type=csv --fields=nom,email --out=users.csv
# Import JSON/CSV
mongoimport --uri="mongodb://..." --db=folab --collection=users --file=users.json
Atlas Backups
# Atlas propose:
# - Continuous Backups (Point-in-time recovery)
# - Snapshots periodiques
# - Restauration vers un nouveau cluster
# Via Atlas CLI
atlas backups snapshots list --clusterName myCluster
atlas backups restores start --clusterName myCluster
Sécurité
// Activer l'authentification (mongod.conf)
security:
authorization: enabled
// Créer un admin
use admin
db.createUser({
user: "admin",
pwd: "securePassword",
roles: ["root"]
})
// Créer un utilisateur applicatif
use folab
db.createUser({
user: "appUser",
pwd: "appPassword",
roles: [
{ role: "readWrite", db: "folab" },
{ role: "read", db: "logs" }
]
})
// Roles built-in
read, readWrite // Base de données
dbAdmin, userAdmin // Administration
clusterAdmin, clusterMonitor // Cluster
backup, restore // Backup
root // Super admin
Checklist production
- [ ] Replica Set avec au moins 3 membres
- [ ] Authentification activée
- [ ] Chiffrement TLS/SSL
- [ ] Backups automatisés
- [ ] Monitoring et alertes
- [ ] Index optimisés
- [ ] Write Concern "majority" pour données critiques
- [ ] Connection pooling configuré
- [ ] Timeouts définis