He estado jugando con MongoDB recientemente (Es INCREÍBLEMENTE RÁPIDO) usando el controlador C# en GitHub. Todo está funcionando bien en mi pequeña aplicación de consola única con la que estoy probando. Puedo agregar 1,000,000 de documentos (sí, millones) en menos de 8 segundos con un solo subproceso. Solo obtengo este rendimiento si uso la conexión fuera del alcance de un ciclo for. En otras palabras, mantengo la conexión abierta para cada inserción en lugar de conectarla para cada inserción. Obviamente eso es artificial..NET mejores prácticas para conexiones MongoDB?
Pensé en subirlo un poco para ver cómo funciona con múltiples hilos. Estoy haciendo esto porque necesito simular un sitio web con múltiples solicitudes simultáneas. Estoy girando entre 15 y 50 hilos, insertando un total de 150,000 documentos en todos los casos. Si solo dejo que los subprocesos se ejecuten, cada uno creando una nueva conexión para cada operación de inserción, el rendimiento se detiene.
Obviamente necesito encontrar una manera de compartir, bloquear o poner en común la conexión. Ahí radica la pregunta. ¿Cuál es la mejor práctica en términos de conexión a MongoDB? ¿Debería mantenerse la conexión abierta durante la vida de la aplicación (hay una latencia sustancial abriendo y cerrando la conexión TCP para cada operación)?
¿Alguien tiene experiencia en el mundo real o en la producción con MongoDB, y específicamente la conexión subyacente?
Aquí está mi muestra de subprocesamiento utilizando una conexión estática que está bloqueada para operaciones de inserción. ¡Ofrezca sugerencias que maximicen el rendimiento y la confiabilidad en un contexto 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);
}
}
}
¿Qué decidieron al final? Enfrentando el mismo problema ... –
La buena noticia es que no tuve que decidir. Los controladores Mongodb-csharp y NoRM agregaron soporte para la agrupación de conexiones. Ambas bibliotecas tienen mecanismos bien diseñados y seguros para las conexiones de agrupamiento contra un proceso mongod o mongos. Ambas áreas también agregan compatibilidad con conjuntos de réplicas en el futuro cercano. –
@TylerBrinks ¿puede mostrar un ejemplo de cómo puede insertar documentos de 1 m en 8sec? No puedo alcanzar esa velocidad en un solo hilo. – IamStalker