溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

實現(xiàn)報表的可控緩存

發(fā)布時間:2020-07-24 12:55:34 來源:網(wǎng)絡(luò) 閱讀:330 作者:raqsoft 欄目:大數(shù)據(jù)

使用緩存可以提升報表性能是不爭的事實,一般高端報表工具都會提供報表緩存功能,可將整個報表計算結(jié)果緩存在文件系統(tǒng)中,以便用戶下次訪問相同參數(shù)的報表時可以快速讀取緩存結(jié)果進(jìn)行展現(xiàn)。但有些情況下報表開發(fā)人員還希望對緩存的內(nèi)容進(jìn)行更準(zhǔn)確和靈活的控制,比如緩存的不是整個報表結(jié)果而是其中一部分、緩存內(nèi)容可被其它報表或程序復(fù)用,以及對不同的緩存結(jié)果設(shè)置不同的超時時間,從而應(yīng)對數(shù)據(jù)量和實時性方面的不同情況。這時,一般的報表緩存就無法滿足需求了。

集算器與報表結(jié)合使用時,可以幫助開發(fā)人員靈活控制緩存內(nèi)容。這里我們將開發(fā)人員在使用集算器可以靈活控制的報表緩存內(nèi)容稱為可控緩存??煽鼐彺婵梢詭砀蟮撵`活性和好處,充分解決實際應(yīng)用中的報表性能問題。下面我們就對前面提到的部分緩存、緩存復(fù)用和設(shè)置不同超時時間三個方面展開討論。

部分緩存

在報表開發(fā)中,有時并不希望將所有報表結(jié)果進(jìn)行緩存,這樣可以避免耗費過高的緩存成本(磁盤空間和應(yīng)用服務(wù)器資源開銷)。另外,當(dāng)報表中的部分?jǐn)?shù)據(jù)實時性要求很高,需要實時與數(shù)據(jù)庫交互進(jìn)行數(shù)據(jù)查詢,那么這部分?jǐn)?shù)據(jù)也不適合進(jìn)行緩存。

通過集算器的可控緩存可以將變化不頻繁的中間結(jié)果緩存起來,當(dāng)報表再次請求時,實時性要求高的數(shù)據(jù)仍然實時從數(shù)據(jù)庫中讀取,同時結(jié)合緩存中的非實時數(shù)據(jù)進(jìn)行報表計算,得到最終報表結(jié)果集。

常規(guī)緩存方案沒有這種緩存部分結(jié)果的功能,只能設(shè)置整個報表是否進(jìn)行緩存,這樣報表在涉及不同時效性數(shù)據(jù)時就會發(fā)生矛盾,而集算器實現(xiàn)的可控緩存顯然更加靈活,效率更高。

舉例

訂單(Orders)數(shù)據(jù)中超過 3 個月的數(shù)據(jù)就不再發(fā)生變化(冷數(shù)據(jù))
數(shù)據(jù)結(jié)構(gòu)如下:

實現(xiàn)報表的可控緩存

現(xiàn)查詢近 6 個月的訂單明細(xì)并匯總月訂單數(shù)量和金額。
報表表樣如下:

實現(xiàn)報表的可控緩存

直接從數(shù)據(jù)庫訂單表檢索 6 個月的數(shù)據(jù)實現(xiàn)雖然最簡單,但每次查詢都要從數(shù)據(jù)庫取全部數(shù)據(jù)顯然性能不高??梢詫?3 個月以上不變的數(shù)據(jù)在初次查詢時緩存起來,而 3 個月內(nèi)的數(shù)據(jù)仍然從數(shù)據(jù)庫讀取,這樣以后再查時直接讀緩存和數(shù)據(jù)庫數(shù)據(jù)來加速報表性能,可以顯著減少數(shù)據(jù)庫的計算時間和 JDBC 的傳輸時間。

集算器將根據(jù)查詢月份判斷:

  • 如果查詢的是歷史數(shù)據(jù)第一次查詢數(shù)據(jù)庫并寫緩存,以后直接讀緩存;

  • 如果查詢的是實時數(shù)據(jù)則每次都從數(shù)據(jù)庫讀??;

  • 如果查詢的數(shù)據(jù)包含歷史數(shù)據(jù)和實時數(shù)據(jù)則將歷史數(shù)據(jù)寫緩存,實時數(shù)據(jù)讀取數(shù)據(jù)庫。

集算器實現(xiàn)

參數(shù)

查詢參數(shù)為起止月份(每個月 1 日),實現(xiàn)中日期過濾數(shù)據(jù)均通過起止參數(shù)處理

實現(xiàn)報表的可控緩存

集算器數(shù)據(jù)準(zhǔn)備

ABC
1=filePath=”/usr/report/cache/”/ 緩存目錄
2=reportName=”orders_customer_month”/ 報表名稱,緩存使用報表名 + 參數(shù)命名
3=elapse@m(pdate@m(now()),-3)/ 三個月前日期
4=his_end=[end,A3].min()/ 歷史數(shù)據(jù)日期終值
5=pdate@me(end)/ 查詢?nèi)掌诮K值
6=sql=”select 公司名稱 客戶, 訂單 ID, 訂購日期, 訂單金額 from 訂單, 客戶 where 訂單. 客戶 ID= 客戶. 客戶 ID and 訂購日期 >=? and 訂購日期 <=?”

7=f=file(filePath/reportName/”=”/begin/”+”/his_end)/ 緩存文件
8=rs=[]/ 報表結(jié)果集
9if f.exists()// 如果有緩存
10
=f.import@b()/ 歷史數(shù)據(jù)讀緩存
11
>rs=rs|B10 / 緩存結(jié)果添加到結(jié)果集
12
=elapse@m(A3,1)/ 查詢數(shù)據(jù)庫起始日期
13
if B12<end/ 有實時數(shù)據(jù)查詢數(shù)據(jù)庫
14

=connect(“demo”)
15

>rs=rs|C14.query@x(sql,B12,A5)
16
return rs
17else// 無緩存
18
=connect(“demo”)
19
=rs=B18.query@x(sql,begin,A5)/ 全量數(shù)據(jù)讀庫
20
if begin<his_end/ 將歷史數(shù)據(jù)寫入緩存
21

=B19.select(訂購日期 >=begin && 訂購日期 <=A5)
22

>f.export@b(C21)
23
return rs

腳本解析:

1、A1-A2 分別設(shè)置緩存目錄和報表名稱,報表名稱用于緩存文件命名

2、A3-A5 根據(jù)月份參數(shù)計算歷史數(shù)據(jù)日期、實時數(shù)據(jù)日期等

3、A6 為查詢 SQL,由于后面會重復(fù)使用,這里將其賦值給 sql 變量

4、A7 設(shè)置緩存文件,文件名為:報表名 = 緩存起始月 - 緩存終止月,如:orders_customer_month=2014-01-01+2014-04-01

5、A8 定義報表數(shù)據(jù)集變量 rs,后續(xù)讀緩存和查詢數(shù)據(jù)庫結(jié)果都會追加到 rs 中

6、A9-C16 判斷緩存(包含三個月以上數(shù)據(jù))如果存在,則根據(jù)查詢月份讀取緩存歷史數(shù)據(jù)(B10),如果還包含實時數(shù)據(jù)則查詢數(shù)據(jù)庫(C15),結(jié)果集追加到 rs 中并為報表輸出結(jié)果(B16)

7、A17-C23 如果沒有緩存(可能是初次查詢,也可能查詢的是實時數(shù)據(jù)),則直接查詢數(shù)據(jù)庫并返回結(jié)果(B19),若查詢數(shù)據(jù)中包含歷史歷史數(shù)據(jù),則寫緩存(C21 和 C22)

報表調(diào)用

這里假定讀者已經(jīng)了解集算器與報表的關(guān)系,集算器僅為報表提供數(shù)據(jù)準(zhǔn)備,將計算結(jié)果以數(shù)據(jù)集的方式提供給報表進(jìn)行呈現(xiàn)。集算器腳本可以被潤乾報表 5.0 及以上版本直接引用(集算器數(shù)據(jù)集);如果是其他報表工具,集算器提供了標(biāo)準(zhǔn) JDBC 和 ODBC 接口,可以采用類似調(diào)用存儲過程的方式調(diào)用集算器腳本,詳細(xì)可以參考教程《應(yīng)用集成 - 被 JAVA 調(diào)用》章節(jié),以及《集算器與 BIRT 集成》或《集算器與 JasperReport 集成》。

以上通過舉例說明了通過集算器實現(xiàn)報表緩存部分結(jié)果提升報表性能的過程,這種方式可以靈活控制緩存內(nèi)容,加速報表運行。此外,將結(jié)果緩存到磁盤避免了通過數(shù)據(jù)庫 JDBC 取數(shù)效率低下的問題,數(shù)據(jù)量大時尤其適用,同時由于緩存無需和數(shù)據(jù)庫交互,降低了數(shù)據(jù)庫的訪問和計算壓力,在報表加速的同時緩解了數(shù)據(jù)庫負(fù)擔(dān)。

值得注意的是,業(yè)務(wù)數(shù)據(jù)無論是否分庫都可以使用這個方式提升報表性能。

緩存復(fù)用

集算器實現(xiàn)的可控緩存可以復(fù)用,一個報表的緩存結(jié)果(部分或全部)可以被其他報表或程序讀取并使用,而不必像常規(guī)報表緩存方案那樣重復(fù)緩存同樣的結(jié)果,這同樣也會大幅度提高整體緩存的效率。

與緩存部分結(jié)果適應(yīng)實時性要求的情況類似,當(dāng)其他報表或程序使用某個報表的緩存結(jié)果時,只需從緩存中(一般是磁盤文件)讀取,并與報表中其他數(shù)據(jù)來源(可能是 DB、文件,或是另一個報表的緩存)進(jìn)行混合運算,就能得到報表需要的結(jié)果集。而常規(guī)的報表緩存以報表模板為單位進(jìn)行緩存,彼此無法復(fù)用,在造成資源浪費之外還會增加一定的性能開銷。

上例中,如果另一張報表希望按客戶來匯總訂單情況:
報表表樣如下:

實現(xiàn)報表的可控緩存

熟悉報表的開發(fā)者都知道,這兩張報表只是分組方式不同,數(shù)據(jù)源是完全一樣的,這樣我們就還可以使用上面的代碼獲取數(shù)據(jù)源,并且生成和訪問緩存,這兩張報表就可以共用緩存了。

設(shè)置不同的超時時間

我們都知道緩存一定都會有超時時間,超過時間后的緩存就會因為失效而被清除,報表再訪問時需要重新生成緩存文件。

一般報表工具的緩存超時時間會在配置文件中設(shè)置,如 3600s 或 7200s,這種設(shè)置有時作用于單張報表的所有參數(shù),有時甚至作用于所有報表,換句話說,整個報表甚至整個系統(tǒng)必須使用同樣的設(shè)置。

顯然,這種做法的性能并不高,很難兼顧不同更新頻率的數(shù)據(jù)。如果能夠針對不同的報表場景設(shè)置不同的超時時間,那樣會更加有效。例如,針對大量歷史數(shù)據(jù)進(jìn)行查詢的報表,由于歷史數(shù)據(jù)的變化不大,我們希望報表的緩存結(jié)果可以保存較長時間,以便每次查詢時都能從緩存中快速讀取結(jié)果;而針對數(shù)據(jù)變化頻繁,實時性要求較高的報表則希望超時時間較短,以便充分滿足數(shù)據(jù)的實時性要求。

集算器實現(xiàn)的可控緩存允許開發(fā)人員針對不同的報表需求設(shè)置不同的超時時間,以應(yīng)對上述提到的報表場景,例如可以在第一個例子中增加超時設(shè)置。這種做法提供了更高的靈活性,使得報表緩存達(dá)到真正意義上的精確可控。

舉例

沿用第一個例子,我們增加相應(yīng)的超時設(shè)置。由于該報表月末查詢比較頻繁,因此希望緩存有效時間長一些(7 天)。這時只需要將 A9 的表達(dá)式改為:

A9: if f.exists()&& interval(f.date(),now())<=7

判斷緩存文件如果存在,并且緩存日期為 7 天內(nèi),則讀取緩存。

本文的例子中用到的是單數(shù)據(jù)集報表,而實際上多數(shù)據(jù)集報表需要可控緩存的情況更多。一個報表的多個數(shù)據(jù)集很可能變化的頻率相差很大,有的數(shù)據(jù)集很穩(wěn)定,幾天甚至幾個月都不會變,而有的數(shù)據(jù)集則可能隨時都在變化。采用部分緩存并設(shè)置不同的超時時間,這時對緩存的可用性就非常有意義了,能夠在確保報表數(shù)據(jù)正確性的同時充分利用緩存手段提高訪問性能。

需要說明的是,集算器實現(xiàn)可控緩存也有其適用場景,并不能完全取代常規(guī)緩存,常規(guī)緩存手段會連同報表計算結(jié)果以及呈現(xiàn)屬性保存在一起,而這里的可控緩存只緩存數(shù)據(jù),在呈現(xiàn)時還要再次進(jìn)行外觀計算,因此更適用于數(shù)據(jù)計算強(qiáng)度較高,但外觀計算強(qiáng)度較低的場景。在實際應(yīng)用中,可以取長補短,將兩者結(jié)合起來使用。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI