1. 程式人生 > >Mondrian入門介紹之schema manager

Mondrian入門介紹之schema manager

原文:http://www.chinabi.net/CIO/knowledge/200809/1168.html

1 olap基本概念

  聯機分析處理(On Line Analytical Proccessing,簡稱OLAP) 概念最早由關係資料庫之父E.F.Codd於1993年提出。OLAP應用是目前資料倉庫上的重要應用之一,是決策分析的關鍵。作為資料倉庫最重要的多維分析工具,OLAP利用儲存在資料倉庫中的資料完成各種分析操作,並以直觀易懂的形式將分析結果返回給決策人員。它的目標是滿足決策支援或多維環境特定的查詢和報表需求,技術核心是多維分析。OLAP具有靈活的分析功能、直觀的資料操作和分析結果視覺化表示等突出優點,從而使使用者對大量複雜資料的分析變得輕鬆而高效,以利於迅速做出正確的判斷,輔助決策。

  相比於傳統的OLTP(聯機事務處理),OLAP定義了多維模型的概念輔助分析操作:

 

Mondrian入門介紹之schemamanager
 

 圖 1

  如圖1所示,這是由三個維度構成的一個OLAP立方體,立方體中包含了滿足條件的cell(子立方)值,這些cell裡面包含了要分析的資料,稱之為度量值。顯而易見,一組三維座標就唯一確定了一個子立方。下面介紹一下多位模型的基本概念:

  立方體:Cubes,由維度構建出來的多維空間,包含了所有要分析的基礎資料,所有的聚合資料操作都在立方體上進行。

  維度:Dimensions,就是觀察資料的一種角度。在這個例子中,路線,源,時間都是維度,

  這三個維度構成了一個立方體空間。維度可以理解為立方體的一個軸。要注意的是有一個特殊的維度,即度量值維度。

  維度成員:Members,構成維度的基本單位。對於時間維,它的成員分別是:第一季度、第二季度、第三季度、第四季度。

  層次:Hierarchies維度的層次結構,要注意的是存在兩種層次:自然層次和使用者自定義層次。對於時間維而言,(年、月、日)是它的一個層次,(年、季度、月)是它的另一個層次,一個維可以有多個層次,層次可以理解為單位資料聚合的一種路徑。

  級別:Levels,

級別組成層次。對於時間維的一個層次(年、月、日)而言,年是一個級別,月是一個級別,日是一個級別,顯然這些級別是有父子關係的。

  度量值:要分析展示的資料,即指標。如圖1中一個cell中包含了兩個度量值:裝箱數和截至時間,可以對其進行多維分析。

  事實表:存放度量值的表,同時存放了維表的外來鍵。所有的分析用的資料最終都是來自與事實表。

  維表:一個維度對應一個或者多個維表。一個維度對應一個維表時資料的組織方式就是採用的星型模式,對應多個維表時就是採用雪花模式。雪花模式是對星型模式的規範化。簡言之,維表是對維度的描述。

  除此之外,OLAP還定義了多維模型的查詢語言MDX(MDX是微軟釋出的多維查詢語言標準),它的語法與SQL有很多相似之處:

 

      select {[Measures].[Salary]} on columns,
  [Employee].[employeeId].members on rows from CubeTest

  對於這條語句,COLUMNS 和 ROWS都代表查詢軸,其中COLS代表列軸,ROWS代表行軸。COLUMNS又可以寫成0,ROWS又可以寫成1,當只有兩個查詢軸時,可以理解為結果的展現格式是一個平坦二維表。這條語句的含義就是查詢名字為CubeTest的立方體,列顯示Measures維度的salary,行顯示 Employee維度employeeId級別的所有成員,那麼得出的結果就是employeeId所有成員的salary,也就是所有員工的薪酬。由 jpivot(jpivot會在後面介紹)展現的結果如圖2所示:

 

圖2

  2 開源OLAP引擎-Mondrian

  OLAP引擎實現了除多維資料展示外的所有資料分析功能:包括建立多維模型、解析MDX語句、返回分析結果。國外傳統資料庫廠商都推出了自己的 OLAP分析工具,微軟發行了MDX語言標準,SQL SERVER Analysis Service是其商業化OLAP引擎。

  開源社群OLAP產品主要是Mondrian OLAP引擎。Mondrian是開源專案Pentaho的一部分,是一個用Java寫成的OLAP引擎。它實現了MDX語言、XML解析、JOLAP規範。它從SQL和其它資料來源讀取資料並把資料聚集在記憶體快取中,然後經過Java API用多維的方式對結果進行展示,同時可以不寫SQL就能分析儲存於SQL 資料庫的龐大資料集,可以封裝JDBC資料來源並把資料以多維的方式展現出來。JPivot是Mondrian預設的表現層工具,它是一個JSP 自定製的標籤庫,可以繪製OLAP分析圖表。使用者可以執行典型的OLAP導航,如下鑽、切片。JPivot使用Mondrian作為它的OLAP伺服器但也支援XML/A資料來源訪問。它使用WCF (Web Component Framework)框架 ,基於XML/XSLT來渲染Web UI元件。

  Mondrian支援的資料庫或資料倉庫主要有:LucidDb、Oracle、 Access、Mysql、Sybase、Ingres、Postgres、Hypersonic、Teredata、

  Mondrian主要特點是對立方體進行了快取,眾所周知,快取龐大的立方體對效能有很大的影響,但是Mondrian利用java語言的特點對這一點進行了很好的控制。其次由於Mondrian基於java語言,所以它能執行在不同的平臺之上,這也是其流行的主要原因之一,例如花旗銀行就在其資料倉庫專案中用Mondrian作為它的OLAP引擎。Mondrian是開源專案,為開發人員和資料分析人員提供了深入研究OLAP技術的機會,同時這也為優化Mondrian總體效能提供了可能。

  3 Mondrian體系結構淺析

  3.1 Mondrian 總體結構

  Mondrian體系結構如圖3所示:

 

圖 3

  整體的架構圖將Mondrian分成了四個大部分Schema manager、Session Manager、Dimension Manager、Aggregate Manager,而實際上各個部分有著更為緊密的聯絡。對於Dimensional Layer、Star Layer和SQL Layer的劃分,更多是處於總體邏輯分層的考慮,具體在原始碼中,邏輯分層的概念比較模糊。

  下面簡單介紹下各個Manager的大致功能,在後續文章會分開詳細介紹:

  1 Session Manager:最為重要的一個部分。接受MDX查詢、解析MDX,返回結果。

  2 Schema Manager:與初始化緊密相關。主要是一些重要的資料結構如快取池的構建以及多維模型的生成。

  3 Aggregate Manager:實現了對聚集表的管理。主要是對OLAP快取的管理,屬於效能優化的部分。

  4 Dimension Manager:維度的管理。實現多維模型中維度和關係資料庫表中列的對映,在Schema Manager也有部分功能處理這些對映。

  3.2 Mondrian Schema Manager分析

  3.2.1 準備工作

  Mondrian的結果展示分為兩種形式:一是利用jpivot展現層在web頁面上展示,一種是呼叫Mondrian api在控制檯顯示。在分析Mondrian的過程中,後一種方式有利於對結果封裝格式的研究以及程式的除錯。所以採取後一種方式來對Mondrian進行分析。分析之前要做一些必要的準備工作。

  分析環境為:

  (1)Window2003

  (2)Tomcat5.0

  (3)mysql5.0.37

  (4)java 1.6.0

  (5)Mondrian3.0.3.11016

  1 正確配置Mondrian原始碼

  (1)在eclipse中構建一個空的java工程(Mondrian3.0工程);

  (2)將Mondrian3.0.3的原始碼壓縮包解壓,將其內容全部拷貝到Mondrian3.0工 程中;

  (3)在工程屬性中指定原始碼目錄為src/main;

  (4)ant執行build.xml檔案的prepare,parser,generate.resources,def四個目標過程, 按順序執行;

  (5)將mondrian.war釋出包中的WEB-INF/lib中的jar包全部拷貝到Mondrian3.0.工程的lib目錄中;

  (6)根據提示的異常匯入必要的jar包檔案;

  在這個過程中需要注意的是:最後執行ant完成對工程進行清理處理;如果一切正常,之後則不需要用mondrian.jar檔案,可以依此為標準檢測是否構建成功。

  2 資料庫建表

  在資料庫中建立如下三張表:

 

      create table tb_employee(employee_id int,
  employee_name int
  )
  create table tb_time(time_id int,
  time_year int,
  time_month int)
  create table tb_salary(employee_id int,
  time_id int,
  salary int)

  插入適當的資料。

  3 編寫Schema檔案test.xml

  在利用Mondrian進行多維分析過程中需要十分注意Schema檔案的編寫。Schema檔案是對資料庫中表的多維模型定義,所以有些選項要和資料庫中表的定義保持一致,更為重要的是Schema檔案的設計的好壞直接影響到多維查詢的效率,Mondrian在schema檔案定義的過程中提供了很多配置選項,可以對多維查詢進行優化。下面是基於資料庫表的一個test.xml:

  在test.xml中定義了一個名為CubeTest的立方體,這個立方體對應的事實表是tb_salary,定義了兩個維度Employee 和Time,這兩個維度分別有一個層次,對應的維度表分別是tb_employee和tb_time,employeeid層次有一個級別,而time層次有兩個級別。在事實表中用employeeid和timeid連線到這兩個維表,該星型模式如圖4所示:

 

圖4

  4 編寫測試類

  可以構建一個簡單的查詢與結果輸出:

 

圖五

  控制檯輸出的結果應為:

     

Mondrian入門介紹之schemamanager
 

  5 測試類的流程

  從測試類可以看出Mondrian的api的確與Jdbc有很多相似之處,從構建查詢到輸出結果主要完成四個步驟:

  (1) 初始化Connection,初始化時傳入必要的引數。getConnection(str)中的str就是連線字串,指定了資料庫引數和jdbc驅動。

  (2) 生成一個String物件,用來儲存MDX查詢語句。

  (3) 生成一個Query物件,用來查詢結果。

  (4) 生成一個Result物件,用來儲存結果。

  其中Connection,Query,Result物件均是Mondrian自定義型別。

  3.2.2 Schema Manager

  1Connection初始化與Rolapschema

  測試類的第一個步驟初始化了Connection物件,Connection物件提供了Mondrian的入口,Connection物件有一個十分重要的成員變數schema,Connection初始化的大部分工作其實是在完成schema的初始化。在整體架構中,Connection初始化屬於Session Manager的範疇,而Schema的初始化由Schema Manager專門完成。Connection物件中含有Schema物件,這也是Session Manager和Schema

  Manager存在緊密聯絡的原因。圖5是初始化一個connection的時序圖:

 

 圖6

  Connection在Mondrian中定義為介面型別,RolapConnection實現了Connection介面,完成了實際初始化的過程。圖6展示了類RolapConnection的部分方法和全部屬性:

 

圖7

  RolapConnection其中的一些屬性與schema有很大的關聯。datasource指定了連線資料來源,如果在連線字串裡定義了 jdbc引數,該屬性可以為空。catalogUrl是test.xml的路徑,schema的初始化是圍繞xml檔案展開的。schemaReader 為其他物件提供了獲取schema內部資訊的渠道。

  RolapConnection的初始化最終會呼叫第二個構造方法。如果其schema引數為空,那麼會呼叫 RolapSchema.Pool.instance.get()方法,從這裡開始,系統流程從Session Manager部分轉到Schema Manger部分。Pool是RoalpSchema的內部類,Pool類利用Singleton模式維護了一個schema池,這樣對於不同的 connection,如果它們所用的xml檔案是一樣的,那麼只用生成一個schema例項就可以滿足需要,當xml檔案很大時,shema池可以提高初始化效率。

  Mondrian提供了兩種方式從schema池中取schema物件,一種是基於關鍵字的,一種是基於內容檢查的。關鍵字key主要包含是 xml檔案路徑、檔名和資料庫連線引數,當採用這種方式時,schema池便是key與schema物件的對映,用key來訪問schema物件。這一對映用java語言中的軟引用技術實現和垃圾收集器之間的互動,最大限度上的利用記憶體同時又不影響垃圾收集過程。但是存在一個問題,那就是不同的key對應的xml檔案的內容可能是一樣的:可能同一個xml檔案放在不同的路徑下,也可能是xml檔名字不同但內容是一樣的,在這種情況下,不同的key對應相同的schema物件,出現了物件冗餘。基於內容檢查的獲取方式可以解決這一問題,它的實現思想是,用兩個key來對應一個schema物件,一個 key與上述的key完全一樣,另一個key是對xml內容用md5加密後的字串,取schema物件時,先將xml內容用md5加密,用得到字串和對映中的所有key比較,如果字串與對映中的某個key相同,說明對於該xml檔案內容,對映中存在相應的schema物件,直接取就可以了,如果對映中沒有一個key滿足要求,說明該xml內容是第一次初始化,那麼初始化對應的schema物件,並新增兩個對映:key與schema物件的對映和 md5字串與schema物件的對映。在這裡key與schema物件的對映並不是多餘的,因為md5字串可能為空。

  兩種訪問schema池的方法各有優劣,在實際應用中很難估計所使用的xml檔案內容有多少是完全相同的。如果xml內容各不相同,第二種方式的效率反而會很低,不僅浪費了時間,而且還浪費了空間。基於內容檢查方式Mondrian預設設定是關閉的,可以根據實際應用情況進行配置。

  2 schema物件的初始化

  schema物件的初始化是SchemaManager的主要功能。顯然,當初始化第一個連線訪問schema池的時候,schema池是空的,這個時候就涉及到schema物件的初始化,即對於一個xml檔案,建立與之對應的schema物件,並把該schema物件放到schema池裡面去。圖7是shema物件初始化的時序圖,較之connection初始化的時序圖,更為詳細了描述了schema部分的初始化過程:

 

圖8

  RoalpSchema的類圖如圖8所示:

 

圖9

  類圖中列出了一個schema物件的主要屬性和主要的初始化方法。結合時序圖和類圖,可以分析出schema初始化的大致流程:

  (1) RolapSchema的六參構造方法呼叫RolapSchema的四參構造方法,在Rolap四參構造方法中,初始化了 internalConnection,主要是設定了internalConnection的datasource屬性,如前面所述,datasource傳遞進來時可以為空,在初始化internalConnection時,如果傳遞進來的datasource為空,會根據傳遞進來的jdbc引數構造一個datasource,這個datasource至關重要,在生成資料庫方言的時候要用到。此外,構造方法還初始化了幾個重要的對映:如立方體名到立方體的對映、共享層次到閱讀器的對映、共享層次名到層次的對映,當然此時的對映都為空。最後構造方法初始化了一個 aggTableManager物件,用來管理聚集表。

  (2) RoalpSchema六參構造方法呼叫RolapSchema的成員函式Load(String,String)。 Load(String,String)函式的主要作用是解析xml檔案,以及將多維模型轉換為MondrianDef定義的物件。 Load(String,String)函式使用了EigenBase包,EigenBase是一個開源的資料管理系統,函式裡面用EigenBase提供的xml解析器來解析xml檔案。同時函式中利用apache提供的common包建立了虛擬檔案系統,正是這個虛擬檔案系統實現了不同的xml檔案讀取方式:比如從本地檔案中讀取或者從http協議讀取。EigenBase為xml的解析提供了一套api,解析的方式是巢狀進行的。Mondrian中與EigenBase xml parser互動的類是MondrianDef,這個類用內部類的方式定義了所有的多維概念,解析過程中,xml節點轉化為多維物件並建立彼此之間的聯絡。這些物件都被包含在xmlSchema物件之中。需要注意的是,MondrianDef定義的多維概念只能算做一種中間過渡的臨時型別,因為此時只建立了立方體、維度、層次、級別、事實之間最基本的關係,沒有考慮到資料的共享,函式的呼叫。

  (3) 在Load(String,String)方法中呼叫Load(MondrianDef.Schema)方法。Load(MondrianDef)方法主要做了兩件事情:函式表物件的初始化,根據MondrianDef的多維物件生成最終的多維物件。在Load(MondrianDef.Schema)方法中初始化了RolapSchemaFunctionTable物件,RolapSchemaFunctionTable是RolapSchema的內部類,主要用來接收使用者自定義函式的定義,這個自定義函式的定義來自與xml檔案。呼叫RolapSchemaFunctionTable物件的 intialize()函式時,初始化所有函式的定義,同時定義所有函式的保留字。這裡的所有函式包括BuildinFunTable、 GlobalFunTable、RolapSchemaRolapFunctionTable。

  Mondrian中各種函式類的關係如圖10所示:

 

圖10

  生成函式表物件之後,再由xmlSchema物件包含的多維物件生成Mondrian最終使用的多維物件。這一過程通過初始化xml檔案中定義的多維模型可能用到的引數,命名集,RolapCube型別的立方體和虛擬立方體來完成。

  RolapSchema物件維護了一個RolapStar(星型模式定義)池,當初始化一個立方體時,訪問這個RolapStar池,引數是這個立方體對應的事實表名。

  如果存在對應的RolapStar物件,那麼直接設定立方體的star域,如果不存在,則生成一個新RolapStar物件再設定。當生成新的 RolapStar物件時,就會呼叫RoalpSchema物件的interConnection成員的datasource,根據這個 datasource去返回所連線的資料庫的特徵引數,為之後生成特定的sql語句做準備。

  在這裡可以對RolapConnection、RolapSchema、RolapCube、RolapStar之間的關係做個小結:多個 connection可能對應一個schema,每個schema又有一個internalConnection,並且可能有多個cube,多個cube 可能對應一個star。Mondrian構造了很多物件池,這種做法提高了對記憶體有限空間的利用率。

  (4) 最後Load(String,String)方法呼叫aggTableManager.intialze()。聚集表管理器的初始化和星型模型有很大關係,同時它利用觸發器機制對Mondrian.properties檔案進行監聽,Mondrian.properties中property值的改變能及時反映到聚集表管理器中,從而影響到聚集的動作。

  至此,一個schema的初始化過程全部完成,流程從Schema Manager重新轉向Session Manager,Session Manager下一步將解析傳入的MDX語句。從以上的分析可見,Session Manager是十分重要的一環,它與後面的Aggregate Manager、Dimensional Manager聯絡也十分緊密。初始化的工作為之後的多維分析操作奠定了牢固的基礎。在Schema Manager部分,可以優化的地方不是很多,唯一可以能提高效率的地方便是xml檔案的編寫,設計高效的多維模式、靈活的運用Mondrian提供的配置引數有助於提高之後資料處理操作的效率。

  

Mondrian入門介紹之schemamanager
 

Mondrian入門介紹之schemamanager
 

Mondrian入門介紹之schemamanager
 

Mondrian入門介紹之schemamanager
 

Mondrian入門介紹之schemamanager
 

Mondrian入門介紹之schemamanager
 

Mondrian入門介紹之schemamanager
 

Mondrian入門介紹之schemamanager
 

Mondrian入門介紹之schemamanager