Monday, May 21, 2012

Cuando SAP HANA conocio a R - El primer beso

Si leen mis blogs (y espero que lo hagan) ya saben que realmente amo el lenguaje de programacion R pero tambien amo a SAP HANA y en el pasado he trabajado con integraciones entre los dos:

HANA meets R
R meets HANA
Sanitizing data in SAP HANA with R

Pero...esas integraciones no fueron hechas utilizando la manera de SAP...lo cual significa que no son apoyadas ni aprobadas por SAP...

Felizmente...actualmente, hay una forma oficial de SAP para hacerlo!

Primero, tenemos que leer y seguir las instrucciones detalladas en Get your own SAP HANA DB server on Amazon Web Services por el asombroso Juergen Schmerder. (Creanlo! Me tomo menos de 10 minutos tener mi SAP HANA corriendo en mi laptop...realmente...muy sencillo).

Con nuestro SAP HANA funcionando, podemos dedicar nuestro tiempo a la parte divertida...la parte #R. 

Anda a tu AWS Management Console y bajo Amazon EC2, lanza una nueva instancia...



Tienes que escoger SUSE Linux Enterprise con 32 bit. You intente con 64 bits y no fue divertido...no funciono y perdi mucho tiempo...32 bit FTW!

Para la instalacion, pueden seguir este enlace SAP HANA Database Development Guide – Integration with R programming language, pero en mi caso, tuve que tratar con mucho problemas, que afortunadamente voy a tratar en este blog, para que ustedes no tengan que pasar por lo mismo.

Primero, necesitamos un compilador puesto que vamos a compilar #R desde su codigo fuente.

sudo zypper install gcc gcc-c++ gcc-fortran

Luego necesitamos obtener y extraer el codigo fuente de #R.

wget http://cran.r-project.org/src/base/R-2/R-2.13.0.tar.gz
tar zxf R-2.13.0.tar.gz && cd R-2.13.0
./configure --enable-R-shlib --with-realine=no --with-x=no
make clean
make
make install

Este paso realmente toma mucho tiempo...asi que sera mejor que hagan algo mas productivo mientras tanto.
Cuando #R esta finalmente instalado, necesitamos descargar e instalar el paquete Rserve.

wget http://www.rforge.net/Rserve/snapshot/Rserve_0.6-5.tar.gz

Ahora, tenemos que entrar a R y hacer la instalacion...

R
install.packages("/PATH_TO_FILE/Rserve.tar.gz", repos = NULL)
library("Rserve") #To test the installation. If there's no output, then it's working fine
q()

Si tienes un error sobre una libreria personal...solo dale "y". Una vez que Rserve esta instalada, necesitamos crear un archivo de configuracion.

vi /etc/Rserv.conf
maxinbuf 10000000
Maxsendbuf 0
remote enable
#Press ESC key
:w
#Press ESC key
:q!

Ahora, debemos crear una usuario que ejecutara el Rserve para que podamos conectarnos desde SAP HANA.

useradd -m login_name
passwd login_name

Por alguna razon Amazon no provee el password para el usuario root...pero podriamos necesitarlo en algun momento...asi que hagasmolo...despues de todo, es nuestro usuario y nosotros estamos pagando por el...

sudo passwd root
#Assign a password

Excelente, ya estamos listos para iniciar nuestro servidos! (Necesitas estar logeado como el nuevo usuario que creamos en un paso anterior).

R CMD Rserve --RS-port 6311 --no-save --RS-encoding "utf8"

Ahora...estamos listos para movernos a nuestro servidor de SAP HANA y seguir configurando.

Right click on your system node at the navigator tab
Select Administration
Select on the right hand side the Configuration tab
Select the indexserver.ini
Select the calcengine
 
#Add the following parameters...
 
cer_timeout - 300
cer_rserve_addresses - Our R Amazon server:6311
cer_rserve_maxsendsize - 0

Una cosa mas, y estaremos listos para empezar...anda a tu AWS Management Console, EC2 y luego escoge Security Groups. Nuestro servidor de R va a estar asignado a "Quicklaunch-1". Solo selecionalo y escoge Inbound. Y agrega el puerto "6311".


Esto es todo amigos!...estamos oficialmente listo para comenzar! En SAP HANA, creamos una tabla y la llamamos TICKETS_BY_YEAR con la siguiente estructura:


Abre un editor de SQL y copia el siguiente codigo...

insert into "SYSTEM"."TICKETS_BY_YEAR" values('20110101',4195);
insert into "SYSTEM"."TICKETS_BY_YEAR" values('20110201',4245);
insert into "SYSTEM"."TICKETS_BY_YEAR" values('20110301',4971);
insert into "SYSTEM"."TICKETS_BY_YEAR" values('20110401',4469);
insert into "SYSTEM"."TICKETS_BY_YEAR" values('20110501',4257);
insert into "SYSTEM"."TICKETS_BY_YEAR" values('20110601',4973);
insert into "SYSTEM"."TICKETS_BY_YEAR" values('20110701',4470);
insert into "SYSTEM"."TICKETS_BY_YEAR" values('20110801',4981);
insert into "SYSTEM"."TICKETS_BY_YEAR" values('20110901',4530);
insert into "SYSTEM"."TICKETS_BY_YEAR" values('20111001',4167);
insert into "SYSTEM"."TICKETS_BY_YEAR" values('20111101',4059);
insert into "SYSTEM"."TICKETS_BY_YEAR" values('20111201',1483);

Esta tabla se supone que guarda la ventas en tickets para una empresa X, durante cada mes del 2011. Lo que queremos hacer aqui es determinar o predecir como estaran nuestras ventas en el 2012. Vamos a utilizar #R para lograrlo. Creamos el siguiente script y lo llamamos "Predict_Tickets". Este script tendra dos Stored Procedures, llamados Prediction_Model y Get_Tickets.

CREATE TYPE T_PREDICTION_TICKETS AS TABLE (
PERIOD VARCHAR(8),
TICKETS INTEGER
);
 
DROP PROCEDURE Prediction_Model;
DROP PROCEDURE Get_Tickets;
 
CREATE PROCEDURE Prediction_Model(IN tickets_year TICKETS_BY_YEAR,OUT result T_PREDICTION_TICKETS)
LANGUAGE RLANG AS
BEGIN
period=as.integer(tickets_year$PERIOD)
tickets=as.integer(tickets_year$TICKETS)
var_year=as.integer(substr(period[1],1,4))
var_year=var_year+1
new_period=gsub("^\\d{4}",var_year,period)
next_year=data.frame(year=new_period)
prt.lm<-lm(tickets ~ period)
pred=round(predict(prt.lm,next_year,interval="none"))
result<-data.frame(PERIOD=new_period,TICKETS=pred)
END;
 
CREATE PROCEDURE Get_Tickets()
LANGUAGE SQLSCRIPT AS
BEGIN
Tickets = SELECT * FROM TICKETS_BY_YEAR;
CALL Prediction_Model(:Tickets,T_PREDICTION_TICKETS);
INSERT INTO "TICKETS_BY_YEAR" SELECT * FROM :T_PREDICTION_TICKETS;
END;
 
CALL Get_Tickets();
SELECT * FROM "TICKETS_BY_YEAR";

Como pueden ver, nuestro primer Stored Procedure llamado Prediction_Model, estamos utilizando RLANG como el lenguaje script...lo cual significa que vamos a incluir codigo R que va a ir de nuestro servidor de SAP HANA a nuestro servidor de R y luego de vuelta con la informacion modificada. Prediction_Model esta llamando al Stored Procedure Get_Tickets, el cual esta haciendo un select a la tabla TICKETS_BY_YEAR y luego llamando a Prediction_Model para finalmente insertar la data de vuelta en SAP HANA. Al final de nuestro script, llamamos a Get_Tickets y hacemos un select  a TICKETS_BY_YEAR para verificar que nuestro script funciono.


Exito! Nuestra integracion de SAP HANA y R funciono de maravilla! Nunca dejamos el SAP HANA Studio, pero nuestro codigo se fue al servidor de R y regreso trayendonos la informacion modificada...todo en solo 829 milliseconds...realmente veloz considerando que ambos servidores estan el nube...eso es todo por ahora...regresare con mas informacion sobre SAP HANA y R apenas pueda...aun hay mucho por descubrir y probar.

Saludos,

Blag.

No comments: