Risoluzione dei problemi di prestazioni per Databases for MongoDB

Utilizzate questa guida per aiutarvi a identificare e risolvere i problemi di prestazioni nella vostra distribuzione Databases for MongoDB in esecuzione su IBM Cloud e alimentata da MongoDB.

Per ulteriori informazioni sulla risoluzione dei problemi di prestazioni, consultare la seguente tabella:

Se le vostre applicazioni hanno risposte lente, timeout o prestazioni incoerenti del database, considerate i passi e le informazioni seguenti.

Sintomi di problemi di prestazioni

Potreste osservare alcuni dei seguenti sintomi che indicano problemi di prestazioni:

  • Aumento della latenza delle applicazioni
  • Voci del log delle query lente
  • Utilizzo elevato della CPU o della memoria
  • Aumento della latenza del disco
  • Ritardo replica
  • Timeout di connessione

Completare i seguenti passaggi per determinare la causa dei problemi:

Passo 1: Verificare l'utilizzo delle risorse

  1. Accedere alla console IBM Cloud e navigare nella distribuzione MongoDB.

  2. Consultare la sezione Monitoraggio per:

    • Utilizzo CPU
    • Utilizzo della memoria
    • IOPS e latenza del disco
    • Connessioni attive

Cosa cercare:

  • CPU costantemente superiore al 75%
  • Memoria costantemente superiore all'80%
  • La latenza del disco aumenta nel tempo
  • Connessioni che si avvicinano ai limiti del piano

Azioni consigliate:

  • Aumentare lo storage o le IOPS se la latenza del disco è elevata.
  • Esaminare i picchi di carico di lavoro dell'applicazione.

Se l'utilizzo delle risorse rimane elevato per periodi prolungati, si consiglia di scalare.

Passo 2: Identificare le query lente

Le query lente sono una delle cause più comuni di degrado delle prestazioni.

  1. Abilita la profilazione:

    db.setProfilingLevel(1, { slowms: 100 })
    
  2. Esaminare le recenti operazioni di rallentamento:

    db.system.profile.find().sort({ ts: -1 }).limit(20)
    
  3. Analizzare l'esecuzione delle query:

    db.collection.find({ ... }).explain("executionStats")
    

Cosa cercare:

  • COLLSCAN (scansione delle collezioni invece di utilizzare gli indici)
  • Alto totalDocsExamined rispetto a nReturned

Azioni consigliate:

  • Creare indici appropriati.
  • Utilizzare gli indici composti per le query a più campi.
  • Assicurarsi che le pipeline di aggregazione inizino con $match.
  • Evitare la paginazione skip() di grandi dimensioni.

Fase 3: Verifica dell'utilizzo della connessione

Le connessioni elevate o mal gestite possono avere un impatto sulle prestazioni.

Controllare le statistiche di connessione:

db.serverStatus().connections

Azioni consigliate:

  • Utilizzate il pooling delle connessioni nella vostra applicazione.
  • Evitare di aprire una nuova connessione per ogni richiesta.
  • Chiudere i cursori inutilizzati.

I limiti di connessione sono determinati dal piano di distribuzione.

Fase 4: Verifica dello stato di salute della replica

Il ritardo nella replica può influire sulle prestazioni di lettura e sulla freschezza dei dati.

Controllare lo stato della replica:

rs.printSecondaryReplicationInfo()

Cause comuni di ritardo:

  • Alta velocità di scrittura
  • Colli di bottiglia del disco
  • Latenza di rete

Azioni consigliate:

  • Scalare le prestazioni dello storage.
  • Rivedere le impostazioni di scrittura delle preoccupazioni.
  • Passare a un piano superiore se il ritardo persiste.

Passo 5: Considerazioni sul cluster Sharded (se applicabile)

Lo sharding potrebbe essere necessario nelle seguenti situazioni:

  • Il set di lavoro è maggiore della RAM
  • IOPS di un singolo nodo al massimo anche dopo lo scaling
  • È richiesto il ridimensionamento della scrittura orizzontale
  • Le collezioni superano 1-2 TB

Per ulteriori informazioni, vedere Sintonizzazione delle prestazioni e sharding.

Se l'installazione utilizza lo sharding, eseguire:

sh.status()

Controllare per:

  • Distribuzione non uniforme dei pezzi
  • Bocconi giganti
  • Traffico concentrato su un unico frammento

Azioni consigliate:

  • Rivedere la selezione delle chiavi di shard.
  • Evitare l'aumento monotono delle chiavi di shard.
  • Considerate le chiavi di shard con hash.

Una selezione non corretta delle chiavi dello shard può influire significativamente sulle prestazioni in scala.

Fase 6: Dopo l'eliminazione di grandi quantità di dati

L'eliminazione di una percentuale significativa di dati non riduce immediatamente l'utilizzo del disco a livello di sistema operativo.

Possibili impatti:

  • Frammentazione interna
  • Elevato utilizzo del disco
  • Prestazioni ridotte

Azioni consigliate:

  • Pianificare attentamente le operazioni di compattazione.
  • Considerare il dump e il ripristino in caso di frammentazione grave.
  • Mantenere l'utilizzo del disco al di sotto dell'80-85%.

Programmare adeguatamente le attività di manutenzione.

Fase 7: verifica della contesa del blocco

La contesa sui blocchi può avere un forte impatto sulle operazioni simultanee e sul throughput complessivo.

  • Controllare le statistiche di blocco globali:

    db.serverStatus().locks
    
  • Controllare le operazioni in corso per i blocchi:

    db.currentOp({
      $or: [
        { waitingForLock: true },
        { "locks.Global": "w" }
      ]
    })
    
  • Analizzare il tempo di attesa del blocco:

    db.serverStatus().globalLock
    

Cosa cercare:

  • Valori elevati currentQueue (lettori o scrittori).
  • Operazioni con waitingForLock: true.
  • Operazioni di lunga durata che mantengono i blocchi.
  • Costruzioni di indici che bloccano le operazioni.

Cause comuni:

  • Query di lunga durata senza indici adeguati.
  • Operazioni di scrittura di grandi dimensioni.
  • L'indice si basa su collezioni di grandi dimensioni.
  • Comandi amministrativi (compact, repairDatabase ).

Azioni consigliate:

  • Se necessario, interrompere le operazioni in corso:
    db.killOp(opid)
    
  • Costruire gli indici in background:
    db.collection.createIndex({ field: 1 }, { background: true })
    
  • Suddividere le operazioni di grandi dimensioni in lotti più piccoli.
  • Programmare gli interventi di manutenzione in periodi di scarso traffico.
  • Utilizzate in modo appropriato i termini read concern e write concern.

Fase 8: analizzare i modelli di carico di lavoro

La comprensione dei modelli di carico di lavoro aiuta a identificare le opportunità di ottimizzazione.

  • Controllare i contatori di funzionamento:

    db.serverStatus().opcounters
    
  • Analizzare le operazioni nel tempo:

    db.serverStatus().opcountersRepl
    
  • Identificare le collezioni calde:

    db.adminCommand({ top: 1 })
    
  • Controllare il rapporto di lettura rispetto a quello di scrittura:

    var stats = db.serverStatus().opcounters;
    print("Read ratio: " + (stats.query + stats.getmore) / (stats.query + stats.getmore + stats.insert + stats.update + stats.delete));
    

Cosa cercare:

  • Operazioni sproporzionate su collezioni specifiche
  • Elevato rapporto lettura-scrittura o scrittura-lettura
  • Improvvisi picchi nel conteggio delle operazioni
  • Modelli basati sul tempo (ore di punta)

Azioni consigliate:

  • Ottimizzate innanzitutto le collezioni di più frequente accesso.
  • Considerare le repliche di lettura per i carichi di lavoro ad alta intensità di lettura.
  • Utilizzare le preferenze di lettura appropriate.
  • Implementare la cache per i dati letti di frequente.
  • Rivedere la strategia di indicizzazione per le collezioni calde.
  • Considerate lo sharding per le raccolte che richiedono un elevato numero di scritture.

Fase 9: Analisi della pressione della memoria e dell'efficienza della cache

MongoDB's WiredTiger il motore di archiviazione si basa molto sull'efficienza della cache.

  • Controllare le statistiche della cache di WiredTiger:

    db.serverStatus().wiredTiger.cache
    
  • Esaminare le metriche chiave:

    var cache = db.serverStatus().wiredTiger.cache;
    print("Cache size: " + cache["bytes currently in the cache"]);
    print("Max cache size: " + cache["maximum bytes configured"]);
    print("Pages read into cache: " + cache["pages read into cache"]);
    print("Pages written from cache: " + cache["pages written from cache"]);
    print("Cache hit ratio: " + (1 - cache["pages read into cache"] / (cache["pages read into cache"] + cache["pages requested from the cache"])));
    
  • Controllare la pressione di sfratto:

    db.serverStatus().wiredTiger.cache["pages evicted by application threads"]
    

Cosa cercare:

  • Rapporto di successo della cache inferiore al 95%
  • Alti tassi di sfratto
  • Dimensione della cache costantemente al massimo
  • Thread dell'applicazione che eseguono lo sfratto

Stimare le dimensioni del set di lavoro:

db.serverStatus().wiredTiger.cache["tracked dirty bytes in the cache"]

Azioni consigliate:

  • Passare a un piano con più memoria se la cache è sempre piena.
  • Rivedere e ottimizzare gli indici (rimuovere gli indici inutilizzati).
  • Limitare le dimensioni dei set di risultati nelle query.
  • Utilizzare le proiezioni per ridurre le dimensioni del documento.
  • Considerare l'archiviazione dei vecchi dati.
  • Monitorare l'andamento delle dimensioni dei set di lavoro.

Le migliori pratiche di allocazione della memoria

  • La cache di WiredTiger dovrebbe essere pari al 50% della RAM disponibile (valore predefinito).
  • Lasciare memoria sufficiente per gli altri processi.
  • Monitorare l'uso dello swap, che dovrebbe essere minimo.

Passo 10: Rivedere le impostazioni delle preferenze di scrittura e lettura

Le impostazioni delle preferenze di scrittura e di lettura hanno un impatto significativo sulle prestazioni e sulla coerenza.

  • Controllare l'attuale preoccupazione di scrittura:

    db.getWriteConcern()
    
  • Controllare la configurazione del set di replica:

    rs.conf()
    
  • Scrivere le opzioni di preoccupazione:

    Opzioni di scrittura delle preoccupazioni
    Scrivi preoccupazione Durabilità Prestazioni Caso d'uso
    w: 1 Basso Alto Dati non critici, elevata produttività
    w: "majority" Alto Medio Approccio predefinito ed equilibrato
    w: <number> Medio-alto Medio-basso Numero di repliche specifiche
    j: true Massima Minima Dati critici che richiedono la sincronizzazione del giornale
  • Leggere le opzioni di preferenza:

    Opzioni di lettura delle preferenze
    Leggi la preferenza Congruenza Prestazioni Caso d'uso
    primary Massima Medio Default, forte coerenza
    primaryPreferred Alto Medio-alto Fallback al secondario
    secondary Eventuale Alto Analisi, reportistica
    secondaryPreferred Eventuale Alto Leggi la scalatura
    nearest Eventuale Massima La latenza più bassa
  • Controllare la preferenza di lettura nella domanda:

    // Example in Node.js driver
    db.collection('users').find({}).readPreference('secondary')
    

Cosa cercare:

  • Criticità di scrittura eccessivamente rigide per i dati non critici
  • Utilizzare la preferenza di lettura di primary quando la coerenza finale è accettabile
  • Non sfruttate le secondarie per i carichi di lavoro in lettura

Azioni consigliate:

  • Utilizzate w: 1 per le scritture ad alta velocità e non critiche.
  • Utilizzare w: "majority" per i dati importanti (impostazione predefinita).
  • Utilizzare secondary o secondaryPreferred per le query di analisi.
  • Considerate nearest per le applicazioni distribuite geograficamente.
  • Bilanciare i requisiti di coerenza con le esigenze di prestazioni.
  • Testate diverse configurazioni sotto carico.

Fase 11: Monitoraggio dell'impatto di backup e manutenzione

Le operazioni di backup e le attività di manutenzione possono influire temporaneamente sulle prestazioni.

IBM Cloud programma di backup

Databases for MongoDB esegue automaticamente un backup. Controllare la pianificazione dei backup nella console IBM Cloud alla voce Backup.

Controllare le operazioni di backup in corso:

db.currentOp({
  $or: [
    { op: "command", "command.backup": { $exists: true } },
    { desc: /^conn/ }
  ]
})

Cosa cercare:

  • Degrado delle prestazioni durante le finestre di backup
  • Aumento dell'I/O del disco durante i backup
  • Ritardo nella replica durante i backup

Azioni consigliate:

  • Monitorare le metriche delle prestazioni durante i tempi di backup.
  • Considerare il ridimensionamento se i backup hanno un impatto costante sulle prestazioni.
  • Esaminare le politiche di conservazione dei backup.
  • Pianificare l'aumento dell'utilizzo delle risorse durante le operazioni di ripristino.

Le migliori pratiche di manutenzione

  • Programmare la costruzione di indici durante i periodi di scarso traffico.
  • Quando è possibile, utilizzare gli indici di sfondo.
  • Monitorare il ritardo della replica durante la manutenzione.
  • Testare prima le operazioni di manutenzione in condizioni di non produzione.
  • Coordinarsi con le finestre di manutenzione di IBM Cloud.