用計(jì)算路由的方法優(yōu)化BI后臺(tái)性能

問(wèn)題的提出

BI 系統(tǒng)的常見(jiàn)結(jié)構(gòu)是:前端是 BI 應(yīng)用,負(fù)責(zé)多維分析的用戶操作和結(jié)果呈現(xiàn);后臺(tái)是數(shù)據(jù)庫(kù) / 數(shù)據(jù)倉(cāng)庫(kù),負(fù)責(zé)數(shù)據(jù)計(jì)算和存儲(chǔ)。前端和后臺(tái)之間用 SQL 作為接口。

成都網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)建站!專注于網(wǎng)頁(yè)設(shè)計(jì)、成都網(wǎng)站建設(shè)、微信開(kāi)發(fā)、微信小程序、集團(tuán)成都企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。核心團(tuán)隊(duì)均擁有互聯(lián)網(wǎng)行業(yè)多年經(jīng)驗(yàn),服務(wù)眾多知名企業(yè)客戶;涵蓋的客戶類型包括:高空作業(yè)車租賃等眾多領(lǐng)域,積累了大量豐富的經(jīng)驗(yàn),同時(shí)也獲得了客戶的一致稱贊!

實(shí)際應(yīng)用中,常常出現(xiàn)后臺(tái)數(shù)據(jù)倉(cāng)庫(kù)壓力過(guò)重的問(wèn)題。問(wèn)題表現(xiàn)為前端響應(yīng)時(shí)間過(guò)長(zhǎng),數(shù)據(jù)倉(cāng)庫(kù)反應(yīng)速度變慢。

常見(jiàn)的解決方案是在數(shù)據(jù)倉(cāng)庫(kù)和應(yīng)用之間再增加一個(gè)前置數(shù)據(jù)庫(kù)。但是前置數(shù)據(jù)庫(kù)和后臺(tái)數(shù)據(jù)倉(cāng)庫(kù)之間很難實(shí)現(xiàn)數(shù)據(jù)的路由和混合計(jì)算,例如:訪問(wèn)頻次很高的熱點(diǎn)數(shù)據(jù)放在前置數(shù)據(jù)庫(kù),大量冷數(shù)據(jù)放在數(shù)據(jù)倉(cāng)庫(kù)中,查詢時(shí)按照一定規(guī)則來(lái)決定訪問(wèn)前置數(shù)據(jù)庫(kù)還是后臺(tái)數(shù)據(jù)倉(cāng)庫(kù)。而如果前置數(shù)據(jù)庫(kù)和后臺(tái)數(shù)據(jù)倉(cāng)庫(kù)是不同的產(chǎn)品,還要考慮 SQL 的翻譯問(wèn)題。

解決思路與過(guò)程

作為數(shù)據(jù)計(jì)算中間件(DCM),構(gòu)建獨(dú)立的數(shù)據(jù)前置層是集算器的重要應(yīng)用模式。數(shù)據(jù)前置層將 BI 系統(tǒng)重構(gòu)為三層結(jié)構(gòu):數(shù)據(jù)存儲(chǔ)及批量數(shù)據(jù)計(jì)算層由數(shù)據(jù)庫(kù)承擔(dān);數(shù)據(jù)前置及緩存層由集算器承擔(dān);數(shù)據(jù)分析展現(xiàn)層由多維分析工具或者報(bào)表工具承擔(dān)。

集算器可以脫離數(shù)據(jù)庫(kù)進(jìn)行數(shù)據(jù)緩存和獨(dú)立的復(fù)雜計(jì)算,同時(shí)具備可編程網(wǎng)關(guān)機(jī)制,可以在緩存計(jì)算和 SQL 透?jìng)髦g自由切換。利用集算器完成前置層數(shù)據(jù)計(jì)算,可以與數(shù)據(jù)庫(kù)承擔(dān)的批量數(shù)據(jù)計(jì)算任務(wù)分離,并且不必再建設(shè)另外一個(gè)數(shù)據(jù)庫(kù)。

集算器可以將熱點(diǎn)數(shù)據(jù)、近期數(shù)據(jù)放在數(shù)據(jù)前置層,從而起到數(shù)據(jù)緩存的作用,可以有效提高數(shù)據(jù)計(jì)算的速度,減少用戶等待時(shí)間。

系統(tǒng)架構(gòu)圖如下:

用計(jì)算路由的方法優(yōu)化BI后臺(tái)性能

案例場(chǎng)景說(shuō)明

前臺(tái) BI 系統(tǒng),要針對(duì)訂單數(shù)據(jù)做自助查詢。查詢的必選條件是訂購(gòu)日期。為了簡(jiǎn)化起見(jiàn),前臺(tái) BI 系統(tǒng)用 tomcat 服務(wù)器中的 jdbc.jsp 來(lái)模擬。

集算器 JDBC 和智能網(wǎng)關(guān)集成在應(yīng)用系統(tǒng)中。jdbc.jsp 模仿 BI 應(yīng)用系統(tǒng),產(chǎn)生符合集算器簡(jiǎn)單查詢規(guī)范的 SQL,通過(guò)集算器 JDBC 提交給集算器智能網(wǎng)關(guān)處理。

數(shù)據(jù)來(lái)自于 ORACLE 數(shù)據(jù)庫(kù) demo 中的 ORDERS 表。ORDERS 訂單表是全量數(shù)據(jù),集算器只存儲(chǔ)最近三年的數(shù)據(jù),比如:2015 年 -2018 年。日期以訂購(gòu)日期為準(zhǔn)。

基礎(chǔ)數(shù)據(jù)準(zhǔn)備與提取緩存數(shù)據(jù)

用下面的 orders.sql 文件在 ORACLE 數(shù)據(jù)庫(kù)中完成 ORDERS 表的建表和數(shù)據(jù)初始化。

點(diǎn)擊下載 orders.sql

在集算器中,新建一個(gè)數(shù)據(jù)源 orcl,連接 ORACLE 數(shù)據(jù)庫(kù)。用 SPL 語(yǔ)言腳本 etl1.dfx 將最近三年的數(shù)據(jù)預(yù)先讀取到集算器集文件 orders.btx 中。SPL 腳本如下:


AB
1=year(now())-3
2=connect(“orcl”)=A2.cursor@d(“select * from orders where to_char(orderdate,‘yyyy’)>=?”,A1)
3=file(“C:/tomcat6/webapps/gateway/WEB-INF/data/orders.btx”)
4=A3.export@z(B2)>A2.close()

從 SPL 腳本可以看出,只要在 A4 單元格中用一句 export 就可以將數(shù)據(jù)庫(kù)中的數(shù)據(jù)導(dǎo)出到文件中。集文件是集算器內(nèi)置的二進(jìn)制文件格式,采用了簡(jiǎn)單壓縮機(jī)制,相同數(shù)據(jù)量比數(shù)據(jù)庫(kù)的占用空間會(huì)更小。@z 選項(xiàng)表示寫出可以分段的文件,很適合常常需要并行的多維分析類運(yùn)算。

B2 單元格中數(shù)據(jù)庫(kù)游標(biāo)的 @d 選項(xiàng),表示從 ORACLE 數(shù)據(jù)庫(kù)中取數(shù)的時(shí)候?qū)?numeric 型數(shù)據(jù)轉(zhuǎn)換成 double 型,精度對(duì)于金額這樣的常見(jiàn)數(shù)值完全足夠了。如果沒(méi)有這個(gè)選項(xiàng)就會(huì)默認(rèn)轉(zhuǎn)換成 big decimal 型數(shù)據(jù),計(jì)算性能會(huì)受到較大影響。

腳本可以用 windows 或者 linux 命令行的方式執(zhí)行,結(jié)合定時(shí)任務(wù),可以定時(shí)執(zhí)行批量任務(wù)。windows 命令行的調(diào)用方式是:

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

linux 命令是:

/raqsoft/esProc/bin/esprocx.sh /gateway/etl1.dfx

解決辦法一:應(yīng)用服務(wù)器集成計(jì)算

集算器 JDBC 智能網(wǎng)關(guān)接收到 SQL 后,轉(zhuǎn)給 gateway1.dfx 程序處理。gateway1.dfx 判斷是否三年內(nèi)的查詢,如果是,就把表名換成文件名,查本地文件 orders.btx 返回結(jié)果。如果不是,把 SQL 轉(zhuǎn)換成 ORACLE 格式,提交數(shù)據(jù)庫(kù)處理。

1、下面的 gateway 目錄復(fù)制到 tomcat 的應(yīng)用目錄。

點(diǎn)擊下載 gateway.zip

目錄結(jié)構(gòu)如下圖:

用計(jì)算路由的方法優(yōu)化BI后臺(tái)性能

注意:配置文件在 classes 中,在官網(wǎng)上獲取的授權(quán)文件也要放在 classes 目錄中。集算器的 Jar 包要放在 lib 目錄中(需要哪些 jar 請(qǐng)參照集算器教程)。另外,還需要檢查和修改 raqsoftConfig.xml 中的如下配置:

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

<JDBC>

<load>Runtime,Server\\</load>

<gateway>gateway1.dfx\\</gateway>

</JDBC> 

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

<JDBC>

<load>Runtime,Server\</load>

<gateway>gateway1.dfx\</gateway>

</JDBC><mainPath>C:\\\tomcat6\\\webapps\\\gateway\\\WEB-INF\\\dfx\\</mainPath><JDBC><load>Runtime,Server\\</load><gateway>gateway1.dfx\\</gateway>
</JDBC> <mainPath>C:\\tomcat6\\webapps\\gateway\\WEB-INF\\dfx\</mainPath><JDBC><load>Runtime,Server\</load><gateway>gateway1.dfx\</gateway></JDBC>

這里標(biāo)簽的內(nèi)容就是網(wǎng)關(guān) dfx 文件。在 BI 系統(tǒng)中調(diào)用集算器 JDBC 時(shí),所執(zhí)行的 SQL 都將交由網(wǎng)關(guān)文件處理。如果不配置這個(gè)標(biāo)簽,JDBC 提交的語(yǔ)句都被集算器當(dāng)作腳本直接解析運(yùn)算,而無(wú)法實(shí)現(xiàn)希望的路由規(guī)則。

2、編輯 gateway 目錄中的 jdbc.jsp,模擬前臺(tái)界面提交 sql 展現(xiàn)結(jié)果。

<%@ 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 where ORDERDATE=date('2015-07-18') and AMOUNT>100
";

out.println("Data gateway test page v1 <br><br><br><pre>");

out.println("訂單ID"+"\\\t"+"客戶ID"+"\\\t"+"雇員ID"+"\\\t"+"訂購(gòu)日期"+"\\\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 where ORDERDATE=date('2015-07-18') and AMOUNT>100
";

out.println("Data gateway test page v1 <br><br><br><pre>");

out.println("訂單ID"+"\\t"+"客戶ID"+"\\t"+"雇員ID"+"\\t"+"訂購(gòu)日期"+"\\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 where ORDERDATE=date('2015-07-18') and AMOUNT>100
";out.print
ln("Data gateway test page v1 <br><br><br><pre>");out.println("訂單ID"+"\\\t"+"客戶ID"+"\\\t"+"雇員ID"+"\\\t"+"訂購(gòu)日期"+"\\\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 where ORDERDATE=date('2015-07-18') and AMOUNT>100"
;out.print
ln("Data gateway test page v1 <br><br><br><pre>");out.println("訂單ID"+"\\t"+"客戶ID"+"\\t"+"雇員ID"+"\\t"+"訂購(gòu)日期"+"\\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,然后提交執(zhí)行 SQL。步驟和一般的數(shù)據(jù)庫(kù)完全一樣,具有很高的兼容性和通用性。對(duì)于 BI 工具來(lái)說(shuō),雖然是界面操作來(lái)連接 JDBC 和提交 SQL,但是基本原理和 jsp 完全一樣。

3、打開(kāi) dfx 目錄中的 gateway1.dfx,觀察理解 SPL 代碼。

首先,可以看到 gateway1.dfx 傳入?yún)?shù)是 sql 和 args,例如傳入 SQL:

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

接下來(lái),可以看到 SPL 腳本如下:


ABC
1=filename=“C:/tomcat6/webapps/gateway/WEB-INF/data/orders.btx”

2=sql.sqlparse@w().split(" ")=A2.select@1(like(~,“ORDERDATE=date(‘????-??-??’)”))
3=mid(right(B2,14),3,10)=year(now())-year(date(A3))
4if B3<=3=connect()=sql=replace(sql,“from ORDERS”,"from  "+filename)
5
=B4.cursor@x(sql)return B5
6else=connect(“orcl”)=sql=sql.sqltranslate(“ORACLE”)
7
=B6.cursor@x(sql)return B7

說(shuō)明:

A1:定義集算器集文件的絕對(duì)路徑。

A2:解析 SQL,獲取 where 子句,并用空格來(lái)拆分成序列。

B2、A3:在 A2 序列找到必選條件訂購(gòu)日期,獲取日期值。

B3:計(jì)算訂購(gòu)日期的年份和當(dāng)前日期年份相差幾年。

A4:判斷相差的年份是否超過(guò) 3 年。

B4-C5:如果不超過(guò) 3 年,就連接文件系統(tǒng)。將 SQL 中的 from 訂單,替換成 from 文件名。執(zhí)行 SQL 得到游標(biāo)并返回。

B6-C7:如果超過(guò) 3 年,就連接數(shù)據(jù)庫(kù)。將 SQL 翻譯成符合 ORACLE 數(shù)據(jù)庫(kù)規(guī)范的 SQL, 執(zhí)行 SQL 得到游標(biāo)并返回。

4、啟動(dòng) tomcat,在瀏覽器中訪問(wèn) http://localhost:8080/gateway/jdbc.jsp,查看結(jié)果。

用計(jì)算路由的方法優(yōu)化BI后臺(tái)性能

還可以繼續(xù)測(cè)試如下情況:

(1) 超出三年的查詢

sql =“select top 10 ORDERID,CUSTOMERID,EMPLOYEEID,ORDERDATE,AMOUNT from ORDERS where ORDERDATE=date(‘2014-07-18’) and AMOUNT>100”;

由于日期 2014 年已經(jīng)超出三年的限制,所以在 C6 中 SQL 會(huì)被翻譯成 ORACLE 規(guī)范如下:

SELECT * FROM (select  ORDERID,CUSTOMERID,EMPLOYEEID,ORDERDATE,AMOUNT from ORDERS where ORDERDATE=TO_DATE(‘2014-07-18’,‘YYYY-MM-DD’) and AMOUNT>100)t WHERE ROWNUM<=10

(2) 分組匯總

sql =“select CUSTOMERID,EMPLOYEEID,sum(AMOUNT) 訂單總額,count(1) 訂單數(shù)量 from ORDERS where ORDERDATE=date(‘2015-07-18’)  group by CUSTOMERID,EMPLOYEEID”;

(3) 并行查詢

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

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

和 ORACLE 類似,集算器簡(jiǎn)單 SQL 也支持 /*+ parallel (4) */ 這樣的并行查詢。

解決辦法二:獨(dú)立節(jié)點(diǎn)服務(wù)器計(jì)算

第一種解決辦法是利用應(yīng)用服務(wù)器的資源。在并發(fā)量很大,或者數(shù)據(jù)量很大的情況下,應(yīng)用服務(wù)器會(huì)出現(xiàn)較大壓力。這種情況下,推薦用獨(dú)立的節(jié)點(diǎn)服務(wù)器進(jìn)行數(shù)據(jù)計(jì)算。節(jié)點(diǎn)服務(wù)器可以進(jìn)行橫向擴(kuò)展,應(yīng)對(duì)大并發(fā)或大數(shù)據(jù)量計(jì)算的壓力。

集算器 JDBC 智能網(wǎng)關(guān)接受到 SQL 后,轉(zhuǎn)給 gateway2.dfx 程序處理。gateway2.dfx 調(diào)用節(jié)點(diǎn)服務(wù)器上的 gatewayServer2.dfx 進(jìn)行計(jì)算。gatewayServer2.dfx 判斷是否三年內(nèi)的查詢,如果是,就把表名換成文件名,查本地文件 orders.btx 返回結(jié)果。如果不是三年內(nèi)的查詢,把 sql 轉(zhuǎn)換成 ORACLE 格式,提交數(shù)據(jù)庫(kù)處理。

1、下面的 gatewayServer 目錄復(fù)制到需要的目錄。集算器的節(jié)點(diǎn)服務(wù)器具備跨平臺(tái)的特性,可以運(yùn)行在任何支持 Java 的操作系統(tǒng)上,部署方法參見(jiàn)集算器教程。這里假設(shè)放到 windows 操作系統(tǒng)的 C 盤根目錄。

點(diǎn)擊下載 gatewayServer.zip

2、修改前面的 dfx,將 A3 改為 =file(“C:/gatewayServer/data/orders.btx”),另存為 etl2.dfx。修改好的 etl2.dfx 在 c:\gatewayServer 目錄。

3、打開(kāi)應(yīng)用服務(wù)器中的 C:\tomcat6\webapps\gateway\WEB-INF\dfx\gateway2.dfx,觀察理解 SPL 代碼。參數(shù)不變,還是傳入的 sql 和 args。


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

A1:調(diào)用節(jié)點(diǎn)機(jī)上的 gatewayServer2.dfx。參數(shù)是 [sql],中括號(hào)表示序列,此時(shí)是只有一個(gè)成員的序列。[“127.0.0.1:8281”] 是節(jié)點(diǎn)機(jī)的序列,采用 IP: 端口號(hào)的方式。節(jié)點(diǎn)機(jī)是集群的時(shí)候,可以有多個(gè) IP 地址,例如:["IP1:PORT1″,"IP2:PORT2″,“IP3:PORT3”]。

A2:返回 A1 調(diào)用的結(jié)果。因?yàn)檎{(diào)用結(jié)果可以是序列,所以要用 ifn 函數(shù)找到序列中第一個(gè)不為空的成員,就是 SQL 對(duì)應(yīng)的返回結(jié)果。

修改 C:\tomcat6\webapps\gateway\WEB-INF\classes\raqsoftConfig.xml 中的如下配置 gateway1.dfx 改為 gateway2.dfx。

<JDBC>

<load>Runtime,Server\\</load>

<gateway>gateway2.dfx\\</gateway>

</JDBC> 

<JDBC>

<load>Runtime,Server\</load>

<gateway>gateway2.dfx\</gateway>

</JDBC><JDBC><load>Runtime,Server\\</load><gateway>gateway2.dfx\\</gateway></JDBC> <JDBC><load>Runtime,Server\</load><gateway>gateway2.dfx\</gate
way></JDBC>

4、啟動(dòng)節(jié)點(diǎn)服務(wù)器。

運(yùn)行 esprocs.exe, 如下圖:

用計(jì)算路由的方法優(yōu)化BI后臺(tái)性能
用計(jì)算路由的方法優(yōu)化BI后臺(tái)性能

點(diǎn)擊配置按鈕,配置相關(guān)參數(shù):
用計(jì)算路由的方法優(yōu)化BI后臺(tái)性能

點(diǎn)擊確定后,返回主界面,點(diǎn)擊啟動(dòng)按鈕。

5、打開(kāi) C:\gatewayServer\dfx\gatewayServer2.dfx,觀察理解 SPL 代碼。


ABC
1=filename=“C:/gatewayServer/data/orders.btx”

2=sql.sqlparse@w().split(" ")=A2.select@1(like(~,“ORDERDATE=date(‘????-??-??’)”))
3=mid(right(B2,14),3,10)=year(now())-year(date(A3))
4if B3<=3=connect()=sql=replace(sql,“from ORDERS”,"from  "+filename)
5
=B4.cursor@x(sql)return B5
6else=connect(“orcl”)=sql=sql.sqltranslate(“ORACLE”)
7
=B6.cursor@x(sql)return B7

代碼基本和前面的 gateway1.dfx 一致。區(qū)別是這個(gè) dfx 是在節(jié)點(diǎn)服務(wù)器 unitServer 上執(zhí)行的,數(shù)據(jù)是存在節(jié)點(diǎn)服務(wù)器上。

5、重啟 tomcat,在瀏覽器中訪問(wèn) http://localhost:8080/gateway/jdbc.jsp,查看結(jié)果。

解決辦法三:集算器組表計(jì)算

當(dāng)數(shù)據(jù)量很大同時(shí)又需要秒級(jí)的查詢速度時(shí),我們建議采用集算器組表來(lái)存儲(chǔ)數(shù)據(jù)。組表適用的場(chǎng)合包括:數(shù)據(jù)表字段有幾十個(gè)甚至更多;數(shù)據(jù)量幾千萬(wàn)行,存成集文件在 1G 以上;查詢要求秒級(jí)響應(yīng)。

對(duì)于簡(jiǎn)單 SQL 來(lái)說(shuō),組表文件的用法和集文件沒(méi)有什么不同, 只是文件名不一樣。gatewayServer2.dfx 中只需要把 A1 改為 =filename=“C:/gatewayServer/data/orders.ctx”,另存為 gatewayServer3.dfx。相應(yīng)的 gateway2.dfx 中的 A1 改為 =callx(“gatewayServer3.dfx”,[sql];[“127.0.0.1:8281”]),另存為 gateway3.dfx。

修改 C:\tomcat6\webapps\gateway\WEB-INF\classes\raqsoftConfig.xml 中的如下配置 gateway2.dfx 改為 gateway3.dfx。

<JDBC>

<load>Runtime,Server\\</load>

<gateway>gateway3.dfx\\</gateway>

</JDBC> 

<JDBC>

<load>Runtime,Server\</load>

<gateway>gateway3.dfx\</gateway>

</JDBC><JDBC><load>Runtime,Server\\</load><gateway>gateway3.dfx\\</gateway></JDBC> <JDBC><load>Runtime,Server\</load><gateway>gateway3.dfx\</gate
way></JDBC>

我們重點(diǎn)理解如何改寫 etl 過(guò)程,修改前面的 etl2.dfx,另存為 etl3.dfx。


A
1=year(now())-3
2=connect(“orcl”)
3=A2.cursor@d(“select CUSTOMERID,EMPLOYEEID,ORDERDATE,ORDERID,AMOUNT from ORDERS where to_char(ORDERDATE,‘yyyy’)>=? order by CUSTOMERID,EMPLOYEEID,ORDERDATE,ORDERID",A1)
4=file(“C:/gatewayServer/data/orders.ctx”)
5=A4.create(#CUSTOMERID,#EMPLOYEEID,#ORDERDATE,#ORDERID,AMOUNT)
6=A5.append(A3)
7>A2.close()

組表與集文件不同,默認(rèn)是采用列式存儲(chǔ)的,支持任意分段的并行計(jì)算,可以有效提升查詢速度。同時(shí),生成組表的時(shí)候,要注意數(shù)據(jù)預(yù)先排序和合理定義維字段。本例中,按照經(jīng)常過(guò)濾、分組的字段,將維字段確定為:CUSTOMERID,EMPLOYEEID,ORDERDATE,ORDERID。

A3 取得數(shù)據(jù)的時(shí)候,要按照維字段排序。因?yàn)?CUSTOMERID,EMPLOYEEID,ORDERDATE 對(duì)應(yīng)的重復(fù)數(shù)據(jù)多,所以放在前面排序;ORDERID 對(duì)應(yīng)的重復(fù)數(shù)據(jù)少,所以放在后面排序。

A4 中定義組表的時(shí)候用 #來(lái)表示維字段。

需要說(shuō)明的是,組表也支持并行查詢 /*+ parallel (n) */。

多任務(wù)性能調(diào)優(yōu)技巧小結(jié)

BI 應(yīng)用的特點(diǎn)是:

1、響應(yīng)時(shí)間要求高,一般不超過(guò) 5-10 秒。

2、查詢對(duì)應(yīng)數(shù)據(jù)量在幾百兆到幾 G 范圍,字段有幾十個(gè)甚至上百個(gè)。

3、并發(fā)量較大,幾十到幾百個(gè)并發(fā)。

性能優(yōu)化的方法是:

1、采用組表,提高單任務(wù)查詢的響應(yīng)速度。

◇ 根據(jù)需求,合理定義維字段。

組表定義的時(shí)候,要按照業(yè)務(wù)的需要確定維字段。要選擇經(jīng)常作為過(guò)濾條件或者用來(lái)分組的字段作為維字段,維字段前用 #標(biāo)識(shí)。

◇ 按照維字段,預(yù)先排序。

要按照維字段做好數(shù)據(jù)的排序,重復(fù)記錄數(shù)多的字段在前面,例如:按照 order by 省,市,縣的字段順序來(lái)排序,而不是反過(guò)來(lái)。

◇ 根據(jù)并發(fā)量,選擇是否用并行查詢。

并發(fā)量比較大的時(shí)候,單個(gè) SQL 查詢就不建議用并行查詢了 /*+ parallel (n) */。并行查詢會(huì)消耗更多的線程數(shù),反而會(huì)影響大的并發(fā)性能。

2、合理配置節(jié)點(diǎn)服務(wù)器的參數(shù),發(fā)揮每個(gè)節(jié)點(diǎn)的性能。

每臺(tái)服務(wù)器(實(shí)體機(jī)或者虛擬機(jī))要啟動(dòng)一個(gè)節(jié)點(diǎn)服務(wù)器,每個(gè)節(jié)點(diǎn)服務(wù)器啟動(dòng)分機(jī)的配置界面如下:

用計(jì)算路由的方法優(yōu)化BI后臺(tái)性能

◇ 根據(jù)硬件資源,配置進(jìn)程數(shù)

進(jìn)程列表中的進(jìn)程數(shù)(也就是適合作業(yè)數(shù))建議是不要超過(guò) CPU 總核數(shù) *2/3。例如:服務(wù)器有 8 個(gè) CPU 每個(gè)兩核,總核數(shù)是 8*2=16,那么進(jìn)程數(shù)量就不要超過(guò) 16*2/3=10 個(gè)。最大作業(yè)數(shù)推薦是適合作業(yè)數(shù) *2,也就是 10*2=20 個(gè)。

◇ 盡量多分配內(nèi)存,但要避免超量

節(jié)點(diǎn)服務(wù)器每個(gè)進(jìn)程的最大內(nèi)存要盡量多分配,但是總數(shù)加起來(lái)要比實(shí)際的物理內(nèi)存小,避免操作系統(tǒng)用硬盤來(lái)補(bǔ)充內(nèi)存的不足。例如,總內(nèi)存是 32G,進(jìn)程數(shù)量是 8 個(gè),那么每個(gè)進(jìn)程的最大內(nèi)存就不要大于 4G。配置進(jìn)程的最大最小內(nèi)存是在 C:\Program Files\raqsoft\esProc\bin\config.txt 中,例如:

jvm_args=-Xms128m -Xmx4845m 最小內(nèi)存是 128M,最大是 4G。

3、橫向擴(kuò)展節(jié)點(diǎn)服務(wù)器,多機(jī)應(yīng)對(duì)大并發(fā)訪問(wèn)。

◇ 橫向擴(kuò)展,應(yīng)對(duì)大并發(fā)。

隨著并發(fā)量的增大,當(dāng)性能不能滿足要求的時(shí)候,要增加節(jié)點(diǎn)服務(wù)器的數(shù)量,通過(guò)橫向擴(kuò)展來(lái)滿足需求。

◇ 增加服務(wù)器列表配置項(xiàng)。

這時(shí)候要修改 gateway3.dfx 中的 callx 函數(shù)的服務(wù)器序列參數(shù)??梢詫⒎?wù)器序列參數(shù)寫到配置文件中,這樣就可以不必每次都修改 dfx 文件了。

4、使用本機(jī)硬盤數(shù)據(jù)進(jìn)行計(jì)算,避免跨網(wǎng)絡(luò)訪問(wèn)。

硬盤的 IO 速度是比較有保證的。

節(jié)點(diǎn)服務(wù)器通過(guò)網(wǎng)絡(luò)去取其他服務(wù)器上的數(shù)據(jù),或者通過(guò)訪問(wèn)共享存儲(chǔ)上的數(shù)據(jù),經(jīng)常會(huì)出現(xiàn)網(wǎng)絡(luò)阻塞的情況,降低查詢響應(yīng)速度。因此,盡可能每臺(tái)節(jié)點(diǎn)服務(wù)器僅僅執(zhí)行本機(jī)上的數(shù)據(jù),不要跨網(wǎng)絡(luò)訪問(wèn)。

集算器優(yōu)勢(shì)總結(jié)

可編程數(shù)據(jù)路由

可編程數(shù)據(jù)路由是數(shù)據(jù)計(jì)算中間件(DCM)的重要應(yīng)用場(chǎng)景。

在前述的例子中,數(shù)據(jù)路由的策略是:最近三年的數(shù)據(jù)作為熱數(shù)據(jù)放路由到集算器中計(jì)算,其他數(shù)據(jù)作為冷數(shù)據(jù),路由到數(shù)據(jù)庫(kù)中計(jì)算。

類似的路由規(guī)則還有:最近三天和最近十二個(gè)月的最后一天的數(shù)據(jù)作為熱數(shù)據(jù),路由到集算器中計(jì)算,其他數(shù)據(jù)路由到數(shù)據(jù)庫(kù)匯總計(jì)算。

對(duì)于冷熱數(shù)據(jù)計(jì)算路由規(guī)則,本篇只介紹了一次查詢只涉及冷或熱數(shù)據(jù)的情況,如果在一次查詢中可能同時(shí)涉及冷熱兩種數(shù)據(jù),我們將在后續(xù)文章中進(jìn)行介紹。

實(shí)際應(yīng)用中,數(shù)據(jù)路由的規(guī)則可能會(huì)很復(fù)雜和多變,通過(guò)配置來(lái)實(shí)現(xiàn)會(huì)非常困難,用編程的方式實(shí)現(xiàn)是最佳方案。采用集算器的編程語(yǔ)言 SPL 來(lái)實(shí)現(xiàn)復(fù)雜的數(shù)據(jù)路由規(guī)則是最簡(jiǎn)單和最高效的。集算器支持多樣性異構(gòu)數(shù)據(jù)源的混合計(jì)算,可以編程實(shí)現(xiàn)涉及到各種異構(gòu)數(shù)據(jù)源的復(fù)雜數(shù)據(jù)路由規(guī)則。

SQL 解析與翻譯

用作多維分析后臺(tái)時(shí),數(shù)據(jù)計(jì)算中間件(DCM)要提供必要的 SQL 解析與翻譯功能。

數(shù)據(jù)路由的實(shí)現(xiàn)離不開(kāi)集算器對(duì) SQL 語(yǔ)句的解析和翻譯。首先要用集算器的 SQL 解析能力,找到 where 條件中的日期字段,然后根據(jù)規(guī)則來(lái)決定路由到文件還是數(shù)據(jù)庫(kù)。如果是路由到數(shù)據(jù)庫(kù),那么要把集算器的標(biāo)準(zhǔn) SQL 翻譯成數(shù)據(jù)庫(kù)的 SQL,就要用到集算器的 SQL 翻譯能力。

集算器的 SQL 解析用 sqlparse()函數(shù)實(shí)現(xiàn),SQL 翻譯用 sqltranslate() 函數(shù)實(shí)現(xiàn)。

SQL 性能優(yōu)化

SQL 性能優(yōu)化也是數(shù)據(jù)計(jì)算中間件(DCM)必不可少的能力。

BI 應(yīng)用允許用戶拖拽生成 SQL,就會(huì)出現(xiàn)很多性能不高的 SQL。比如直接在明細(xì)查詢的 SQL 外面加上一層 count 來(lái)統(tǒng)計(jì)結(jié)果總條數(shù):select count(1) from (select f1,f2,f3,f4…f30 from table1 where f1=1 and 1=1)。此時(shí)子查詢中的 f1 到 f30 如果全部取出,就會(huì)降低查詢的性能。1=1 這樣的過(guò)濾條件也會(huì)造成沒(méi)有意義的時(shí)間消耗。

集算器簡(jiǎn)單 SQL 引擎,可以完成自動(dòng)查詢優(yōu)化。去掉 1=1 這樣不必要的條件,也不會(huì)取出所有字段來(lái)完成 count。從而實(shí)現(xiàn) SQL 解析和優(yōu)化,有效的提高查詢性能。

類似的,還有 select top 10 f1,f2 from table1 order by f1。集算器會(huì)采用小結(jié)果集比較的方式實(shí)現(xiàn)??梢宰龅綗o(wú)須大排序,只遍歷一邊數(shù)據(jù)即可得到需要的結(jié)果,有效提升查詢速度。

組表列存 / 有序壓縮存儲(chǔ)

先進(jìn)的數(shù)據(jù)存儲(chǔ)方式,是數(shù)據(jù)計(jì)算中間件(DCM)成功實(shí)施的重要保障。

集算器組表采用列存方式存儲(chǔ)數(shù)據(jù),對(duì)于字段特別多的寬表查詢,性能提升特別明顯。組表采用的列存機(jī)制和常規(guī)列存是不同的。常規(guī)列存(比如 parquet 格式),只能分塊之后,再在塊內(nèi)列存,在做并行計(jì)算的時(shí)候是受限的。組表的可并行壓縮列存機(jī)制,采用倍增分段技術(shù),允許任意分段的并行計(jì)算,可以利用多 CPU 核的計(jì)算能力把硬盤的 IO 發(fā)揮到極致。

組表生成的時(shí)候,要指定維字段,數(shù)據(jù)本身是按照維字段有序存放的,常用的條件過(guò)濾計(jì)算不依賴索引也能保證高性能。文件采用壓縮存儲(chǔ),減小在硬盤上占用的空間,讀取更快。由于采用了合適的壓縮比,解壓縮占用的 CPU 時(shí)間可以忽略不計(jì)。

組表也可以采取行存和全內(nèi)存存儲(chǔ)數(shù)據(jù),支持內(nèi)存數(shù)據(jù)庫(kù)方式運(yùn)行。

集群功能

敏捷的集群能力可以保證數(shù)據(jù)計(jì)算中間件(DCM)的高性能和高可用性。

集算器節(jié)點(diǎn)服務(wù)器是獨(dú)立進(jìn)程,可以接受集算器網(wǎng)關(guān)程序的計(jì)算請(qǐng)求并返回結(jié)果。對(duì)于并發(fā)訪問(wèn)的情況,可以發(fā)給多個(gè)服務(wù)器同時(shí)計(jì)算,提高并發(fā)容量。對(duì)于單個(gè)大計(jì)算任務(wù)的情況,可以分成多個(gè)小任務(wù),發(fā)給多個(gè)服務(wù)器同時(shí)計(jì)算,起到大數(shù)據(jù)并行計(jì)算的作用。

集算器集群計(jì)算方案,具備敏捷的橫向擴(kuò)展能力,并發(fā)量或者數(shù)據(jù)量大時(shí)可以通過(guò)快速增加節(jié)點(diǎn)來(lái)解決。集算器集群也具備容錯(cuò)能力,即有個(gè)別節(jié)點(diǎn)失效時(shí)還能確保整個(gè)集群能工作,計(jì)算任務(wù)能繼續(xù)執(zhí)行完畢,起到多機(jī)熱備和保證高可用性的作用。

應(yīng)用推廣

作為數(shù)據(jù)計(jì)算中間件(DCM),集算器實(shí)現(xiàn)的數(shù)據(jù)計(jì)算網(wǎng)關(guān)和路由,可以解決數(shù)據(jù)倉(cāng)庫(kù)無(wú)法滿足性能要求,冷熱數(shù)據(jù)分開(kāi)又要混合計(jì)算的場(chǎng)景,不僅僅限于前端是 BI 的情況。例如:大屏展示、管理駕駛艙、實(shí)時(shí)報(bào)表、大數(shù)據(jù)量清單報(bào)表、報(bào)表批量訂閱等等。


本文名稱:用計(jì)算路由的方法優(yōu)化BI后臺(tái)性能
網(wǎng)站網(wǎng)址:http://bm7419.com/article44/iehhee.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、網(wǎng)站制作、品牌網(wǎng)站建設(shè)、手機(jī)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站維護(hù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁(yè)設(shè)計(jì)