node.js - tutorial - Problemas de rendimiento de NodeJS+Mongodb
node js tutorial (2)
Dzhu, un montón de cosas:
¿Intentaste esta consulta desde el shell mongo? ¿Puedes intentar ejecutarlo en el shell y también usar la función .explain () para tener una idea del tiempo de ejecución del servidor? Esto le ayudará a verificar que su índice es correcto y debería ayudar a aislar si el problema de rendimiento está en el lado del cliente o del lado del servidor.
¿Tienes escrituras pasando al mismo tiempo? ¿Es este fragmento de código que proporcionó la única carga de trabajo para la base de datos mientras se está ejecutando su punto de referencia o hay más cosas al mismo tiempo?
Use la utilidad mongostat (vea documentos mongodb) mientras se ejecuta su punto de referencia. Esto le dará una idea de lo que el servidor está haciendo en tiempo real. En particular, observe el bloqueo% y las columnas qr / qw. Las columnas qr / qw le dicen cuántas operaciones de lectura + escritura están en cola (es decir, bloqueadas y en espera de ejecución).
Tenga en cuenta que al activar el perfilador del servidor mongo en el nivel 2 (- perfil = 2), el servidor registrará TODAS las operaciones, lo que afectará gravemente el rendimiento de la base de datos. Utilice --profile = 1 para registrar solo las operaciones más lentas que las lentas. Luego, una vez que haya finalizado su prueba, mire los contenidos de db.system.profile para obtener detalles sobre cualquier operación lenta que el servidor haya ejecutado.
Esto debería ayudarte a empezar.
Tengo una aplicación nodejs + mongodb que se conecta así:
var dbConfig = new mongo.Server(config.db.host, config.db.port, {auto_reconnect: true, poolSize: 20});
var db = new mongo.Db(config.db.name, dbConfig);
cuando se hizo una evaluación comparativa (usando apache ab), se encontró que tiene problemas (tiempo> = 1 seg) cuando las conexiones concurrentes son> 20 (incluso 2 o más conexiones concurrentes parecen aumentar los tiempos linealmente):
[
{
"key": "mongoQuery1",
"min": 2,
"max": 598,
"mean": 387.60683760683764,
"sd": 134.56045668980255,
"variance": 18106.51650456823
},
{
"key": "mongoQuery2",
"min": 8,
"max": 149,
"mean": 73.14120370370358,
"sd": 25.141715811881994,
"variance": 632.1058739654371
},
...
]
Lo anterior es la salida del servidor de perfiles que utilicé para capturar información de perfiles de la aplicación del nodo. Básicamente, he puesto cosas como esta para perfilar la aplicación:
var start = new Date().getTime();
db.collection(''TheCollection'', query, function(err, col) {
col.find(query).toArray(function(err, items) {
var elapsed = new Date().getTime() - start;
profiler.send(''mongoQuery1'', elapsed);
});
});
Tenga en cuenta que el tamaño de la colección es mínimo (700 registros) y todas las colecciones se indexan de acuerdo con las consultas.
Me quedo sin ideas, ¿alguien tiene idea de por qué el rendimiento es tan malo?
EDITAR:
para una consulta simple como:
db.user_permission.find({ username: ''a'', permission_type: ''vehicle''})
con el user_permission teniendo el índice:
db.user_permission.ensureIndex({username: 1, permission_type: 1});
El tiempo aumenta linealmente con usuarios concurrentes.
Editar 2
Intenté activar el perfilado para mongod (--profile = 2 --slowms = 100)
cada vez que ejecuto ab contra él, la db se corrompe, con lo siguiente en los registros mongod:
Wed Nov 21 10:41:54 [conn4] creating profile collection: knightsbridge.system.profile
Wed Nov 21 10:41:54 [FileAllocator] allocating new datafile /Users/dzhu/data/mongodb/knightsbridge.ns, filling with zeroes...
Wed Nov 21 10:41:54 [FileAllocator] creating directory /Users/dzhu/data/mongodb/_tmp
Wed Nov 21 10:41:54 [FileAllocator] done allocating datafile /Users/dzhu/data/mongodb/knightsbridge.ns, size: 16MB, took 0.018 secs
Wed Nov 21 10:41:54 [FileAllocator] allocating new datafile /Users/dzhu/data/mongodb/knightsbridge.0, filling with zeroes...
Wed Nov 21 10:41:54 [FileAllocator] done allocating datafile /Users/dzhu/data/mongodb/knightsbridge.0, size: 64MB, took 0.152 secs
Wed Nov 21 10:41:54 [conn5] Assertion: 10334:Invalid BSONObj size: 0 (0x00000000) first element: EOO
0x10037637b 0x1000afc2e 0x1000b005c 0x10001ea53 0x100233529 0x1002a9b0b 0x1001a0a9f 0x10069518b 0x1002a2a4e 0x1005ca15e 0x10064a0ca 0x100018681 0x10019302c 0x1005a7823 0x7fff8a42f8bf 0x7fff8a432b75
0 mongod 0x000000010037637b _ZN5mongo15printStackTraceERSo + 43
1 mongod 0x00000001000afc2e _ZN5mongo11msgassertedEiPKc + 206
2 mongod 0x00000001000b005c _ZN5mongo11msgassertedEiRKSs + 12
3 mongod 0x000000010001ea53 _ZNK5mongo7BSONObj14_assertInvalidEv + 1475
4 mongod 0x0000000100233529 _ZN5mongo13unindexRecordEPNS_16NamespaceDetailsEPNS_6RecordERKNS_7DiskLocEb + 265
5 mongod 0x00000001002a9b0b _ZN5mongo11DataFileMgr12deleteRecordEPKcPNS_6RecordERKNS_7DiskLocEbbb + 587
6 mongod 0x00000001001a0a9f _ZN5mongo16NamespaceDetails11cappedAllocEPKci + 1535
7 mongod 0x000000010069518b _ZN5mongo16NamespaceDetails5allocEPKciRNS_7DiskLocE + 123
8 mongod 0x00000001002a2a4e _ZN5mongo11DataFileMgr17fast_oplog_insertEPNS_16NamespaceDetailsEPKci + 126
9 mongod 0x00000001005ca15e _ZN5mongo7profileERKNS_6ClientERNS_5CurOpE + 3134
10 mongod 0x000000010064a0ca _ZN5mongo16assembleResponseERNS_7MessageERNS_10DbResponseERKNS_11HostAndPortE + 4010
11 mongod 0x0000000100018681 _ZN5mongo16MyMessageHandler7processERNS_7MessageEPNS_21AbstractMessagingPortEPNS_9LastErrorE + 257
12 mongod 0x000000010019302c _ZN5mongo3pms9threadRunEPNS_13MessagingPortE + 1084
13 mongod 0x00000001005a7823 thread_proxy + 163
14 libsystem_c.dylib 0x00007fff8a42f8bf _pthread_start + 335
15 libsystem_c.dylib 0x00007fff8a432b75 thread_start + 13
versión mongod:
mongod --version
db version v2.2.0, pdfile version 4.5
Wed Nov 21 10:47:24 git version: f5e83eae9cfbec7fb7a071321928f00d1b0c5207
también
Aparte del conjunto de controladores nodejs predeterminado de 1, ¿mongod coloca restricciones en el número de conexiones simultáneas permitidas?
Para usar mongo db y node js encontré un problema con la documentación https://docs.mongodb.com .
Esto funcionó para mí:
Para establecer el nivel de perfil:
const set = await db.setProfilingLevel(''all'')
Para leer el perfil:
código
function profile (db, limit = 10) {
const mc = db
return new Promise((resolve, reject) => {
mc.collection(''system.profile'').find().limit(limit)
.sort({ ts: -1 }).toArray((err, res) => {
if (err) return reject(err)
resolve(!!res && !!res[0] && res)
})
})
}