Recentemente ho suonato con MongoDB (È FANTASTICAMENTE VELOCE) usando il driver C# su GitHub. Tutto funziona perfettamente nella mia piccola app per console a thread singolo con cui sto testando. Sono in grado di aggiungere 1.000.000 di documenti (sì, milioni) in meno di 8 secondi con un singolo thread. Ottengo questa prestazione solo se utilizzo la connessione al di fuori dell'ambito di un ciclo for. In altre parole, sto mantenendo la connessione aperta per ogni inserto piuttosto che la connessione per ogni inserto. Ovviamente è forzato.Migliori pratiche .NET per le connessioni MongoDB?
Ho pensato di fare un salto di una tacca per vedere come funziona con più thread. Lo sto facendo perché ho bisogno di simulare un sito Web con più richieste simultanee. Sto girando tra i 15 e i 50 thread, inserendo ancora un totale di 150.000 documenti in tutti i casi. Se faccio solo girare i thread, creando ciascuno una nuova connessione per ogni operazione di inserimento, le prestazioni si arrestano.
Ovviamente ho bisogno di trovare un modo per condividere, bloccare o mettere in comune la connessione. Qui sta la domanda. Qual è la migliore pratica in termini di connessione a MongoDB? La connessione deve essere mantenuta aperta per tutta la durata dell'app (c'è una latenza sostanziale che apre e chiude la connessione TCP per ogni operazione)?
Qualcuno ha un'esperienza di produzione o di mondo reale con MongoDB, e in particolare la connessione sottostante?
Ecco il mio esempio di threading utilizzando una connessione statica bloccata per operazioni di inserimento. Si prega di offrire suggerimenti che ottimizzino le prestazioni e l'affidabilità in un contesto web!
private static Mongo _mongo;
private static void RunMongoThreaded()
{
_mongo = new Mongo();
_mongo.Connect();
var threadFinishEvents = new List<EventWaitHandle>();
for(var i = 0; i < 50; i++)
{
var threadFinish = new EventWaitHandle(false, EventResetMode.ManualReset);
threadFinishEvents.Add(threadFinish);
var thread = new Thread(delegate()
{
RunMongoThread();
threadFinish.Set();
});
thread.Start();
}
WaitHandle.WaitAll(threadFinishEvents.ToArray());
_mongo.Disconnect();
}
private static void RunMongoThread()
{
for (var i = 0; i < 3000; i++)
{
var db = _mongo.getDB("Sample");
var collection = db.GetCollection("Users");
var user = GetUser(i);
var document = new Document();
document["FirstName"] = user.FirstName;
document["LastName"] = user.LastName;
lock (_mongo) // Lock the connection - not ideal for threading, but safe and seemingly fast
{
collection.Insert(document);
}
}
}
Cosa hai deciso alla fine? Di fronte allo stesso problema ... –
La buona notizia è che non dovevo decidere. I driver Mongodb-csharp e NoRM hanno entrambi aggiunto il supporto per il pool di connessioni. Entrambe le librerie dispongono di meccanismi ben progettati e thread-safe per mettere in comune le connessioni con un processo mongod o mongos. Entrambe le aree aggiungono anche il supporto per i set di repliche nel prossimo futuro. –
@TylerBrinks puoi mostrare un esempio di come puoi inserire documenti da 1m sotto 8 sec? Non riesco a raggiungere quella velocità, su un singolo thread. – IamStalker