multithreading - threads - ¿Hay una manera de compartir memoria entre los trabajadores/hilos/algo en Node.JS?
threads nodejs (4)
En realidad Node soporta procesos de desove. No estoy seguro de cuán cerca está la bifurcación de Node a la bifurcación real, pero puedes intentarlo:
http://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options
Por cierto: no es cierto que Node no sea adecuado para eso. Es tan adecuado como cualquier otro idioma / servidor web. Siempre puede activar varias instancias de su servidor en diferentes puertos y poner un proxy en frente.
Si necesita más memoria, agregue más memoria. :) Es tan simple como eso. También debe pensar en colocar todos esos datos en una base de datos en memoria dedicada como Redis o Memcached (o incluso Couchbase si necesita consultas complejas). Ya no tendrás que preocuparte por duplicar esos datos.
Tengo una aplicación Node que accede a una estructura de datos estática, grande (> 100M), compleja, en memoria, acepta consultas y luego entrega pequeñas porciones de esos datos al cliente a través de HTTP.
La mayoría de las consultas se pueden responder en décimas de segundo. ¡Hurra por el nodo!
Pero, para ciertas consultas, la búsqueda de esta estructura de datos tarda unos segundos. Esto apesta porque todos los demás tienen que esperar.
Para servir a más clientes de manera eficiente, me gustaría usar algún tipo de paralelismo.
Pero, debido a que esta estructura de datos es tan grande, me gustaría compartirla entre los trabajadores o los subprocesos o lo que sea, para no quemar cientos de megabytes. Esto sería perfectamente seguro, porque la estructura de datos no se va a escribir. Un típico ''fork ()'' en cualquier otro idioma lo haría.
Sin embargo, por lo que puedo decir, todas las formas estándar de hacer paralelismo en Node lo hacen explícitamente imposible. Por seguridad, no quieren que compartas nada.
¿Pero hay una manera?
Fondo:
No es práctico colocar esta estructura de datos en una base de datos, o usar memcached, o algo así.
Las bibliotecas de la API de WebWorker y similares solo permiten que los mensajes serializados cortos se pasen dentro y fuera de los trabajadores.
El clúster de Node utiliza una llamada llamada ''fork'', pero en realidad no es una bifurcación del proceso existente, está generando una nueva. Así que una vez más, no hay memoria compartida.
Probablemente la respuesta realmente correcta sería usar el acceso similar a un sistema de archivos a la memoria compartida, también conocido como tmpfs, o mmap. Hay algunas bibliotecas de nodos que hacen que mount () y mmap () estén disponibles para algo exactamente como esto. Desafortunadamente, uno tiene que implementar un acceso complejo a la estructura de datos sobre búsquedas y lecturas sincrónicas. Mi aplicación utiliza matrices de matrices de dicts y así sucesivamente. Sería bueno no tener que volver a implementar todo eso.
Intenté escribir un enlace C / C ++ de acceso a memoria compartida desde nodejs. https://github.com/supipd/node-shm
Todavía trabajo en progreso (pero trabajando para mí), tal vez sea útil, si hay algún error o sugerencia, infórmeme.
La mayoría de las aplicaciones web pasan la mayor parte de su vida esperando buffers de red y lecturas de bases de datos. Node.js está diseñado para sobresalir en este trabajo encuadernado. Si su trabajo está realmente vinculado por la CPU, es posible que otra plataforma le sirva mejor.
Con eso fuera del camino ...
Use process.nextTick (quizás incluso bloques anidados) para asegurarse de que el costoso trabajo de la CPU sea asincrónico y no esté permitido bloquear su hilo. Esto asegurará que un cliente que haga solicitudes costosas no afecte negativamente a todos los demás.
Use el cluster node.js para agregar un proceso de trabajo para cada CPU en el sistema. Los procesos de trabajo pueden vincularse a un solo puerto HTTP y usar Memcached o Redis para compartir el estado de la memoria. Los trabajadores también tienen una API de mensajería que se puede usar para mantener sincronizada la memoria caché en proceso, sin embargo, tiene algunas limitaciones de coherencia.
construir con waf es de estilo antiguo (nodo 0.6 y debajo), la nueva construcción es con gyp.
Debe consultar el clúster de nodos ( http://nodejs.org/api/cluster.html ). No está claro que esto le va a ayudar sin tener más detalles, pero esto ejecuta varios procesos de nodo en la misma máquina usando fork.