Come configurare MongoDB driver Java MongoOptions per l'uso in produzione?


100

Ho cercato sul Web le migliori pratiche per la configurazione di MongoOptions per il driver Java MongoDB e non ho trovato molto altro che l'API. Questa ricerca è iniziata dopo che mi sono imbattuto nell'errore "com.mongodb.DBPortPool $ SemaphoresOut: Out of semaphores to get db connection" e aumentando le connessioni / moltiplicatore sono stato in grado di risolvere il problema. Sto cercando collegamenti o le tue best practice per configurare queste opzioni per la produzione.

Le opzioni per il driver 2.4 includono: http://api.mongodb.org/java/2.4/com/mongodb/MongoOptions.html

  • autoConnectRetry
  • connectionsPerHost
  • connectTimeout
  • maxWaitTime
  • socketTimeout
  • threadAllowedToBlockForConnectionMultiplier

I nuovi driver hanno più opzioni e sarei interessato a saperne di più.

Risposte:


160

Aggiornato a 2.9:

  • autoConnectRetry significa semplicemente che il driver tenterà automaticamente di riconnettersi al server dopo una disconnessione imprevista. Negli ambienti di produzione di solito si desidera impostare questo valore su true.

  • connectionsPerHost è la quantità di connessioni fisiche che una singola istanza Mongo (è singleton, quindi di solito ne hai una per applicazione) può stabilire un processo mongod / mongos. Al momento della scrittura, il driver java stabilirà questa quantità di connessioni alla fine anche se il throughput effettivo della query è basso (in ordine di parole vedrai aumentare la statistica "conn" in Mongostat fino a raggiungere questo numero per server app).

    Non è necessario impostarlo su un valore superiore a 100 nella maggior parte dei casi, ma questa impostazione è una di quelle cose "provalo e guarda". Tieni presente che dovrai assicurarti di impostare questo valore sufficientemente basso in modo che la quantità totale di connessioni al tuo server non superi

    db.serverStatus().connections.available

    In produzione attualmente abbiamo questo a 40.

  • connectTimeout . Poiché il nome suggerisce un numero di millisecondi, il driver attenderà prima che un tentativo di connessione venga interrotto. Imposta il timeout su un valore lungo (15-30 secondi) a meno che non ci sia una possibilità realistica e attesa che ciò impedisca tentativi di connessione altrimenti riusciti. Normalmente, se un tentativo di connessione richiede più di un paio di secondi, l'infrastruttura di rete non è in grado di offrire un throughput elevato.

  • maxWaitTime . Numero di ms che un thread attenderà prima che una connessione diventi disponibile nel pool di connessioni e solleva un'eccezione se ciò non avviene in tempo. Mantieni predefinito.

  • socketTimeout . Valore di timeout del socket standard. Impostato su 60 secondi (60000).

  • threadAllowedToBlockForConnectionMultiplier . Moltiplicatore per connectionsPerHost che indica il numero di thread che possono attendere che le connessioni diventino disponibili se il pool è attualmente esaurito. Questa è l'impostazione che causerà l'eccezione "com.mongodb.DBPortPool $ SemaphoresOut: fuori dai semafori per ottenere la connessione db". Verrà generata questa eccezione una volta che la coda di thread supera il valore threadAllowedToBlockForConnectionMultiplier. Ad esempio, se connectionsPerHost è 10 e questo valore è 5, è possibile bloccare fino a 50 thread prima che venga generata l'eccezione di cui sopra.

    Se si prevedono grandi picchi di velocità effettiva che potrebbero causare code di grandi dimensioni, aumentare temporaneamente questo valore. Al momento lo abbiamo a 1500 esattamente per questo motivo. Se il carico della tua query supera costantemente il server, dovresti semplicemente migliorare la tua situazione hardware / scalabilità di conseguenza.

  • readPreference . (AGGIORNATO, 2.8+) Utilizzato per determinare la preferenza di lettura predefinita e sostituisce "slaveOk". Configurare un ReadPreference tramite uno dei metodi class factory. Una descrizione completa delle impostazioni più comuni è disponibile alla fine di questo post

  • w . (AGGIORNATO, 2.6+) Questo valore determina la "sicurezza" della scrittura. Quando questo valore è -1, la scrittura non riporterà alcun errore indipendentemente dagli errori di rete o di database. WriteConcern.NONE è il WriteConcern predefinito appropriato per questo. Se w è 0, gli errori di rete faranno fallire la scrittura, ma gli errori di mongo no. Questo è in genere indicato come scritture "spara e dimentica" e dovrebbe essere utilizzato quando le prestazioni sono più importanti della coerenza e della durata. Usa WriteConcern.NORMAL per questa modalità.

    Se si imposta w a 1 o superiore, la scrittura è considerata sicura. Le scritture sicure eseguono la scrittura e la fanno seguire da una richiesta al server per assicurarsi che la scrittura sia riuscita o recupera un valore di errore se non lo ha fatto (in altre parole, invia un comando getLastError () dopo la scrittura). Notare che fino a quando questo comando getLastError () non viene completato, la connessione è riservata. Come risultato di ciò e del comando aggiuntivo, la velocità effettiva sarà notevolmente inferiore rispetto alle scritture con w <= 0. Con un valore aw di esattamente 1, MongoDB garantisce che la scrittura sia riuscita (o verificabilmente fallita) sull'istanza a cui è stata inviata la scrittura.

    Nel caso dei set di repliche puoi usare valori più alti per w che dice a MongoDB di inviare la scrittura almeno ai membri "w" del set di repliche prima di tornare (o più precisamente, attendere la replica della tua scrittura ai membri "w" ). Puoi anche impostare w sulla stringa "maggioranza" che dice a MongoDB di eseguire la scrittura sulla maggior parte dei membri del set di repliche (WriteConcern.MAJORITY). In genere dovresti impostarlo su 1 a meno che non siano necessarie prestazioni non elaborate (-1 o 0) o scritture replicate (> 1). I valori superiori a 1 hanno un impatto considerevole sulla velocità effettiva di scrittura.

  • fsync . Opzione di durabilità che, se abilitata, costringe mongo a scaricare su disco dopo ogni scrittura. Non ho mai avuto problemi di durabilità relativi a un backlog di scrittura, quindi abbiamo questo valore su false (impostazione predefinita) in produzione.

  • j * (NUOVO 2.7+) *. Booleano che, se impostato su true, forza MongoDB ad attendere il commit di un gruppo di journaling riuscito prima di tornare. Se il journaling è abilitato, puoi abilitarlo per una maggiore durata. Fare riferimento a http://www.mongodb.org/display/DOCS/Journaling per vedere cosa ti offre il journaling (e quindi perché potresti voler abilitare questo flag).

ReadPreference La classe ReadPreference consente di configurare a quali istanze di mongod vengono instradate le query se si lavora con i set di repliche. Sono disponibili le seguenti opzioni:

  • ReadPreference.primary () : tutte le letture vengono inviate solo al membro principale del repset. Utilizzare questa opzione se si richiede che tutte le query restituiscano dati coerenti (gli ultimi scritti). Questa è l'impostazione predefinita.

  • ReadPreference.primaryPreferred () : tutte le letture vanno al membro primario repset, se possibile, ma possono interrogare i membri secondari se il nodo primario non è disponibile. Pertanto, se il primario diventa non disponibile, le letture diventano coerenti, ma solo se il primario non è disponibile.

  • ReadPreference.secondary () : tutte le letture passano ai membri del repset secondario e il membro primario viene utilizzato solo per le scritture. Usalo solo se riesci a convivere con letture coerenti alla fine. È possibile utilizzare membri aggiuntivi del ripetitore per aumentare le prestazioni di lettura sebbene ci siano limiti al numero di membri (votanti) che un rappresentante può avere.

  • ReadPreference.secondaryPreferred () : tutte le letture vanno ai membri del repset secondario se qualcuno di essi è disponibile. Il membro primario viene utilizzato esclusivamente per le scritture a meno che tutti i membri secondari non siano disponibili. A parte il fallback al membro primario per le letture, questo è lo stesso di ReadPreference.secondary ().

  • ReadPreference.nearest () : le letture vanno al membro repset più vicino disponibile per il client del database. Utilizzare solo se sono accettabili letture coerenti alla fine. Il membro più vicino è il membro con la latenza più bassa tra il client ei vari membri del repset. Poiché i membri occupati alla fine avranno latenze più elevate, questo dovrebbe anche bilanciare automaticamente il carico di lettura anche se nella mia esperienza secondario (Preferito) sembra farlo meglio se le latenze dei membri sono relativamente coerenti.

Nota: tutte le versioni precedenti hanno versioni abilitate per tag dello stesso metodo che restituiscono invece istanze di TaggableReadPreference. Una descrizione completa dei tag del set di repliche è disponibile qui: Tag del set di repliche


6
Non è pericoloso lasciare socketTimeout e connectTimeout come predefiniti (infinito)? Se una connessione si blocca per qualche motivo, la tua app (o almeno quel thread) si bloccherà per sempre. Non dovrebbero essere impostati come molto molto alti (qualcosa come 30 secondi per la connessione, 2 minuti per il socket)?
Idris Mokhtarzada

Idris, molto vero. Nel mio post ho erroneamente dato per scontato che MongoOptions avesse i nostri valori predefiniti. Il nostro layer Mongo ORM li ha rispettivamente a 15 secondi e 1 minuto e durante la scrittura ho pensato che fossero i valori predefiniti. I timeout infiniti sono decisamente una cattiva idea. Grazie per l'avviso, l'ho corretto nel post
Remon van Vliet

l'opzione "slaveOk" è ora deprecata, se vuoi che sia vero l'equivalente, fai: mongoOptions.readPreference = ReadPreference.secondaryPreferred ();
Gubatron

Buona risposta ma la tua definizione di threadAllowedToBlockForConnectionMultiplier è sbagliata (moltiplicatore di parole chiave). Come da documentazione: "moltiplicatore per connectionsPerHost per # di thread che possono bloccare se connectionsPerHost è 10 e threadAllowedToBlockForConnectionMultiplier è 5, quindi 50 thread possono bloccare più di quello e verrà generata un'eccezione"
Tyler Zale

3
Sembra una risposta piuttosto popolare. Se qualcuno è interessato a farmi aggiornare questo per riflettere le modifiche nell'ultimo driver, fammelo sapere
Remon van Vliet
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.