版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、mondrian源碼分析1.概述11.1.若干概念11.2.架構(gòu)22.靜態(tài)類包分析32.1.包解釋32.2.Schema manger部分42.3.包mondrian.calc42.4.包mondrian.olap接口52.4.1.mdx函數(shù)包52.4.2.funCall52.4.3.Query類62.5.包mondrian.rolap計算層62.5.1.成員讀取包MemberReader62.5.2.單元格讀取CellReader82.5.3.RolapResult類112.5.4.RolapEvaluator類122.5.5.關(guān)于排序122.6.聚集層Star layer132.6.1.概
2、述132.6.2.聚合裝載過程132.6.3.segment詳解142.6.4.緩存失效控制173.交互管理層183.1.初始化MondrianModel183.2.獲取結(jié)果集194.修改點224.1.mondrian角色參數(shù)化224.2.緩存失效控制224.3.connection創(chuàng)建參數(shù)優(yōu)化234.4.維度成員排序234.5.對mondrian bug的修正244.6.to-do List241. 概述1.1. 若干概念成員(member):成員是代表維度中一次或多次數(shù)據(jù)出現(xiàn)的項。度量值也可以算作一個維度,因此一個具體度量值項也可以作為一個成員。元組(tuple):是向量,用于定義來自多維
3、數(shù)據(jù)集的數(shù)據(jù)切片;它由來自一個或多個維度的單個成員的有序集合組成。元組用于標識來自多維數(shù)據(jù)集的特定多維數(shù)據(jù)塊;由來自多維數(shù)據(jù)集中各個維度的一個成員組成的元組完全描述單元值。換言之,元組是一種成員向量。例如:(時間.下半年, 路線.非陸地.航空),由單個成員組成的元組也可括在圓括號內(nèi),但這不是必需的。單元(cell):多維成員的交集創(chuàng)建單元,可以是單個單元或單元塊。元組唯一標識多維數(shù)據(jù)集中的一部分;它不必指某個特定單元,也不必包括多維數(shù)據(jù)集中的所有維度。集合(set):集合是零個、一個或多個元組的有序集合。集合最常用于在 MDX 查詢中定義軸維度和切片器維度,并且同樣可能只具有單個元組或可能在某
4、些情況下為空。下面的示例顯示具有兩個元組的集合: (時間.上半年, 路線.非陸地.航空), (時間.下半年, 路線.非陸地.海路) 1.2. 架構(gòu)mondrian總共包含四個層次:表示層,計算層,聚集層,存儲層.。表示層(presentation layer):指最終呈現(xiàn)在用戶顯示器上的,以及與用戶之間的交互,有許多方法來展現(xiàn)多維數(shù)據(jù),包括數(shù)據(jù)透視表,餅,柱,線狀圖. 計算層(dimensional layer):分析,驗證,執(zhí)行MDX查詢. 一個mdx查詢語句會有多個處理階段。先是計算軸,然后是軸上的單元值。為效率起見,計算層批量將單元請求發(fā)送到聚集層。請求轉(zhuǎn)換器允許程序操作存在的請求,而不
5、是為每個請求從頭構(gòu)造mdx請求。元數(shù)據(jù)描述了計算模型和它怎么匹配到關(guān)系模型。聚集層(star layer):一個聚集指內(nèi)存中一組計算值(cell),這些值通過維列來限制.計算層發(fā)送單元請求,如果請求不在緩存中,或者不能通過旋轉(zhuǎn)聚集導(dǎo)出的話,聚集層向存儲層發(fā)送請求. 聚集層是一個數(shù)據(jù)緩沖層(cache),從數(shù)據(jù)庫來的單元數(shù)據(jù),聚合后提供給計算層。聚集層的主要作用是提高系統(tǒng)的性能。 存儲層:提供聚集單元數(shù)據(jù)(cell)和維表的成員(member),這些層可以不在同一機子上,但是計算和聚集層必須在同一臺機子上。有三種需要存儲的數(shù)據(jù):事實數(shù)據(jù)(事實表)、維度表和聚集數(shù)據(jù)(即聚合表)架構(gòu)圖如下:2. 靜
6、態(tài)類包分析2.1. 包解釋mondrian.calc 提供編譯好的表達式。mondrian.gui 設(shè)計Mondrian schema的圖形接口mondrian.i18n 國際化和本地化工具mondrian.mdx 為mdx表達式定義解析樹mondrian.olap 核心包,定義了連接和schema的元模型,用來執(zhí)行查詢mondrian.olap4j 中間層,olap服務(wù)器的驅(qū)動,用來代替jolap的mondrian.recorder 任務(wù)處理記錄接口mondrian.rolap olap包的數(shù)據(jù)訪問層的實現(xiàn)mondrian.spi 用戶自定義擴展的服務(wù)端支持接口mondrian.tui Mo
7、ndrian文本用戶接口mondrian.udf 用戶定義方法mondrian.util Mondrian工具包mondrian.web Mondrian的servlet和tag庫mondrian.xmla xml for analysis API的實現(xiàn)2.2. Schema manger部分Mondrian.rolap.RolapSchema類是mondrian schema的核心類,該類在在建立RolapConnection時被建立,但是有個schema Pool維護著schema的緩存,參見RolapSchema.Pool內(nèi)部類。在RolapSchema對象生成之前,首先有個原始的Mon
8、drianDef$Schema對象,該對象相當(dāng)于mondrian schema xml文件的簡單對應(yīng),由xml解析器直接生成。具體來說首先由xml文件解析成dom對象,然后再生成更加結(jié)構(gòu)化的MondrianDef$Schema,最后再load成更加高級的RolapSchema對象,具體參見RolapSchema.load(String catalogUrl,String catalogStr);以MondrianDef$Schema或RolapSchema對象為根,都還會有一系列的內(nèi)部類去對應(yīng)于mondrian schema下的子元素。如果一個Hierarchy的hasAll為true,則會有
9、一個all member,對應(yīng)著也需要一個虛擬的all level,位于該Hierarchy的levels0位置。2.3. 包mondrian.calcCalc是所有可計算表達式的基接口。在mondrian中關(guān)于表達式有如下兩個概念: n The logical language of parsed MDX fragments (Exp). n The phyiscal language of compiled expressions (Calc). 兩種語言可以允許我們將邏輯語言(即mdx語言) 和物理語言(how it is to be evaluated) 分開. 物理語言對類型的要求更
10、加嚴格, and certain constructs which are implicit in the logical language (such as the addition of calls to the <Member>.CurrentMember function) are made explicit in the physical language。Calc接口針對各種類型有許多子接口:其中IntegerCalc, BooleanCalc, DoubleCalc, StringCalc是數(shù)值型的,MemberCalc, LevelCalc, HierarchyCa
11、lc, DimensionCalc則用于olap模型中的元素。每一個子接口有都有一個實現(xiàn)的虛基類:AbstractIntegerCalc, AbstractBooleanCalc, AbstractDoubleCalc, AbstractStringCalc, AbstractMemberCalc, AbstractLevelCalc, AbstractHierarchyCalc, AbstractDimensionCalc。表達式(Expression)通常由表達式編譯者(ExpCompiler)創(chuàng)建。對于一個給定的表達式通常有若干個evaluation策略,表達式編譯者在編譯過程中可以給我
12、們一個選擇的機會。2.4. 包mondrian.olap接口Mondrian的核心包,定義了連接對象和完整的olap模型結(jié)構(gòu)元對象,并且允許執(zhí)行mdx查詢語句。2.4.1. mdx函數(shù)包 定義了mdx內(nèi)置的函數(shù)集。函數(shù)(function)的定義:參數(shù)描述例子name函數(shù)名"Members"signature函數(shù)標志"<Dimension>.Members"description函數(shù)描述"Returns the set of all members in a dimension."flagsEncoding of the s
13、yntactic type, return type, and parameter types of this operator. The encoding is described below."pxd"The flags field is an string which encodes the syntactic type, return type, and parameter types of this operator. The first character determines the syntactic type, as described by FunUti
14、l.decodeSyntacticType(String). The second character determines the return type, as described by FunUtil.decodeReturnCategory(String). The third and subsequence characters determine the types of the arguments arguments, as described by FunUtil.decodeParameterCategories(String). For example, "pxd
15、" means "an operator with property syntax (p) which returns a set (x) and takes a dimension (d) as its argument".2.4.2. funCallA FunCall is a function applied to a list of operands. The parser creates function calls as an unresolved function call. The validator converts it to a resolv
16、ed function call, which has a function definition and extra type information。參見:Mondrian.olap. ResolveFunCall UnresolveFunCall 2.4.3. Query類用于mdx 查詢。2.4.3.1. 創(chuàng)建query創(chuàng)建:Connection.parseQuery(java.lang.String)。 創(chuàng)建mondrian.olap.Parser類,基于java_cup實現(xiàn),調(diào)用其parse或debug_parse()方法,里面最主要 是CUP$Parser$do_action()
17、方法,內(nèi)部針對所有語句詞句做了解析。其中case75:生成最后的mondrian.olap.Query對象,內(nèi)部調(diào)用parser.makeQuery()方法,內(nèi)部初始化時會再調(diào)用query的resolve,mondrian.olap.QueryAxis的resolve(),進而會執(zhí)行數(shù)據(jù)庫。2.4.3.2. 執(zhí)行query執(zhí)行:Connection.execute(mondrian.olap.Query)返回結(jié)果: Result.有些查詢從緩存中讀取,非常迅速。當(dāng)也有些需要花費些時間,這時可以通過MondrianProperties.QueryTimeout參數(shù)設(shè)置timeout。如果想控制返
18、回結(jié)果不至于太大,可以通過MondrianProperties.QueryLimit參數(shù)控制返回的cell數(shù)目。在查詢執(zhí)行的任何時候,另一個進程都可以通過cancel()方法取消該查詢,此時Connection.execute(Query)會拋出異常。2.5. 包mondrian.rolap計算層實現(xiàn)最終的實際的olap數(shù)據(jù)訪問功能,包括讀取維度成員值和cell值。2.5.1. 成員讀取包MemberReader2.5.1.1. 概述包路徑:Mondrian.rolap。該部分的起點是RolapEvaluator類。當(dāng)一個類似于“member.children”的成員表達式被請求時, Rola
19、pEvaluator將調(diào)用RolapSchemaReader對象. RolapSchemaReader將再負責(zé)調(diào)用各個MemberReader對象(每個維度一個memberReader)。在大部分場合下,將使用SmartMemberReader 來迅速返回所需要的維度成員值。2.5.1.2. SmartMemberReaderSmartMemberReader實現(xiàn)了MemberReader接口,它實現(xiàn)了維度成員及其子成員的緩存,如果有一個成員位于緩存中,則還會有一個其子成員的列表。它同時緩存了level下的成員們。該類主要的成員有:source:MemberReader,用于實際從數(shù)據(jù)庫中讀取
20、維度成員值。mapMemberToChildren:map,實現(xiàn)成員及其子成員的映射,key為RolapMember,value為List<RolapMember>。mapKeyToMember: map ,實現(xiàn)所有成員的緩存,其中的key為MmberKeymapLevelToMembers: map,實現(xiàn)級別及其所有成員的映射,key為RolapLevel,value為List<RolapMember>。上述的source其實為mondrian.rolap.SqlMemberSource類,該類中反過來又存儲了SmartMemberReader對象,作為其cache成
21、員屬性。成員讀取過程:n smartMemberReader.getMemberChildren(parentMembers,children,constrain);n 最終通過source.getMemberChildren(),其中反過來會把找到的children賦予mapKeyToMember。n 最終除了將結(jié)果返回在children輸出參數(shù)中,同時也對mapMemberToChildren賦值了。另外,smartMemberReader.getMembersInlevel()實現(xiàn)了對mapLevelToMembers的緩存。在new RolapEvaluator()時被調(diào)用。在讀取時會
22、對成員進行order by(如果設(shè)置了ascending的話。)2.5.2. 單元格讀取CellReader2.5.2.1. 概述包路徑:Mondrian.rolap。Cells會被求值多次。第一次時, Evaluator使用FastBatchingCellReader來求值。當(dāng)一個單元被求值時,evaluateCurrent()被調(diào)用。此時FastBatchingCellReader并沒有被調(diào)用,而是為那個cell記錄了一個 CellRequest并且return (not throw) an exception。在所有的cells都有了對應(yīng)的CellRequests之后, Aggregat
23、ion會生成 SQL,以一個單獨的sql請求來載入所有的cells。然后由AggregatingCellReader 重新計算cells,從緩存中返回cells值。2.5.2.2. FastBatchingCellReader類主要方法,Object get(Evaluator evaluator)n 首先根據(jù)當(dāng)前的上下文環(huán)境(即一組members)創(chuàng)建cellRequest,cellRequest中包含了所有必要的從star中取值的信息。該組members的交集便是要求值的單元格,其中切片軸上的成員和其他軸上的成員完全同等對待;其中度量軸上的成員要求上StoredMeasure(非計算成員C
24、aculatedMember);度量值上的成員位于第一個。通過調(diào)用request的addConstrainedColumn()方法把各member對應(yīng)的column和value(屬StarColumnPredicate)值加至到request中.n 調(diào)用AggregationManager.getCellFromCache(request,pinnedSegments)方法從緩存中獲取cell值。首先根據(jù)request中的列組索引標識從緩存中獲取aggreation緩存對象,如果為空說明緩存還未建立則直接返回null,如果有值則調(diào)用aggregation.getCellValue(measur
25、e,colValueKeys)方法獲取緩存的cell值;getCellValue內(nèi)部首先會根據(jù)measure查找匹配的segment,然后調(diào)用segment.getCellValue(keys)從segment的dataset緩存集中查找相應(yīng)的cell值。n 如果getCellFromCache返回為null則調(diào)用recordCellRequest()記錄需求。這些cell request會被組織成多個cell request batch,以便將來聚合層進行批讀取以提高效率。關(guān)于batch的詳細討論參見下面Batch類章節(jié)。n 上層會在適當(dāng)?shù)臅r候調(diào)用batchCellReading.loadA
26、ggregations()以實際讀取這些cell值,前提是batches對象中已有cellRequest了。每個batch的讀取參見batch. loadAggregation()方法,最終調(diào)用聚合層的方法,參見aggreation.load(.)。2.5.2.3. FastBatchingCellReader.Batch類每個batch對應(yīng)與一組特定的columns環(huán)境下的cell求?。ň哂邢嗤牧泻土兄?列值是具體的值,不會是“all”值));從batch的屬性可以看出batch包含了哪些上下文:n RolapStar.Column,這個指明了基于哪些列(也即基于哪些維度,包括切片維度)進
27、行讀?。籲 Set<StarColumnPredicate>,保存了每列的限定值,對于一列而言,限定值可能會有多個(畢竟是批處理,一次請求多個);n MeasureList,指明求取哪些度量值上的cell(度量值本質(zhì)是度量維上的限定值)。n BitKey,該batch的唯一索引。如圖所示的一個mdx查詢結(jié)果界面:此時會產(chǎn)生兩個batch,每個batch最終可能會產(chǎn)生若干segment,segment是cells的集合,segment數(shù)和度量值個數(shù)相同。n 一個batch是(其中“當(dāng)量數(shù)/適應(yīng)交通量=擁擠度”,擁擠度是計算成員),最終產(chǎn)生3個segment,每個segment只有一個
28、cell:Ø (地市=寧波市,measure=觀察里程)Ø (地市=寧波市,measure=當(dāng)量數(shù))Ø (地市=寧波市,measure=適應(yīng)交通量)n 另一個batch是(其中的G310等是路線代碼,最終過濾掉空值后就剩下兩個了) ,最終產(chǎn)生3個segment,每個segment有多個cell:Ø (地市=寧波市,roadId in (G310,G322,G210,S321.),measure=觀察里程)Ø (地市=寧波市,roadId in (G310,G322,G210,S321.),measure=當(dāng)量數(shù)) Ø (地市=寧波市,
29、roadId in (G310,G322,G210,S321.),measure=適應(yīng)交通量)2、 2.5.3. RolapResult類RolapResult 是一個運行中的請求的結(jié)果集。Mondiran的執(zhí)行結(jié)果由RolapResult類表單,由于mdx查詢語句本身就包含on rows(行軸上)、on columns(列軸上)和where部分(切片軸上),結(jié)果集中相對應(yīng)的為ROlapAxis對象,這其中有個sliceAxis對象。因此結(jié)果集是由若干ROlapAxis對象和一個RolapCell組構(gòu)成的。每個axis對象又由若干Position對象組成,每個Position對象又可能由若干m
30、ember組成(注意一個postion會橫跨多個維度的成員)。注意ROlapAxis是抽象類,實際的對象類可能隨著不同的軸是不同的。如圖:圖中,column軸上兩個position(每個position含有一個成員),分別是: Measures.YJDMeasures.GCLCRow軸上有三個position(每個position含有二個成員),分別是:dimLX.All dimLXs, dimTime.All dimTimesdimLX.All dimLXs.寧波梁輝, dimTime.All dimTimesdimLX.All dimLXs.同江三亞, dimTime.All dimTim
31、es切片軸上則有一個position:dimStation.All dimStations.寧波市單元值們則放置在RolapResult中的cellInfos對象里,屬CellInfoContainer接口,其中存放著CellInfo,并通過Cellkey進行索引。CellKey:用于在maps里訪問cellinfo時使用的鍵值,根據(jù)cell的位置來決定鍵值。CellKey共有四個默認實現(xiàn),及zero、one、two、three和many版的實現(xiàn),分別對應(yīng)著軸的個數(shù)。這些類中關(guān)鍵的屬性便是存儲各軸的位置值。CellInfo、CellInfoContainer:內(nèi)部類。CellInfo包含了一個
32、cell所需要的所有信息(最關(guān)鍵的包含value值和一些formatter設(shè)置);最終將作為構(gòu)造ROlapCell對象的參數(shù)。CellInfoContainer顯然是cellInfo的容器,并使用CellKey來索引。ROlapCell:最終返回給jpivot的cell單元值。2.5.4. RolapEvaluator類最終負責(zé)在多維環(huán)境中執(zhí)行mdx表達式。該類中維護一個很重要的對象,即currentMembers,該上下文對象針對每個維度都包含了一個成員;通過setContext方法用來設(shè)置當(dāng)前維度,以開始計算當(dāng)前維度組合下的表達式值。2.5.5. 關(guān)于排序排序有單元值排序和維度成員排序兩種
33、場景,但單元值排序優(yōu)先級更高,只有當(dāng)單元值排序相當(dāng)時,才再對成員值進行排序。單元值排序有六種,升序、降序、打破Hierarchy升序、打破Hierarchy降序、top count、bottom count。其中前四種參見:FunUtil.SortMembers()中的方法,這是總?cè)肟冢渲杏蠦reakMemberComparator、HierarchicalMemberComparator、BreakArrayComparator、HierarchicalArrayComparator等排序器(Array包含多個member,此時相當(dāng)于cell上下文環(huán)境由多個維度參與)。對于array類排序
34、,參見其中的public int compare(Member a1,Member a2)方法;對于單member類排序,參見其中的public int compareInternal(Membera1,Member a2)方法。維度成員排序似乎有三種:按照orderKey、按照ordinary、按照值(參見RolapMpareTo()方法,最終相當(dāng)于按字符串或數(shù)值比較,其中第三種內(nèi)部又會用到ascending屬性),這個是我們自己新增的屬性。具體參見FunUpareSiblingMembers()方法。2.6. 聚集層Star layer2.6.1. 概述包,管理聚合緩存,這些緩存中包含著各
35、單元格值。RolapStar中含有aggregation(聚合),一個aggregation是針對一組columns的,該聚合可以包含多個segment,同一個aggregation中的每個segment都將覆蓋到相同的列集合;每個segment表達了一組cell值,這些cell自然是由具體的列值和一個必備度量值(如下面的unit sales)來限定,如:(Unit sales, Gender = 'F', State in 'CA','OR', Marital Status = anything),由于其中的列值可能會取多個,因此最終表達的ce
36、ll值也可能是多個。RolapStar中有一個aggregations,是一個map對象,通過request的constrainedColumnsBitKey來索引一個aggregation。2.6.2. 聚合裝載過程實際中無論是底層的單元值還是聚合后的單元值都是放在聚合對象aggregation中的。以aggregation.load(colums,measures,predicates,pinnedSegments)為入口:n 參數(shù)中的除了measure不一樣外,其限定的列(colums)及列值(prediactes)都是一致的。因此轉(zhuǎn)換成對對若干segment的求值: Segment.l
37、oad(segment,.),在該方法內(nèi)部:Ø 首先根據(jù)segments中的信息生成sql查詢語句,有兩個不同的生成類:AggQuerySpec和SegmentArrayQuerySpec,前者用于找到聚合表情況下的sql語句生成,后者用于基于原始表的sql語句生成。具體可以參見它們的generateSqlQuery()方法,這里注意對以distinct count有不同的生成方法。Sql生成的核心類是sqlQuery,類似于交換系統(tǒng)中的QuerySqlFactory類。注意:聚合操作如avg、sum等都最終還是利用sql語句實現(xiàn)的,并非mondiran自己實現(xiàn)這些聚合功能。
38、6; 利用jdbc,執(zhí)行sql語句,獲取到j(luò)dbc 結(jié)果集。參見mondrian.rolap.RolapUtil.executeQuery()方法。Ø 解析結(jié)果集,將結(jié)果集中的數(shù)據(jù)填充到rows二維數(shù)值中,并且把各列的值也填充好。如圖:結(jié)果集每條記錄的值如寧波市、G010.,前面兩個是維度列值,后面幾個是度量值。各列的值(其中第0項值為:寧波市):Ø 決定采用稀疏性(sparse)還是稠密性(dense)SegmentDataSet存儲;并創(chuàng)建該空的DataSet對象。每個segment關(guān)聯(lián)一個DataSet對象;但其稀疏性還是稠密性都是一致的。注意dataset中單元值的
39、個數(shù)可能是1個或多個,是由各限定列的指定值個數(shù)乘積,若所有限定列都取單值,則顯然最終決定一個唯一的單元。Ø 將上述的rows中間集轉(zhuǎn)換到SegmentDataSets集中。最后再分揀給每個segment,確保每個segment的setData(SegmentDataSet)被調(diào)用。n 若干排序:ValueColumnConstraintComparator2.6.3. segment詳解n 下圖是有兩個限定列的兩個segment的描述(注:其中roadid列雖然指定了8個候選值,但由于使用了空行/列過濾,最后只剩下兩個路線有值,故最后segment結(jié)果集的單元數(shù)也只有兩個,對應(yīng)于G0
40、10和G318的):其中第二個對應(yīng)的dataset為:317.769, 120.604對應(yīng)的透視界面為(參見其中的“觀測里程”度量值,與上面的dataset一致):n 再譬如有三個限定列的segment描述,它們位于另一個aggreation對象中:(其中timeId列的any代表所以可能的時間值,共有20032005三個年,所以最終該segment共有3個cell值)對應(yīng)的dataset為:129.910, 129.909, 57.950對應(yīng)的透視界面為(顯然該aggreation還有另外一個segment,其中的roadId對應(yīng)于G010寧波梁輝):n 再譬如維度中有多個層次的情況時,一個
41、維度會對應(yīng)多個列:Query query = connection.parseQuery( "SELECT" + " Time.1997," + " Time.1997.Children ON COLUMNS," + " Customer.USA," + " Customer.U
42、SA.OR," + " Customer.USA.WA ON ROWS" + "FROM Sales");Result result = connection.execute(query);該語句執(zhí)行后產(chǎn)生的segment分別為(除了第一個外,其他segment都會包含多個cell,因為它們的限定列中含有多值的情況):Segment YN#1Year Nation Unit Sales1997 USA xxxPredicates: Year=1997,
43、Nation=USASegment YNS#1Year Nation State Unit Sales1997 USA OR xxx1997 USA WA xxxPredicates: Year=1997, Nation=USA, State=OR, WASegment YQN#1Year Quarter Nation Unit Sales1997 Q1 USA xxx1997 Q2 USA xxxPredicates: Year=1997, Quarter=any, Nation=USASegment YQNS#1Year Quarter Nation State Unit Sales199
44、7 Q1 USA OR xxx1997 Q1 USA WA xxx1997 Q2 USA OR xxx1997 Q2 USA WA xxxPredicates: Year=1997, Quarter=any, Nation=USA, State=OR, WA2.6.4. 緩存失效控制為了提高訪問效率,必須要使用緩存;但使用緩存必須在數(shù)據(jù)庫底層數(shù)據(jù)發(fā)生變化時做好數(shù)據(jù)的失效和刷新工資。老版的做法非常粗略:mondrian.rolap.RolapSchema.clearCache();這意味著連mondrian schema都被失效,與之關(guān)聯(lián)的全部緩存也都被失效。新版的做法是引入了mondrian.
45、olap.CacheControl接口,可以很精細地由應(yīng)用控制緩存。為此mondrian引入了cell region的概念,region是由一個或多個成員定義出的多維空間(定義時可以指定是否包含這些成員的子成員)。為了使緩存失效,你需要首先定義一個region,然后告訴mondrian失效該region內(nèi)的所有cells;為了確保一致性,mondrian還會自動地把這些cell的聚合單元也一起失效。具體參見CacheControl.CellRegion類。最終調(diào)用cacheControl.flush(cellRegion)。具體失效時,還是針對segment進行的,因為mondiran中的ce
46、ll緩存是通過segment組織的。失效發(fā)生時,可能segment中的部分cell無用了,但mondrian并不會真正刪除這些cell,而是strengthened其predicates,例如失效前的某個segment為:1997 USA OR xxx1997 USA WA xxxPredicates: Year=1997, Nation=USA, State=OR, WA然后Crossjoin(time.1997.Q2,Customer.USA.OR)的cellRegion失效,此時該segment變?yōu)椋?997 USA OR xxx1997 USA WA xxxPredicates: Ye
47、ar=1997, Nation=USA, State=WA目前這樣處置未必最合理,因為會有內(nèi)存泄露。將來可能根據(jù)該segment中的cell達到一定的失效閥值,就徹底把該segment拋棄掉。Segment的合并也是將來應(yīng)考慮的事情,以減少segment碎片。維度成員值的緩存控制目前mondrian還未提供控制接口。但是metaCacheControl,例如控制schema xml等還是提供不少接口了,例如:l mondrian.rolap.RolapSchema.clearCache() l mondrian.olap.MondrianServer.flushSchemaCache() l
48、mondrian.rolap.cache.CachePool.flush() l mondrian.rolap.RolapSchema.flushRolapStarCaches(boolean) 該方法不失效schema,但失效緩存,在應(yīng)用層還不想使用cellRegion失效緩存前,可以適度使用。l mondrian.rolap.RolapSchema.flushAllRolapStarCachedAggregations() l mondrian.rolap.RolapSchema.flushSchema(String,String,String,String) l mondrian.rol
49、ap.RolapSchema.flushSchema(DataSource,String) 3. 交互管理層MondrianModel 是JPivot中用來展現(xiàn)一個MDX查詢的所有原數(shù)據(jù)的模型。這里主要講MondrianModel的三個方法,initialize(),getResult(),destroy()。3.1. 初始化MondrianModel1、 在jpivot.mondrian.MondrianModel執(zhí)行initialize()方法之前,先用MondrianModelFactory.Config對象為MondrianModel對象設(shè)置jdbc,schema url等參數(shù)。2、
50、.getConnection()方法,創(chuàng)建并返回mondrian.rolap.RolapConnection對象,置于變量monConnection中;創(chuàng)建連接的參數(shù)指定詳見mondrian.olap.RolapConnectionProperties。2.1 在創(chuàng)建RolapConnection對象的構(gòu)造函數(shù)中,會用對象池技術(shù)建立mondrian.rolap.RolapSchema對象。該對象會被緩存在對象池中,只會創(chuàng)建一次(RolapSchema對象中還有一個大對象xmlSchema,是純定義性質(zhì)的,);這里需要注意的是:n RolapSchema對象的建立有幾種方法:首先schema字符
51、串內(nèi)容本身可以通過參數(shù)直接傳遞進來;也可以通過url地址指定;還可以通過自定義的DynamicSchemaProcessor類來給定(這樣就有機會動態(tài)對schena內(nèi)容進行修改)。n RolapSchema對象本身的建立一般是從緩存中讀取,沒有時則創(chuàng)建。但若使用了上述的DynmicSchemaProcessor則每次都會重新創(chuàng)建;并且若指定了UseContentChecksum參數(shù) (將使用md5對字符串內(nèi)容編碼),若UseContentChecksum為true,則 md5編碼值與以前的不同,則即使存在了RolapSchema對象也會重新創(chuàng)建。可與DynamicSchemaProcessor
52、屬性一起用。n 在Mondrian新版本3.0中,RolapConnectionProperties 中除了定義了DynamicSchemaProcessor 和UseContentChecksum 參數(shù),還新增了UseSchemaPool屬性,如果該屬性為false,將禁用schema緩存。2.2 最后調(diào)用RolapSchema.createRole()方法創(chuàng)建該連接關(guān)聯(lián)的role對象(如果指定了的話);并創(chuàng)建ROlapSchemaReader對象(和role綁定的,讀取時會進行必要的控制)。2.3 根據(jù)傳入的參數(shù)設(shè)置locale,沒有的話按照en處理。3、調(diào)用connection的pars
53、eMDX(),最終調(diào)用ConnectionBase.parseQuery()方法準備好一個mondrian.olap.Query對象,置入成員變量monQuery;query對象由mondrian.olap.parse對象生成,該對象是一個自動生成的類,使用了javacup技術(shù)。3.2. 獲取結(jié)果集1、 之前確保MondiranModel中的monQuery對象已經(jīng)創(chuàng)建好。2、 Jpivot中,界面會調(diào)用jpivot.table.TableCompont對象的render方法進行繪制,最終會調(diào)用MondrianModel.getResult()的方法,但返回的是jpivot.olap.mode
54、l.Result對象,并非mondrian.olap.Result對象。2.1 首先執(zhí)行MondrianQueryAdapter對象queryAdapter的onExecute()。得到mdx語句。2.2 調(diào)用monConnection.execute(monQuery)獲取mondrian result對象;內(nèi)部會創(chuàng)建 new ROlapResult(monQuery,true),RolapResult得到的是運行中請求的結(jié)果,其中ture代表要實際裝載數(shù)據(jù)。2.3 內(nèi)部會進行Evaluator算法:顯式成員:在軸上的成員。隱式成員:不在軸上的成員,可能是在函數(shù)中。如果一個維度的成員都是隱式
55、成員,相當(dāng)于在切片上使用默認成員。有兩種特定維度:時間維度和度量維度。時間維度度量維度的默認成員是沒有所有的××的,約定成俗的是第一個度量。首先,RolapEvaluator會被創(chuàng)建。創(chuàng)建過程中,它會從每個hierarchy中獲取一個member,每個member是hierarchy的默認成員。對于大多數(shù)hierarchy,這個默認成員就是所有成員??赡苡袃煞N例外:1)hierarchy沒有所有成員;2)hierarchy有所有成員但是它不是默認成員。這樣的話,默認成員仍然會被使用,但是可能會有問題。然后載入所有無所有成員的hierarchy的根成員,載入非默認成員的所有的
56、成員。2.4 內(nèi)部會進行Evaluator算法,三大步驟:n Determine axes步驟:決定每個軸上的所有成員,但此時還不保存信息(不創(chuàng)建RolapAxis)。確定切片軸上的成員。軸上發(fā)現(xiàn)的成員都會被加入到AxisMember中。如果該成員是度量,則切片指明請求的度量,并將該度量放入evaluator的context中(取代cube中的第一個度量,即默認度量)。其它的切片成員也會被放入evaluator的context的。n execute axes步驟:為每個軸保存所有成員,創(chuàng)建RolapAxis對象(重復(fù)了第一步驟,只是此時創(chuàng)建了RolapAxis對象,該對象是結(jié)果集中的維度成員值
57、部分)。執(zhí)行第一步和第二步時確保數(shù)據(jù)已經(jīng)載入。n get cell步驟:根據(jù)軸上的成員值計算并存儲每個單元值(結(jié)果集的cell值部分),參見executeBody()方法,內(nèi)部主要調(diào)用executeStripe()方法,Ø ExecuteStripe()方法內(nèi)部采用遞歸方法依次獲取每個單元值,從行軸開始(軸位置索引最大的那個),針對每個行軸的mondrian.olap.position進行循環(huán),在一個循環(huán)內(nèi)再針對列軸的每個position進行循環(huán),求得交叉點的cell值。每個position由一個或多個維度成員值組成,具體的個數(shù)同該軸上交叉的維度數(shù);在計算某cell值之前,會依次用該cell的member值(包括切片上的維度值)設(shè)置好evaluator的context。最后調(diào)用evaluator.evaluateCurrent()方法獲得當(dāng)前context下的cell值。Ø Evaluator.evaluateCurrent()內(nèi)部可能會執(zhí)行到間接遞歸調(diào)用,這個發(fā)生在執(zhí)行計算成員值的情況下;此時為了計算成員,首先需要獲取其他度量值,而為了獲取這些前置的度量值又要調(diào)用evaluateCurrent()方法。EvaluateCurrent內(nèi)真正獲取單元值的地方是調(diào)用:ce
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 施工安全教育培訓(xùn)計劃
- 塊料樓地面施工方案范文
- 合同管理制度及合同簽訂流程
- 安裝冬季施工措施
- 花籃式懸挑腳手架施工危險源分析及預(yù)防措施
- 鋁合金門窗施工方案范文
- 車位購買權(quán)轉(zhuǎn)讓協(xié)議
- 開放式基金傳真交易協(xié)議
- 結(jié)構(gòu)工程承包合同范本
- 國際民間貿(mào)易協(xié)議書
- 與信仰對話 課件-2024年入團積極分子培訓(xùn)
- 中學(xué)美術(shù)《剪紙藝術(shù)》完整課件
- 國家職業(yè)技術(shù)技能標準 X4-07-99-10 禮儀主持人(試行)勞社廳發(fā)200633號
- 施工現(xiàn)場預(yù)防坍塌、高處墜落事故專項整治工作總結(jié)
- 醫(yī)院感染暴發(fā)及處理課件
- 小學(xué)五年級體育教案全冊(人教版)
- 教科版(2024秋)六年級上冊1.各種形式的能量 教案
- 二年級數(shù)學(xué)看錯數(shù)字問題專項練習(xí)
- 2024年1月國家開放大學(xué)專科《法理學(xué)》期末紙質(zhì)考試試題及答案
- 手機短視頻拍攝與剪輯(微課版) 課件 第7章 視頻攝像
- 反訴狀(業(yè)主反訴物業(yè))(供參考)
評論
0/150
提交評論