Indicizzazione della mangusta nel codice di produzione


124

Secondo la documentazione Mongoose per MongooseJSe MongoDB/ Node.js:

All'avvio dell'applicazione, Mongoose chiama automaticamente ensureIndexogni indice definito nello schema. Sebbene sia utile per lo sviluppo, si consiglia di disabilitare questo comportamento in produzione poiché la creazione dell'indice può causare un impatto significativo sulle prestazioni. Disabilita il comportamento impostando l' autoIndexopzione del tuo schema su false.

Questo sembra istruire la rimozione dell'indicizzazione automatica da mongoose prima della distribuzione per ottimizzare Mongoose dall'istruzione di Mongo di andare a sfornare tutti gli indici all'avvio dell'applicazione, il che sembra avere senso.

Qual è il modo corretto per gestire l'indicizzazione nel codice di produzione? Forse uno script esterno dovrebbe generare indici? O forse ensureIndexnon è necessario se una singola applicazione è l'unico lettore / scrittore di una raccolta perché continuerà un indice ogni volta che si verifica una scrittura su DB?

Modifica: per integrare, MongoDB fornisce una buona documentazione su come eseguire l'indicizzazione, ma non perché o quando dovrebbero essere eseguite le direttive di indicizzazione esplicite. Mi sembra che gli indici debbano essere aggiornati automaticamente dalle applicazioni di scrittura sulle raccolte con indici esistenti e che ensureIndexè davvero più di una cosa una tantum (eseguita quando viene applicato un nuovo indice), nel qual caso Mongoose autoIndexdovrebbe essere un no-op in un normale riavvio del server.

Risposte:


135

Non ho mai capito perché la documentazione di Mongoose consiglia così ampiamente la disabilitazione autoIndexin produzione. Una volta che l'indice è stato aggiunto, le ensureIndexchiamate successive vedranno semplicemente che l'indice esiste già e quindi torneranno. Quindi ha un effetto sulle prestazioni solo quando crei l'indice per la prima volta e in quel momento le raccolte sono spesso vuote, quindi la creazione di un indice sarebbe comunque rapida.

Il mio suggerimento è di lasciare autoIndexabilitato a meno che tu non abbia una situazione specifica in cui ti dà problemi; come se desideri aggiungere un nuovo indice a una raccolta esistente che contiene milioni di documenti e desideri un maggiore controllo su quando viene creato.


10
Ho una domanda da aggiungere ... Cosa succede se lo imposto falso? Quindi gli indici verranno creati quando inserisco i dati o devo crearli esplicitamente. Mi dispiace se questa è una domanda per principianti, ma sarebbe davvero utile se rispondessi.
Saransh Mohapatra,

5
@SaranshMohapatra Quando autoIndexè falso, è necessario chiamare sureIndexes sul modello per creare i suoi indici.
JohnnyHK

Di quanto dovrò chiamarlo ogni volta o solo una volta definendo il modello?
Saransh Mohapatra

@SaranshMohapatra quando definisci (compila) il tuo modello. Lo faccio la prima volta che avvio l'app. Ora la cosa difficile è decidere di eliminare tutti gli indici e ricrearli, nel caso in cui lo schema cambi.
Moss

3
@JohnnyHK sei ancora d'accordo con la tua risposta ora che è quasi il 2016?
Alexander Mills

41

Sebbene sia d'accordo con la risposta accettata, vale la pena notare che, secondo il manuale di MongoDB , questo non è il modo consigliato per aggiungere indici su un server di produzione:

Se la tua applicazione include operazioni sureIndex () e non esiste un indice per altri problemi operativi, la creazione dell'indice può avere un grave impatto sulle prestazioni del database.

Per evitare problemi di prestazioni, assicurati che l'applicazione controlli gli indici all'avvio utilizzando il metodo getIndexes () o il metodo equivalente per il tuo driver e termini se gli indici corretti non esistono. Crea sempre gli indici nelle istanze di produzione utilizzando il codice dell'applicazione separato, durante le finestre di manutenzione designate.

Naturalmente, dipende davvero da come la tua applicazione è strutturata e distribuita. Se stai distribuendo su Heroku, ad esempio, e non stai utilizzando la funzione di preavvio di Heroku , è probabile che la tua applicazione non stia affatto servendo richieste durante l'avvio, quindi è probabilmente sicuro creare un indice in quel momento.

Oltre a questo, dalla risposta accettata:

Quindi ha un effetto sulle prestazioni solo quando crei l'indice per la prima volta e in quel momento le raccolte sono spesso vuote, quindi la creazione di un indice sarebbe comunque rapida.

Se sei riuscito a ottenere il modello di dati e le query inchiodate la prima volta, va bene, e spesso è così. Tuttavia, se stai aggiungendo nuove funzionalità alla tua app, con una nuova query DB su una proprietà senza un indice, ti ritroverai spesso ad aggiungere un indice a una raccolta contenente molti documenti esistenti.

Questo è il momento in cui è necessario prestare attenzione all'aggiunta di indici e considerare attentamente le implicazioni sulle prestazioni di farlo. Ad esempio, potresti creare l'indice in background :

db.ensureIndex({ name: 1 }, { background: true });

3
Ok, quindi tutto ciò che devi fare è NON avviare il tuo server fino a quando tutti i callback sureIndex non sono stati attivati ​​per ogni raccolta.
Alexander Mills

@AlexMills come lo assicuri?
lonelymo

async.each (Object.keys (models), function (key, cb) {models [key] .ensureIndexes (cb)}, cb)
Alexander Mills

basta chiamare sureIndexes su ogni modello di mangusta, attendere che tutto finisca, quindi avviare il server; Consiglio anche di aspettare che avvengano le connessioni db prima di avviare anche il tuo server
Alexander Mills

2
Non c'è ensureIndexpiù. C'è createIndexinvece. Ho ragione?
jack blank

1

usa questo codice di blocco per gestire la modalità di produzione:

const autoIndex = process.env.NODE_ENV !== 'production';
mongoose.connect('mongodb://localhost/collection', { autoIndex });
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.