2016-08-01 3 views
2

Je voudrais utiliser le paquet plombier pour effectuer un traitement parallèle flexible et espérait qu'il fonctionnerait dans un cadre node.js tel qu'il ne soit pas bloquant ...R paquet de plombier pour le traitement parallèle node.js

J'ai le fichier plombier suivant.

# myfile.R 

#* @get /mean 
normalMean <- function(samples=10){ 
    Sys.sleep(5) 
    data <- rnorm(samples) 
    mean(data) 
} 

J'ai aussi installé PM2 comme le suggère ici http://plumber.trestletech.com/docs/hosting/

J'ai aussi fait le même fichier run-myfile.sh-à-dire

#!/bin/bash 
R -e "library(plumber); pr <- plumb('myfile.R'); pr\$run(port=4000)" 

et rendu exécutable comme l'a suggéré ...

I ont démarré pm2 en utilisant

pm2 start /path/to/run-myfile.sh 

et je voulais tester pour voir si elle pouvait réaliser un cadre node.js non bloquant ...

en ouvrant une autre console de R et exécutant la commande suivante ...

foo <- function(){ 
    con <- curl::curl('http://localhost:4000/mean?samples=10000',handle = curl::new_handle()) 
    on.exit(close(con)) 
    return(readLines(con, n = 1, ok = FALSE, warn = FALSE)) 
} 

system.time(for (i in seq(5)){ 
    print(foo()) 
}) 

Peut-être est ma mauvaise compréhension de la façon dont un cadre non-bloquant node.js est censé fonctionner, mais dans ma tête la dernière boucle ne devrait prendre qu'un peu plus de 5 secondes. Mais il semble prendre 25 secondes, suggérant que tout est séquentiel plutôt que parallèle.

Comment est-ce que je pourrais utiliser l'ensemble de plombier pour effectuer cette nature non-bloquante?

Répondre

2

pm2 ne peut malheureusement pas équilibrer les processus R pour vous. R est monothread et n'a pas vraiment de bibliothèques qui lui permettent de se comporter de façon asynchrone comme NodeJS (pour l'instant), il n'y a donc pas beaucoup de bonnes façons de paralléliser le code comme ça dans les plombiers aujourd'hui. La meilleure option serait d'exécuter plusieurs back-ends R de plombier et de répartir le trafic entre eux. Voir la section "load balancing" ici: http://plumber.trestletech.com/docs/docker-advanced

+1

Il y a une discussion en cours ici, ce qui serait le meilleur endroit pour continuer la conversation: https://github.com/trestletech/plumber/issues/31 –

0

Fondamentalement les requêtes concurrentes sont mises en file d'attente par httpuv afin qu'elles ne soient pas performantes par elles-mêmes. L'auteur recommande plusieurs conteneurs docker, mais il peut être compliqué et exigeant en termes de réponse.

Il existe d'autres technologies, par exemple Rserve et rApache. Rserve forks prosess et il est possible de configurer rApache en pré-fork afin de gérer les requêtes simultanées.

Voir les messages suivants pour la comparaison

https://www.linkedin.com/pulse/api-development-r-part-i-jaehyeon-kim/ https://www.linkedin.com/pulse/api-development-r-part-ii-jaehyeon-kim/