Skip to Content

      从本篇文章开始,本人将深入挖掘SAP HANA与R语言整合的具体原理,之所以选择这个主题,很大程度上是因为从SAP D-code大会回来之后,发现有很多相关的应用,尤其是数据分析及预测任务应用到了R,  所以想深入研究一下背后的原理.所以这个系列的文章要求读者了解R语言,并且尝试过与SAP HANA进行整合.相关的文档可以参考https://help.sap.com/hana/SAP_HANA_R_Integration_Guide_en.pdf, 另外可以参考本人的令一篇文章,

http://scn.sap.com/community/chinese/hana/blog/2014/02/14/r%E8%AF%AD%E8%A8%80%E5%8C%85%E5%AE%89%E8%A3%85%E5%B9%B6%E5%AE%…

       通过这个系列的文章,将向大家揭示SAP HANA与R之间的一个双向数据流的具体步骤, 这样在SAP HANA中使用R语言编写与运行存储过程的时候,理解其中的原理, 将有助于编写的存储过程更加高效, 出现问题的时候也知道该如何去分析原因,查看监控日志,对于有更高需要的用户,甚至可以把R语言整合到你的任何应用中去(当然前提是你的应用中支持TCP/IP通信).


(一)   嵌入式R语言执行环境

      在本篇文章中,将介绍一些嵌入式R语言的基础,后续文章再继续揭秘SAP HANA是如何执行R代码的.

      SAP HANA能够与R语言整合,在很大程度是因为R语言本身支持一个嵌入式的运行环境.也就是说,你可以把R代码嵌入到C代码中去执行.这当然依赖于R语言在安装的时候安装的一些库.

QQ截图20140413175009.png

在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这个库文件.

QQ截图20140413185129.png

       可以看出,这个结果和R语言的运行结果很相似.

       由此作为启发,基于嵌入式的R语言运行环境,我们可以自己建立一个R语言的服务器,作为一个TCP/IP的服务器端,接受客户端通过TCP/IP发过来的请求,然后在服务器端执行R代码,再把执行结果返回给客户端. 这便是Rserve这个扩展包的开发初衷.

       以上便是SAP HANA与R语言能够整合在一起的一个基础.


() Rserve介绍

          有了以上的基础, Rserve200310月份的时候就诞生了,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 HANAR客户端中,也是用C++进行实现的,不过这个实现比作者自己提供的那个C++接口要复杂得多. 当然,理论上,只要有TCP/IP协议的支持,你可以用任何语言去实现自己的Client.

() 面向消息的通信协议QAP1

 

       Rserve跟客户端的通信协议采用QAP1(quad attributes protocol v1). 基于这种面向消息的协议, 客户端首先发送一个消息,然后等待接受服务器端的响应消息. 消息中必须包含具体的动作,及相关的一些附属数据信息. 服务器的响应消息包含响应代码及结果数据. 每个消息都包含一个消息头部分与数据部分. 每个消息头大小为16byte. 消息头的结构如下:

                                  Offset                      type                 meaning

                [0]              (int)       指定请求或者响应的类型

                [4]              (int)       指定消息的长度(031bit)

                [8]              (int)       指定数据部分的偏移量

                [12]             (int)       指定消息的长度(3263bit)

       消息的数据部分可以包含一些附加参数, 比如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

        实用最多的一个commandCMD_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…,请勿用于任何商业用途。

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply