轻量级可嵌入多维分析后台

问题的提出

多维分析(BI)系统后台数据源一般有三种选择。1、普通数据库;2、专业数据仓库;3、BI 系统自带的数据源。前端

可是,这三种选择都有各自的问题。普通数据库通常都是行式存储,很难得到多维分析但愿的高性能,只适用较小数据量。专业数据仓库有很多是列式存储的,性能问题不大,可是价格都比较昂贵,建设、扩展和维护成本也都很是高。BI 系统自带的数据源都比较封闭,只能为自家的 BI 前端提供支持,没法为多个不一样厂家的前端提供数据服务。java

解决思路与过程

集算器能够独立承担轻量级多维分析后台的做用,至关于中小型数据仓库或者数据集市。结构图以下:

集算器能够将多维分析的数据事先以列存形式存储到二进制文件中,称为组表。多维分析前端应用拖拽生成 SQL,经过集算器 JDBC 提交。集算器对组表执行 SQL 查询,将结果返回给多维分析前端。组表文件也可由集算器从各类异构数据源采集数据并计算而来。linux

和普通数据库方案相比,集算器列存的二进制文件可以直接提高性能。而对于昂贵的专业数据库和相对封闭的 BI 自带数据源,集算器能够提供更加经济、简便的解决方案,并可以从各类异构数据源采集数据。web

集算器有三种部署方式:一、集成在前端应用中;二、独立服务器;三、集群热备。下面介绍具体方法。sql

案例场景说明

在下面的案例中,多维分析系统要针对订单数据作自助分析。为了简化起见,多维分析系统前台用 tomcat 服务器中的 jdbc.jsp 来模拟。Tomcat 安装在 windows 操做系统的 C:\tomcat6。数据库

集算器 JDBC 集成在多维分析应用中。jdbc.jsp 模仿多维分析应用系统,产生符合集算器规范的 SQL,经过集算器 JDBC 提交给集算器 SPL 脚本处理。windows

多维分析系统的数据来自于生产数据库 demo 中的 ORDERS 表,生产库是 ORACLE 数据库。多维分析系统不能直接连 demo 数据库实现分析,以避免给生产数据库带来过多的压力。ORDERS 订单表是全量数据,集算器 ETL 天天将当天的最新数据同步到组表文件中。日期以订购日期 ORDERDATE 为准,假设当前的日期是 2015-07-18。浏览器

后台数据初始化

用下面的 ordersAll.sql 文件在 ORACLE 数据库中完成 ORDERS 表的建表和数据初始化。缓存

ordersAlltomcat

数据截止到 2017 年 7 月 17 日。

多维分析系统后台上线初始化的时候,要将 ORDERS 表中的历史数据同步到集算器的二进制文件中。这是上线前一次性执行的准备工做,上线运行后就不须要执行了。

在集算器中,新建一个数据源 orcl,链接 ORACLE 数据库。用 SPL 语言脚本 etlAll.dfx 将所有数据读取到集算器组表文件 orders.ctx 中。SPL 脚本以下:

A B
1 =connect(“orcl”) =A1.cursor@d(“select ORDERDATE,CUSTOMERID,EMPLOYEEID,ORDERID,AMOUNT from ORDERS order by ORDERDATE,CUSTOMERID,EMPLOYEEID,ORDERID”)
2 =file(“C:/tomcat6/webapps/DW/WEB-INF/data/orders.ctx”)
3 =A2.create(#ORDERDATE,#CUSTOMERID,#EMPLOYEEID,#ORDERID,AMOUNT)
4 =A3.append(B1) >A1.close()

Orders.ctx 是组表文件,默认是采用列式存储的,支持任意分段的并行计算,能够有效提高查询速度。生成组表的时候,要注意数据预先排序和合理定义维字段。本例中,按照常常过滤、分组的字段,将维字段肯定为:ORDERDATE,CUSTOMERID,EMPLOYEEID, ORDERID。

从 ORACLE 中取得数据的时候,要按照维字段排序。由于 ORDERDATE,CUSTOMERID,EMPLOYEEID 对应的重复数据多,因此放在前面排序;ORDERID 对应的重复数据少,因此放在后面排序。

B1 单元格中数据库游标的 @d 选项,表示从 ORACLE 数据库中取数的时候将 numeric 型数据转换成 double 型,精度对于金额这样的常见数值彻底足够了。若是没有这个选项就会默认转换成 big decimal 型数据,计算性能会受到较大影响。

ETL 过程

多维分析系统上线以后,要天天晚上定时同步当天最新的数据。咱们假设当天日期是 2015-07-18。用下面的 ordersUpdate.sql 文件在 ORACLE 数据库给 ORDERS 表增长当天的数据,模拟数据的增量。

ordersUpdate

用 SPL 语言脚本 etlUpdate1.dfx 将当天数据增量补充到集算器组表文件 orders.ctx 中。SPL 脚本以下:

A B C
1 =connect(“orcl”)
2 =A1.cursor@d(“select ORDERDATE,CUSTOMERID,EMPLOYEEID,ORDERID,AMOUNT from ORDERS where ORDERDATE=? order by ORDERDATE,CUSTOMERID,EMPLOYEEID,ORDERID”,etlDate)
3 =file(“C:/tomcat6/webapps/DW/WEB-INF/data/orders.ctx”)
4 =A3.create() =A4.append(A2) =A3.rollback()
5 >A1.close()

etlUpdate.dfx 的输入参数是 etlDate,也就是须要新增的当天日期。

B4 单元格直接将新数据追加到组表文件中。由于第一个排序字段是 orderdate,因此追加新数据不会影响排序。若是第一个排序字段不是 orderdate,就要从新排序。

C4 中的 rollback 是回滚函数,若 B4 执行 append 过程当中,出现错误,那么将执行回滚操做,恢复到 append 操做以前的组表状态。正常执行完毕,则不会回滚。

etlUpdate1.dfx 脚本能够用 windows 或者 linux 命令行的方式执行,结合定时任务,能够定时执行。也能够用 ETL 工具来定时调用。

windows 命令行的调用方式是:

C:\Program Files\raqsoft\esProc\bin>esprocx.exe C: \etlUpdate1.dfx

linux 命令是:

/raqsoft/esProc/bin/esprocx.sh /esproc/ etlUpdate1.dfx

应用结构一:应用集成计算

集算器 JDBC 集成在多维分析的应用中,接收到 SQL 后查本地文件 orders.ctx 返回结果。

一、下面压缩文件中的 DW 目录复制到 tomcat 的应用目录。

DW

目录结构以下图:

配置文件在 classes 中,在官网上获取的受权文件也要放在 classes 目录中。集算器的 Jar 包要放在 lib 目录中(须要哪些 jar 请参照集算器教程)。

修改 raqsoftConfig.xml 中的主目录配置:

<mainPath>C:\\tomcat6\\webapps\\DW\\WEB-INF\\data</mainPath>

配置好主目录后,orders.ctx 就能够不写全路径名,直接写 from orders.ctx 便可。

二、编辑 DW 目录中的 jdbc.jsp,模拟前台界面提交 sql 展示结果。

<%@ page language=”java” import=”java.util.*” pageEncoding=”utf-8″%>

<%@ page import=”java.sql.*” %>

<body>

<%

String driver = “com.esproc.jdbc.InternalDriver”;

String url = “jdbc:esproc:local://”;

try {

Class.forName(driver);

Connection conn = DriverManager.getConnection(url);

Statement statement = conn.createStatement();

String sql =”select top 10 ORDERID,CUSTOMERID,EMPLOYEEID,ORDERDATE,AMOUNT from ORDERS.ctx where ORDERDATE=date(‘2015-07-18’) and AMOUNT>100″;

out.println(“Test page v1<br><br><br><pre>”);

out.println(“订单ID”+”\\\t”+”客户ID”+”\\\t”+”雇员ID”+”\\\t”+”订购日期”+”\\\t”+”订单金额”+”<br>”);

ResultSet rs = statement.executeQuery(sql);

int f1,f6;

String f2,f3,f4;

float f5;

while (rs.next()) {

f1 = rs.getInt(“ORDERID”);

f2 = rs.getString(“CUSTOMERID”);

f3 = rs.getString(“EMPLOYEEID”);

f4 = rs.getString(“ORDERDATE”);

f5 = rs.getFloat(“AMOUNT”);

out.println(f1+”\\\t”+f2+”\\\t”+f3+”\\\t”+f4+”\\\t”+f5+”\\\t”+”<br>”);

}

out.println(“</pre>”);

rs.close();

conn.close();

} catch (ClassNotFoundException e) {

System.out.println(“Sorry,can`t find the Driver!”);

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

}

%>

</body> 

<%@ page language=”java” import=”java.util.*” pageEncoding=”utf-8″%>

<%@ page import=”java.sql.*” %>

<body>

<%

String driver = “com.esproc.jdbc.InternalDriver”;

String url = “jdbc:esproc:local://”;

try {

Class.forName(driver);

Connection conn = DriverManager.getConnection(url);

Statement statement = conn.createStatement();

String sql =”select top 10 ORDERID,CUSTOMERID,EMPLOYEEID,ORDERDATE,AMOUNT from ORDERS.ctx where ORDERDATE=date(‘2015-07-18’) and AMOUNT>100″;

out.println(“Test page v1<br><br><br><pre>”);

out.println(“订单ID”+”\\t”+”客户ID”+”\\t”+”雇员ID”+”\\t”+”订购日期”+”\\t”+”订单金额”+”<br>”);

ResultSet rs = statement.executeQuery(sql);

int f1,f6;

String f2,f3,f4;

float f5;

while (rs.next()) {

f1 = rs.getInt(“ORDERID”);

f2 = rs.getString(“CUSTOMERID”);

f3 = rs.getString(“EMPLOYEEID”);

f4 = rs.getString(“ORDERDATE”);

f5 = rs.getFloat(“AMOUNT”);

out.println(f1+”\\t”+f2+”\\t”+f3+”\\t”+f4+”\\t”+f5+”\\t”+”<br>”);

}

out.println(“</pre>”);

rs.close();

conn.close();

} catch (ClassNotFoundException e) {

System.out.println(“Sorry,can`t find the Driver!”);

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

}

%>

</body>

能够看到,jsp 中先链接集算器的 JDBC,而后提交执行 SQL。步骤和通常的数据库彻底同样,具备很高的兼容性和通用性。对于多维分析工具来讲,虽然是界面操做来链接 JDBC 和提交 SQL,可是基本原理和 jsp 彻底同样。

三、启动 tomcat,在浏览器中访问 http://localhost:8080/DW/jdbc.jsp,查看结果。

还能够继续测试以下状况:

一、分组汇总

sql ="select CUSTOMERID,EMPLOYEEID,sum(AMOUNT) 订单总额,count(1) 订单数量 from ORDERS.ctx where ORDERDATE=date(‘2015-07-18’) group by CUSTOMERID,EMPLOYEEID";

二、并行查询

sql="select /*+ parallel (4) */

top 10 ORDERID,CUSTOMERID,EMPLOYEEID,ORDERDATE,AMOUNT from ORDERS.ctx where ORDERDATE=date(‘2015-07-18’) and AMOUNT>100" 

sql="select /*+ parallel (4) */

top 10 ORDERID,CUSTOMERID,EMPLOYEEID,ORDERDATE,AMOUNT from ORDERS.ctx where ORDERDATE=date(‘2015-07-18’) and AMOUNT>100"

和 ORACLE 相似,集算器简单 SQL 也支持 /+ parallel (4) / 这样的并行查询。

应用结构二:独立服务器

第一种解决办法是利用应用服务器的资源。在并发量很大,或者数据量很大的状况下,应用服务器会出现较大压力。这种状况下,推荐用独立的节点服务器进行数据计算。

集算器 JDBC 接收到 SQL 后,转给 DW.dfx 程序处理。DW.dfx 调用节点服务器上的 DWServer.dfx 进行计算。DWServer.dfx 把表名换成文件名,查本地文件 orders.ctx 返回结果。

下面的 DWServer 目录复制到须要的目录。集算器的节点服务器具有跨平台的特性,能够运行在任何支持 Java 的操做系统上,部署方法参见集算器教程。这里假设放到 windows 操做系统的 C 盘根目录。

DWServer

一、系统上线以前执行初始化 dfx,将 orders.ctx 文件放到 C:/DWServer/data 目录中。测试的时候能够直接将已经生成好的 orders.ctx 复制过去。

二、修改前面的 dfx,将 A1 改成 =file(“C:/DWServer/data/orders.ctx”),另存为 etlUpdate2.dfx。修改好的 etlUpdate2.dfx 在 c:\DWServer 目录。

三、打开应用服务器中的 C:\tomcat6\webapps\DW\WEB-INF\dfx\DW.dfx,观察理解 SPL 代码。参数 sql 是传入的 SQL 语句。

A B
1 =callx(“DWServer.dfx”,[sql];[“127.0.0.1:8281”])
2 return A1.ifn()

A1:调用节点机上的 DWServer.dfx。参数是 [sql],中括号表示序列,此时是只有一个成员的序列。[“127.0.0.1:8281”] 是节点机的序列,采用 IP: 端口号的方式。

A2:返回 A1 调用的结果。由于调用结果是序列,因此要用 ifn 函数找到序列中第一个不为空的成员,就是 SQL 对应的返回结果。

修改 C:\tomcat6\webapps\DW\WEB-INF\classes\raqsoftConfig.xml 中的以下配置:

<mainPath>C:\\\tomcat6\\\webapps\\\DW\\\WEB-INF\\\dfx</mainPath>

<JDBC>

<load>Runtime,Server</load>

<gateway>DW.dfx</gateway>

</JDBC> 

<mainPath>C:\\tomcat6\\webapps\\DW\\WEB-INF\\dfx</mainPath>

<JDBC>

<load>Runtime,Server</load>

<gateway>DW.dfx</gateway>

</JDBC>

这里标签的内容就是 JDBC 网关 dfx 文件。在 BI 系统中调用集算器 JDBC 时,所执行的 SQL 都将交由网关文件处理。若是不配置这个标签,JDBC 提交的语句会被集算器看成脚本直接解析运算。

四、启动节点服务器。

运行 esprocs.exe, 以下图:


点击配置按钮,配置相关参数:

点击肯定后,返回主界面,点击启动按钮。

五、打开 C:\DWServer\dfx\DWServer.dfx,观察理解 SPL 代码。

A B C
1 =filename=”C:/DWServer/data/orders.ctx”
2 =sql=replace(sql,”from ORDERS.ctx”,”from “+filename)
3 =connect() =A3.cursor@x(A2) return B3

A1:定义集算器集文件的绝对路径。

A2:将文件名替换为绝对路径。

A3-C3:链接文件系统。执行 SQL 获得游标并返回。

服务器方式也能够和“应用结构一”中同样配置主目录,A2 就不用写绝对路径了。路径写在这里的 SPL 中,好处是同一个服务器能够给多套数据表(文件)提供服务。若是不少文件都在主目录下,会不方便管理。

六、重启 tomcat,在浏览器中访问 http://localhost:8080/DW/jdbc.jsp,查看结果。

应用结构三:集群热备

在并发量不断增大,或者数据量不断增长的状况下,节点服务器能够进行横向扩展,应对大并发或大数据量计算的压力。

一、在另外一台 window 的机器上再部署一套集算器节点,部署方法和解决方法二略有不一样,须要配置一下数据分区。两台服务器的 IP 地址是 168.0.122 和 192.168.0.176。方法二中的 c:\DWServer 目录也要复制到另外一台服务器上。

图中数据分区名称配置为 0,路径是 c:/DWServer/data。注意,两个服务器都要配置。

二、改写 168.0.122 上的 c:/DWServer/dfx/etlUpdate2.dfx,另存为 etlUpdate3.dfx。

A B C
1 =connect(“orcl”)
2 =A1.cursor@d(“select ORDERDATE,CUSTOMERID,EMPLOYEEID,ORDERID,AMOUNT from ORDERS where ORDERDATE=? order by ORDERDATE,CUSTOMERID,EMPLOYEEID,ORDERID”,etlDate)
3 =file(“C:/ DWServer/data/orders.ctx”)
4 =A3.create() =A4.append(A2) =A3.rollback()
5 >A1.close()
6 =sync([“192.168.0.176:8281″]:”192.168.0.122:8281”;0)

A6 单元格是将更新以后的 orders.ctx 同步到 192.168.0.176 的 0 分区,也就是 C:/ DWServer/data 目录。[“192.168.0.176:8281”] 是指须要同步的节点机列表,若是有更多的节点机须要同步,能够写做:[“IP1:PORT1″,”IP2:PORT2″,”IP3:PORT3”]。

由于这里有同步的代码,因此只须要在 192.168.0.122 上执行定时任务 etlUpdate3.dfx 就能够了。

三、打开应用服务器中的 C:\tomcat6\webapps\DW\WEB-INF\dfx\DW.dfx,修改以下:

A B
1 =callx(“DWServer.dfx”,[sql];[“192.168.0.122:8281″,”192.168.0.176:8281”])
2 return A1.ifn()

A1:调用节点机上的 DWServer.dfx。参数是 [sql],中括号表示序列,此时是只有一个成员的序列。由于节点机是集群,因此有两个 IP 地址。在多并发时 callx 会随机访问两个节点。

四、重启 tomcat,在浏览器中访问 http://localhost:8080/DW/jdbc.jsp,查看结果。

集算器优点总结

开放的轻量级数据仓库 / 数据集市

集算器是专业的数据计算中间件(DCM),具有独立计算的能力,能够脱离数据库、数据仓库为多维分析系统前端提供数据源服务。

集算器采用列存数据,具有专业数据仓库的查询性能,千万级别的数据量,能够达到秒级的明细查询速度。普通数据库通常都是行存,没法达到多维分析的性能要求。同时,和专业数据仓库不一样,集算器价格都较低,建设、扩展和维护成本都比较小。

集算器是开放的,对多维分析系统前端提供标准的 JDBC 服务。能够造成平台式的后台数据源,为多个不一样厂家的前端同时提供数据服务。

组表列存 / 有序压缩存储

先进的数据存储方式,是数据计算中间件(DCM)成功实施的重要保障。

集算器组表采用列存方式存储数据,对于字段特别多的宽表查询,性能提高特别明显。组表采用的列存机制和常规列存是不一样的。常规列存(好比 parquet 格式),只能分块以后,再在块内列存,在作并行计算的时候是受限的。组表的可并行压缩列存机制,采用倍增分段技术,容许任意分段的并行计算,能够利用多 CPU 核的计算能力把硬盘的 IO 发挥到极致。

组表生成的时候,要指定维字段,数据自己是按照维字段有序存放的,经常使用的条件过滤计算不依赖索引也能保证高性能。文件采用压缩存储,减少在硬盘上占用的空间,读取更快。因为采用了合适的压缩比,解压缩占用的 CPU 时间能够忽略不计。

组表也能够采起行存和全内存存储数据,支持内存数据库方式运行。

集群功能

敏捷的集群能力能够保证数据计算中间件(DCM)的高性能和高可用性。

集算器节点服务器是独立进程,能够接受集算器 JDBC 的计算请求并返回结果。对于并发访问的状况,能够发给多个服务器同时计算,提升并发容量。对于单个大计算任务的状况,能够分红多个小任务,发给多个服务器同时计算,起到大数据并行计算的做用。

集算器集群计算方案,具有敏捷的横向扩展能力,并发量或者数据量大时能够经过快速增长节点来解决。集算器集群也具有容错能力,即有个别节点失效时还能确保整个集群能工做,计算任务能继续执行完毕,起到多机热备和保证高可用性的做用。

应用推广

做为数据计算中间件(DCM),集算器提供的后台数据源能够支持各类前端应用,不只仅限于前端是多维分析的状况。例如:大屏展现、管理驾驶舱、实时报表、大数据量清单报表、报表批量订阅等等。

集算器造成的后台数据源也能够和数据库、数据仓库配合使用。集算器实现的数据计算网关和路由,能够在集算器缓存数据和数据仓库之间智能切换,解决数据仓库没法知足性能要求的问题。例如:冷热数据分开计算的场景。具体作法参见《集算器实现计算路由优化 BI 后台性能》。

相关文章
相关标签/搜索