深入理解SAP HANA与R整合的原理(一)
从本篇文章开始,本人将深入挖掘SAP HANA与R语言整合的具体原理,之所以选择这个主题,很大程度上是因为从SAP D-code大会回来之后,发现有很多相关的应用,尤其是数据分析及预测任务应用到了R, 所以想深入研究一下背后的原理.所以这个系列的文章要求读者了解R语言,并且尝试过与SAP HANA进行整合.相关的文档可以参考https://help.sap.com/hana/SAP_HANA_R_Integration_Guide_en.pdf, 另外可以参考本人的令一篇文章,
通过这个系列的文章,将向大家揭示SAP HANA与R之间的一个双向数据流的具体步骤, 这样在SAP HANA中使用R语言编写与运行存储过程的时候,理解其中的原理, 将有助于编写的存储过程更加高效, 出现问题的时候也知道该如何去分析原因,查看监控日志,对于有更高需要的用户,甚至可以把R语言整合到你的任何应用中去(当然前提是你的应用中支持TCP/IP通信).
(一) 嵌入式R语言执行环境
在本篇文章中,将介绍一些嵌入式R语言的基础,后续文章再继续揭秘SAP HANA是如何执行R代码的.
SAP HANA能够与R语言整合,在很大程度是因为R语言本身支持一个嵌入式的运行环境.也就是说,你可以把R代码嵌入到C代码中去执行.这当然依赖于R语言在安装的时候安装的一些库.
在R语言的安装目录下(本机:/usr/local/lib64/R),有些头文件,提供了一些函数的原型,还有一个libR.so文件,这是R语言库的动态链接库. 有了这些文件的支持,就可以在C语言中直接嵌入R语言代码了,下面以例子来说明.
#include <stdio.h>
#include "Rembedded.h" //包含头文件
#include "Rdefines.h"
int main(){
char *argv[] = {
"REmbeddedPostgres", "--gui=none", "--silent" //参数
};
int argc = sizeof(argv)/sizeof(argv[0]);
Rf_initEmbeddedR(argc, argv);
SEXP e;
SEXP fun;
SEXP arg;
int i;
fun = Rf_findFun(Rf_install("print"), R_GlobalEnv);
PROTECT(fun);
arg = NEW_INTEGER(10);
for(i = 0; i < GET_LENGTH(arg); i++)
INTEGER_DATA(arg)[i] = i + 1;
PROTECT(arg);
e= allocVector(LANGSXP, 2);
PROTECT(e);
SETCAR(e, fun);
SETCAR(CDR(e), arg);
/* Evaluate the call to the R function.Ignore the return value. */
eval(e, R_GlobalEnv);
UNPROTECT(3);
return 0;
}
这段代码不是太看好,主要是一些R语言内核定义的一些函数与宏. 主要的过程涉及到调用Rf_initEmbeddedR(argc, argv),初使化一个嵌入式的运行环境,SEXP是一个指针,指向R语言内部的一些数据结构(相关的结构及更多的函数参考R语言源代码R-2.15.0/src/main),然后安义了一个arg数组,初始化为1到10,最后安装了一个print函数,最后调用eval函数来执行R代码.
我们编译一下上面的代码:
gcc embed.c -I/usr/local/lib64/R/include -L/usr/local/lib64/R/lib -lR
-I参数指定头文件件路径,-L参数指定动态链接库路径,-lR指定链接libR.so这个库文件.
可以看出,这个结果和R语言的运行结果很相似.
由此作为启发,基于嵌入式的R语言运行环境,我们可以自己建立一个R语言的服务器,作为一个TCP/IP的服务器端,接受客户端通过TCP/IP发过来的请求,然后在服务器端执行R代码,再把执行结果返回给客户端. 这便是Rserve这个扩展包的开发初衷.
以上便是SAP HANA与R语言能够整合在一起的一个基础.
(二) Rserve介绍
有了以上的基础, Rserve在2003年10月份的时候就诞生了,到2013年最新发布的Rserve 1.7-3,差不多刚好10年的时间.作者是Simon Urbanek ,现在是AT&T labs的一名研究员,主要做统计相关的一些研究工作,更多介绍见http://simon.urbanek.info/. 有关Rserve的更多信息请参考http://www.rforge.net/Rserve/, 同时该网站提供Rserve相关的服务器端与客户端下载.服务器端 由纯C语言实现, 用来接受客户的请求,数据,进行计算,然后把结果返回给客户端. 客户端提供C++与java还有php的版本. 值得一提的是, 作者发布的C++接口只是提供了最基本的功能,还并不完善,用作者自己的话说, “This C++ interface is experimental and does not come in form of a library,” 也就是说只是实验性质的,而且作者本人也不用这个C++的接口, 而且只支持R中最基本的比如lists,vectors,doubles这些数据类型,对于其他的一些类型如果需要还得自己实现, “Look at the sources to see how to implement other types if necessary”
在SAP HANA的R客户端中,也是用C++进行实现的,不过这个实现比作者自己提供的那个C++接口要复杂得多. 当然,理论上,只要有TCP/IP协议的支持,你可以用任何语言去实现自己的Client.
(三) 面向消息的通信协议QAP1
Rserve跟客户端的通信协议采用QAP1(quad attributes protocol v1). 基于这种面向消息的协议, 客户端首先发送一个消息,然后等待接受服务器端的响应消息. 消息中必须包含具体的动作,及相关的一些附属数据信息. 服务器的响应消息包含响应代码及结果数据. 每个消息都包含一个消息头部分与数据部分. 每个消息头大小为16个byte. 消息头的结构如下:
Offset type meaning
[0] (int) 指定请求或者响应的类型
[4] (int) 指定消息的长度(0到31bit)
[8] (int) 指定数据部分的偏移量
[12] (int) 指定消息的长度(32到63bit)
消息的数据部分可以包含一些附加参数, 比如DT_INT,DT_STRING等类型的参数.具体参考Rsrv.h
当前Rserve支持的一些命令如下:
command parameters | response data
CMD_login DT_STRING | –
CMD_voidEval DT_STRING | –
CMD_eval DT_STRING or | DT_SEXP
DT_SEXP
CMD_shutdown [DT_STRING] | –
CMD_openFile DT_STRING | –
CMD_createFile DT_STRING | –
CMD_closeFile – | –
CMD_readFile [DT_INT] | DT_BYTESTREAM
CMD_writeFile DT_BYTESTREAM | –
CMD_removeFile DT_STRING | –
CMD_setSEXP DT_STRING, | –
DT_SEXP
CMD_assignSEXP DT_STRING, | –
DT_SEXP
CMD_setBufferSize DT_INT | –
CMD_setEncoding DT_STRING | – (since 0.5-3)
since 0.6:
CMD_ctrlEval DT_STRING | –
CMD_ctrlSource DT_STRING | –
CMD_ctrlShutdown – | –
since 1.7:
CMD_switch DT_STRING | –
CMD_keyReq DT_STRING | DT_BYTESTREAM
CMD_secLogin DT_BYTESTREAM | –
CMD_OCcall DT_SEXP | DT_SEXP
实用最多的一个command是CMD_eval. 这个命令的作用就是根据接受到的一符合R语言语法的字符串,对它进行语法解析,然后计算运行,得出结果,然后再发回响应消息.
其实如果能够直接在SAP HANA内部运行R程序,基于嵌入式R,在技术上是可行的也是简单的,而且性能上会更好,但是很遗憾因为开源软件的版权问题不能直接这么做.
本篇文章的介绍先到此结束,在后续的文章中我再介绍Rserve的运行机制及SAP HANA中具体如何与Rserve进行通信的. 了解这些原理,对于优化Rserve,获得更高的性能,是有必要的. 因为Rserve是开源的,如果对底层细节胸有成竹的话,可以自己对Rserve进行改进,达到自己的需求.
想获取更多SAP HANA学习资料或有任何疑问,请关注新浪微博@HANAGeek!我们欢迎你的加入!
转载本文章请注明作者和出处http://scn.sap.com/community/chinese/hana/blog/2014/04/13/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3sap-hana%E4%B8%8Er%E6%95%B…,请勿用于任何商业用途。