Le migliori pratiche per le prestazioni
Utilizzare queste informazioni per applicare le migliori pratiche alla distribuzione di Databases for MongoDB in esecuzione su IBM Cloud.
Diagramma di flusso per la risoluzione dei problemi di prestazioni
Utilizzate il diagramma di flusso per determinare come risolvere i problemi di prestazione e le fasi successive.
┌─────────────────────────────────┐
│ 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 │
└────────────────┘
Antipattern comuni
Evitate questi errori comuni che causano problemi di prestazioni.
Antipattern delle query
1. Indici mancanti
Problema:
// No index on 'email' field
db.users.find({ email: "user@example.com" })
Soluzione:
// Create index
db.users.createIndex({ email: 1 })
2. Query regex inefficienti
Problema:
// Case-insensitive regex without index
db.users.find({ name: /john/i })
Soluzione:
// Use text index or exact match
db.users.createIndex({ name: "text" })
db.users.find({ $text: { $search: "john" } })
3. Operazioni di salto() di grandi dimensioni
Problema:
// Skipping thousands of documents
db.collection.find().skip(10000).limit(10)
Soluzione:
// Use range queries with indexed field
db.collection.find({ _id: { $gt: lastSeenId } }).limit(10)
4. Selezione di campi non necessari
Problema:
// Fetching entire documents
db.users.find({ status: "active" })
Soluzione:
// Use projection
db.users.find({ status: "active" }, { name: 1, email: 1 })
5. Pipeline di aggregazione inefficienti
Problema:
// $match after $lookup
db.orders.aggregate([
{ $lookup: { ... } },
{ $match: { status: "completed" } }
])
Soluzione:
// $match first to reduce documents
db.orders.aggregate([
{ $match: { status: "completed" } },
{ $lookup: { ... } }
])
Problemi di progettazione degli schemi
1. Array non vincolati
Problema:
// Array grows indefinitely
{
userId: 123,
activities: [/* thousands of items */]
}
Soluzione:
// Use separate collection or bucketing
{
userId: 123,
month: "2024-01",
activities: [/* limited items */]
}
2. Incorporazione eccessiva
Problema:
// Deeply nested documents
{
user: {
profile: {
settings: {
preferences: {
// many levels deep
}
}
}
}
}
Soluzione:
// Flatten or use references
{
userId: 123,
profileId: 456
}
3. Documenti di grandi dimensioni
Problema:
// Documents approaching 16MB limit
{
data: "very large string...",
attachments: [/* large binary data */]
}
Soluzione:
// Store large data separately (GridFS or object storage)
{
dataRef: "s3://bucket/key",
attachments: [{ ref: "gridfs://id" }]
}
Errori di gestione delle connessioni
1. Non utilizzare il pooling delle connessioni
Problema:
// Creating new connection per request
app.get('/api/users', async (req, res) => {
const client = await MongoClient.connect(uri);
// ...
await client.close();
});
Soluzione:
// 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. Non chiude i cursori
Problema:
// Cursor left open
const cursor = db.collection.find();
// Never closed
Soluzione:
// Always close cursors
const cursor = db.collection.find();
try {
await cursor.forEach(doc => { /* process */ });
} finally {
await cursor.close();
}
3. Troppe connessioni
Problema:
// One connection per user session
const connections = new Map();
users.forEach(user => {
connections.set(user.id, new MongoClient(uri));
});
Soluzione:
// Share connection pool across application
const client = new MongoClient(uri);
// All users share the same pool
Insidie dell'indicizzazione
1. Troppi indici
Problema:
// Index on every field
db.collection.createIndex({ field1: 1 })
db.collection.createIndex({ field2: 1 })
db.collection.createIndex({ field3: 1 })
// ... 20+ indexes
Impatto: Rallenta le scritture e aumenta lo spazio di archiviazione.
Soluzione: Mantenere solo gli indici necessari e utilizzare indici composti.
2. Ordine degli indici errato negli indici composti
Problema:
// Query: { status: "active", createdAt: { $gt: date } }
// Index: { createdAt: 1, status: 1 } // Wrong order
Soluzione:
// Correct order: equality first, range second
db.collection.createIndex({ status: 1, createdAt: 1 })
3. Non utilizzare le query coperte
Problema:
// 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
Soluzione:
// 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 })
Appendice: soglie delle metriche
Soglie consigliate per le principali metriche di prestazione.
| Metrica | Soglia di avvertenza | Soglia critica | Azione consigliata |
|---|---|---|---|
| Utilizzo CPU | 75% | 90% | Scalare i core della CPU |
| Utilizzo della memoria | 80% | 95% | Allocazione della memoria in scala |
| Utilizzo del disco | 80% | 90% | Scalare lo spazio su disco |
| IOPS disco | 80% del limite | 95% del limite | Aumentare le dimensioni del disco per ottenere più IOPS |
| Connessioni attive | 80% del limite | 95% del limite | Pianificazione della scala o ottimizzazione del pooling delle connessioni |
| Ritardo replica | 5 secondi | 30 secondi | Indagare e scalare se necessario |
| Rapporto riscontri cache | < 95% | < 90% | Scalare la memoria o ottimizzare le query |
| Tempo di esecuzione della query | 100ms (avg) | 1000ms (avg) | Ottimizzare le query e gli indici |
| Tempo attesa blocco |
|
|
Ottimizzazione delle operazioni e eliminazione delle query a lungo termine |
| Errori pagina |
|
|
Memoria di scala |
| Latenza di rete |
|
|
Controllare la configurazione di rete |
| Durata del backup | 1 ora | 4 ore | Considerare il ridimensionamento o l'ottimizzazione |
Raccomandazioni sulla frequenza di monitoraggio
| Categoria metrica | Frequenza di controllo | Periodo di conservazione |
|---|---|---|
| Utilizzo delle risorse | Ogni 1 minuto | 30 giorni |
| Prestazioni delle query | Ogni 5 minuti | 14 giorni |
| Stato di replica | Ogni 1 minuto | 30 giorni |
| Statistiche di connessione | Ogni 5 minuti | 14 giorni |
| Stato backup | Ogni 1 ora | 90 giorni |
| Crescita del disco | Ogni 1 ora | 90 giorni |
Esempi di configurazione degli avvisi
Allarme CPU
Condition: CPU > 80% for 10 consecutive minutes
Action: Send notification to ops team
Escalation: Page on-call if > 90% for 15 minutes
Allarme memoria
Condition: Memory > 85% for 15 consecutive minutes
Action: Send notification to ops team
Escalation: Auto-scale if > 95% for 10 minutes
Avviso di ritardo nella replica
Condition: Lag > 10 seconds
Action: Send notification immediately
Escalation: Page on-call if > 60 seconds
Allarme spazio su disco
Condition: Disk > 80%
Action: Send notification to ops team
Escalation: Create incident if > 90%
Sintesi delle migliori pratiche
| Area | Suggerimento |
|---|---|
| Indicizzazione | Esaminate regolarmente e rimuovete gli indici inutilizzati |
| Monitoraggio | Configurare gli avvisi per i ritardi di CPU, memoria, disco e replica |
| Pianificazione della capacità | Mantenere l'utilizzo del disco al di sotto dell'80% e scalare in modo proattivo |
| Progettazione della query | Utilizzare piani di spiegazione durante lo sviluppo |
| Ridimensionamento | Scalare in modo proattivo prima della saturazione |
| Pooling delle connessioni | Utilizzare pool di connessioni ed evitare connessioni per richiesta |
| Leggi le preferenze | Utilizzate le secondarie per i carichi di lavoro in lettura |
| Scrivi preoccupazione | Bilanciare la durata con le esigenze di prestazioni |
| Progettazione dello schema | Evitare array non limitati e incorporazioni eccessive |
| Pianificazione del backup | Programmare durante i periodi di basso traffico |
| Rete | Utilizzate endpoint privati per i carichi di lavoro di IBM Cloud |
| Sicurezza | Ruotare regolarmente le credenziali e utilizzare l'elenco dei permessi IP |
| Documentazione | Documentare le metriche di base e i modelli normali |
| Esecuzione di test | Testate prima le modifiche alle prestazioni nella fase di non produzione |
| Supporto | Raccogliere la diagnostica prima di contattare l'assistenza |