Skip to content

ve-ronica/moduleR

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ModuleR Prediction Web Service

Quickstart

Build container, start, and run test. First image build will take some time as Docker downloads the base Ubuntu image. Subsequent builds will use much quicker:

$ make clean image run && sleep 10 && make test
docker kill rapache && docker rm rapache
rapache
rapache
docker build -t myrepo/predict-service:latest .
Sending build context to Docker daemon 365.6 kB
Step 1 : FROM ubuntu
 ---> b549a9959a66
 ....
 
Successfully built eb7446fb1c90
docker run -d --name rapache -p 80:80 myrepo/predict-service:latest
c69975971c4df33272ffac7110af190f52efaad397751779ed7580e57c3d2e47

curl --data 'x1=1&x2=2&x3=3' http://192.168.99.100/predict/test/1
{"score":{"1":12.9322980080557},"status":"Ok","error":"","name":"test","version":1,"date":null}

Rook Testing

A standalone Rook service implementation is provided in src/predictRook.R and can be run without Apache httpd as follows:

  • Start webservice:
$ src/predictRook.R 
Loading required package: Rook
Loading required package: rjson
Loading required package: futile.logger
INFO [2016-04-08 11:50:17] [45109] Starting prediction web service 
INFO [2016-04-08 11:50:17] Loading models from directory ../model
INFO [2016-04-08 11:50:17] [45109] Loaded model test__1 from file ../model/test__1.rds
INFO [2016-04-08 11:50:17] Starting web service
starting httpd help server ... done
DEBUG [2016-04-08 11:50:20] Request for model test, version 1
DEBUG [2016-04-08 11:50:20] Received request (http://127.0.0.1:8000/custom/predict/test/1?) with POST parameters: x1,x2,x3
DEBUG [2016-04-08 11:50:20] Using model test, version 1
DEBUG [2016-04-08 11:50:20] [45109] Using prediction features: x1,x2,x3
DEBUG [2016-04-08 11:50:20] Request (http://127.0.0.1:8000/custom/predict/test/1?) returns: {"score":{"1":12.9322980080557},"status":"Ok","error":"","name":"test","version":1}
  • Test the service:
$ curl --data 'x1=1&x2=2&x3=3' http://127.0.0.1:8000/custom/predict/test/1
{"score":{"1":12.9322980080557},"status":"Ok","error":"","name":"test","version":1}

##Adding a New Model An R model must be prepared before it can be deployed within the fraudscore service. The model object must implement a predict() function as well as have attributes name and version which will be used to identify the model via the webservice REST parameters. The saved RDS model file will be read from the model directory when the service initializes:

> m <- lm(y ~ x1 + x2 + x3)
> predict(m, newdata=data.frame(x1=1, x2=2, x3=3))
    1 
12.93 
> m$name <- 'test'
> m$version <- 1
> saveRDS(m, file="test__1.rds")

Apache Deployment

The fraudscore web service is implementated as a Rook service and deployed under Apache httpd via the RApache (mod_R) module. Below are the steps for deploying the service on Ubuntu Server:

  • Install apache2 and rapache:
$ sudo apt-get install apache2
$ sudo add-apt-repository ppa:opencpu/rapache
$ sudo apt-get update
$ sudo apt-get install libapache2-mod-r-base
  • Install R modules Rook, and dependencies.

  • Configure httpd by linking rapache.conf into the configuration directory:

$ sudo ln -s rapache.conf /etc/apache2/sites/enabled
  • Edit settings in rapache.conf to point to the socure implementation files and set the number of required workers (StartServers and MaxRequestWorkers). The configuration contains settings for the mpm_prefork module necessary to maintain single threaded access to each R model.

  • Restart httpd:

$ sudo service apache2 restart
  • Test rapache configuration here

  • Test fraudscore service via curl:

$ curl --data 'x1=1&x2=2&x3=3' http://127.0.0.1:8000/custom/predict/test/1
{"score":{"1":12.9322980080557},"status":"Ok","error":"","name":"test","version":1}

##Debugging The service writes to various log files that can be used to asses the health of the system and diagnose issues:

  • /var/log/apache2/access.log: logs incoming requests to the webservice. The trailing field is the time taken to service the request in microseconds.

  • /var/log/apache2/error.log: logs Apache and RApache errors messages if there are problems starting the Apache server or unhandled errors in the R service implementation.

  • /tmp/rapache.log: log statements generated by the R service implementation itself. On startup, Apache will fork StartServers child processes, each will create a copy of the R interpreter and load a copy of the model. Each log statement is prefixed with the pid of the child process. This behaviour can be seen in the snippet below:

      INFO [2014-06-25 20:40:15] [13291] Starting fraudscore web service (socure.base=/opt/webservice)
      INFO [2014-06-25 20:40:15] [13292] Starting fraudscore web service (socure.base=/opt/webservice)
      INFO [2014-06-25 20:40:48] [13291] Loaded model from file /opt/webservice/socure_model_predictor.rda
      INFO [2014-06-25 20:40:48] [13292] Loaded model from file /opt/webservice/socure_model_predictor.rda
    

Docker

A Dockerfile can be used to create a fraudscore server image.

Bulding image

$ docker build -t socure/fraudscore .
....
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
socure/fraudscore   latest              e2cad5f170f8        13 seconds ago      627.1 MB

Running container

$ docker run -d --name rapache -p 80:80  socure/fraudscore
...
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                NAMES
eceaac8b4afa        socure/fraudscore   "/usr/sbin/apachectl   23 minutes ago      Up 23 minutes       0.0.0.0:80->80/tcp   rapache

Connecting to Container

$ docker exec -i -t rapache /bin/bash
root@eceaac8b4afa:/# export TERM=xterm
root@eceaac8b4afa:/# tail /tmp/rapache.log 
INFO [2015-06-19 22:17:08] [22][xxx-yyy-zzz] Predicting fraudscore
INFO [2015-06-19 22:17:08] [22][xxx-yyy-zzz] Sending response: {"fraudscore":0.101921292367321,"status":"Ok","error":"","name":"generic","version":"20150527","date":"12:48:06 05/29/15 2015"}
INFO [2015-06-19 22:17:08] [23] Request for model generic, version 20150527
INFO [2015-06-19 22:17:08] [23][xxx-yyy-zzz] Using model generic, version 20150527
INFO [2015-06-19 22:17:08] [23][xxx-yyy-zzz] Predicting fraudscore
INFO [2015-06-19 22:17:08] [23][xxx-yyy-zzz] Sending response: {"fraudscore":0.101921292367321,"status":"Ok","error":"","name":"generic","version":"20150527","date":"12:48:06 05/29/15 2015"}
INFO [2015-06-19 22:17:08] [13] Request for model generic, version 20150527
INFO [2015-06-19 22:17:08] [13][xxx-yyy-zzz] Using model generic, version 20150527
INFO [2015-06-19 22:17:08] [13][xxx-yyy-zzz] Predicting fraudscore
INFO [2015-06-19 22:17:08] [13][xxx-yyy-zzz] Sending response: {"fraudscore":0.101921292367321,"status":"Ok","error":"","name":"generic","version":"20150527","date":"12:48:06 05/29/15 2015"}
root@eceaac8b4afa:/# 

Stopping Container

$ docker kill rapache
rapache

Deleting Container

$ docker rm rapache
rapache

Deploying to Elastic Beanstalk

The fraudscore service can be deployed as a Docker application under AWS Elastic Beanstalk. First an application archive is created using the Makefile. The resulting archive can be uploaded via the AWS Elastic Beanstalk and deployed in the same way as a Java WAR file.

$ git pull
Already up-to-date.
$ make clean fraudscore.zip
rm fraudscore.zip
zip fraudscore.zip Dockerfile fraudscore.R rapache.conf RSourceOnStartup.R fraudscore.logrotate model/generic__1.rds model/generic__20150527.rds model/kabbage__20140711.rds model/transferwise__20150507.rds
  adding: Dockerfile (deflated 62%)
  adding: fraudscore.R (deflated 69%)
  adding: rapache.conf (deflated 59%)
  adding: RSourceOnStartup.R (deflated 48%)
  adding: fraudscore.logrotate (deflated 40%)
  adding: model/generic__1.rds (deflated 1%)
  adding: model/generic__20150527.rds (deflated 1%)
  adding: model/kabbage__20140711.rds (deflated 2%)
  adding: model/transferwise__20150507.rds (deflated 0%)
$ ssh ec2-54-92-162-114.compute-1.amazonaws.com
 _____ _           _   _      ____                       _        _ _
| ____| | __ _ ___| |_(_) ___| __ )  ___  __ _ _ __  ___| |_ __ _| | | __
|  _| | |/ _` / __| __| |/ __|  _ \ / _ \/ _` | '_ \/ __| __/ _` | | |/ /
| |___| | (_| \__ \ |_| | (__| |_) |  __/ (_| | | | \__ \ || (_| | |   <
|_____|_|\__,_|___/\__|_|\___|____/ \___|\__,_|_| |_|___/\__\__,_|_|_|\_\
                                       Amazon Linux AMI

[ec2-user@ip-10-35-205-170 ~]$ sudo docker ps
CONTAINER ID        IMAGE                              COMMAND                CREATED             STATUS              PORTS               NAMES
e3e0c17a520a        aws_beanstalk/staging-app:latest   "/usr/sbin/apachectl   5 hours ago         Up 5 hours          80/tcp              jovial_lumiere

[ec2-user@ip-10-35-205-170 ~]$ sudo docker exec -it e3e0c17a520a /bin/bash
root@e3e0c17a520a:/# tail /tmp/rapache.log 
INFO [2015-06-22 18:24:11] [28] Loaded model transferwise__20150507 from file /opt/webservice/model/transferwise__20150507.rds
INFO [2015-06-22 18:24:11] [28] Starting web service
INFO [2015-06-22 18:24:12] [29] Loaded model transferwise__20150507 from file /opt/webservice/model/transferwise__20150507.rds
INFO [2015-06-22 18:24:12] [29] Starting web service
INFO [2015-06-22 18:24:12] [23] Loaded model transferwise__20150507 from file /opt/webservice/model/transferwise__20150507.rds
INFO [2015-06-22 18:24:12] [23] Starting web service
INFO [2015-06-22 18:24:12] [21] Loaded model transferwise__20150507 from file /opt/webservice/model/transferwise__20150507.rds
INFO [2015-06-22 18:24:12] [21] Starting web service
INFO [2015-06-22 18:24:13] [17] Loaded model transferwise__20150507 from file /opt/webservice/model/transferwise__20150507.rds
INFO [2015-06-22 18:24:14] [17] Starting web service

Using Docker on OSX

TODO: update to DockerMachine

Docker can be used on OSX by using Boot2Docker, a purpose-built virtual machine and associated utility scripts.

  • Create a new Boot2Docker VM. This only needs to be done once:
$ boot2docker init
  • Start the Boot2Docker VM:
$ boot2docker start
Waiting for VM and Docker daemon to start...
.o
Started.
Writing /Users/jkamerman/.boot2docker/certs/boot2docker-vm/ca.pem
Writing /Users/jkamerman/.boot2docker/certs/boot2docker-vm/cert.pem
Writing /Users/jkamerman/.boot2docker/certs/boot2docker-vm/key.pem

To connect the Docker client to the Docker daemon, please set:
    export DOCKER_HOST=tcp://192.168.59.103:2376
    export DOCKER_CERT_PATH=/Users/jkamerman/.boot2docker/certs/boot2docker-vm
    export DOCKER_TLS_VERIFY=1
  • Display the environment variables for the Docker client:
$ boot2docker shellinit
Writing /Users/jkamerman/.boot2docker/certs/boot2docker-vm/ca.pem
Writing /Users/jkamerman/.boot2docker/certs/boot2docker-vm/cert.pem
Writing /Users/jkamerman/.boot2docker/certs/boot2docker-vm/key.pem
    export DOCKER_CERT_PATH=/Users/jkamerman/.boot2docker/certs/boot2docker-vm
    export DOCKER_TLS_VERIFY=1
    export DOCKER_HOST=tcp://192.168.59.103:2376
  • To set the environment variables in your shell do the following:
$ eval "$(boot2docker shellinit)"
Writing /Users/jkamerman/.boot2docker/certs/boot2docker-vm/ca.pem
Writing /Users/jkamerman/.boot2docker/certs/boot2docker-vm/cert.pem
Writing /Users/jkamerman/.boot2docker/certs/boot2docker-vm/key.pem
  • Run the hello-world container to verify your setup.
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from hello-world

a8219747be10: Pull complete 
91c95931e552: Already exists 
hello-world:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.

Digest: sha256:aa03e5d0d5553b4c3473e89c8619cf79df368babd18681cf5daeb82aab55838d
Status: Downloaded newer image for hello-world:latest
Hello from Docker.
This message shows that your installation appears to be working correctly.
  • Use the IP address of the Boot2Docker VM to test the application:
$ echo $DOCKER_HOST
tcp://192.168.59.103:2376
$ curl --data $(cat test/test.post) http://192.168.59.103/fraudscore/generic/20150527
{"fraudscore":0.101921292367321,"status":"Ok","error":"","name":"generic","version":"20150527","date":"12:48:06 05/29/15 2015"}

About

Scalable Prediction Services with R

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • R 51.0%
  • ApacheConf 45.3%
  • Makefile 3.7%