BI筆記之---Cube增量處理的一個場景的處理方案

增量處理概述:

通常來說Cube會隨着時間的積累而日漸增長,這樣一來如果每次都是全量處理的話會導致處理時間逐漸變長。所以對於大規模的 Cube,爲了追求處理時間和性能,都會採取增量處理的方案。

 

場景:

根據數據倉庫的數據結構以及業務含義的不通,數據的組織會有差異,這裏討論的是增量處理的其中一個場景,其中:

事實表是以日期鍵爲主鍵(數據的生成日期),根據日期有建立爲月的分區。

並且事實數據是不發生變化的,只隨日期的增長而增長。Cube的處理週期爲天,Cube的分區是按月進行的分區。

這種場景多發生在分析狀態數據,比如分析IIS日。

 

問題:

關於增量處理的一般過程,可以參考我的這篇筆記

在SSIS下有Cube process的任務包,在這個下面指定增量處理的時候,只能把針對的是哪一個分區寫死,而不能去動態判斷,如下圖:

這樣就需要使用腳本代碼來實現。

image

 

方案:

如上,可以用腳本代碼來實現,網上關於如何用腳本模塊的實現方法很多,都是VB版本的,這裏爲了簡單明瞭,使用powershell來實現。如果想將其寫成c#的版本可以直接參考powershell的模式。

使用powershell主要方便在於它可以直接使用.net framework的對象,而操作cube 的是需要AMO的一系列對象的。建議先參考下AMO對橡樹。對AMO的對橡樹有了解之後編寫代碼思路纔可以更清晰些。

 

步驟:

1. 對所有分區進行命名規範,比如[MeasureGroupName]_[Year]-[Month]。

2. 在代碼中,先找到昨天所對應的分區(根據分區命名規則)

3. 確定昨天所對應的SQL查詢,這個查詢將作爲這個Cube的剛纔所找到的分區的增量查詢語句。增量查詢的語句是根據分區的查詢語句來確定的。

4. 處理

 

代碼:

#AMO對象所需dll所在位置,這裏跟VS下填加引用一樣,如果是64位系統地址可能會有些變化

[void][reflection.assembly]::LoadFile("C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.AnalysisServices.dll")

#這裏假定Adventure Works下的沒一個分區都是按照[度量值組名]_[年]-[月]的方式來命名的。當然實際當中Adventure Works每個度量值組只有一個分區,而且不是這樣命名的。

$ServerName="localhost"

$DatabaseName="Adventure Works DW 2008R2"

$CubeName="Adventure Works"

#新建一個Server對象,c#的寫法是Server _s = new Server();

$server=New-Object Microsoft.AnalysisServices.Server

$server.Connect($ServerName)

$db=$server.Databases.GetByName($DatabaseName)

$cu=$db.Cubes.GetByName($CubeName)

$t=[System.Datetime]::Now.Tostring("yyyy-MM-dd HH:mm")

write-output "[$t][$CubeName]Processing dimensions..."

############################################

#先處理維度

############################################

$server.CaptureXml=$true

foreach ($dm in $cu.Dimensions)

{

#注意這裏枚舉類型在powershell下的用法

$dm.Dimension.Process([Microsoft.AnalysisServices.ProcessType]::ProcessUpdate)

}

$server.CaptureXml=$false

$r = $server.ExecuteCaptureLog($true,$true)

#這裏顯示處理結果,實際上只有出現錯誤的時候纔會枚舉到

foreach ($xr in $r)

{

foreach ($xm in $xr.Messages)

{

write-output $xm.Description

}

}

$t=[System.Datetime]::Now.Tostring("yyyy-MM-dd HH:mm")

write-output "[$t][$CubeName]Dimension process finished!"

#$server.CaptureLog.Clear()

############################################

#處理Cube

############################################

#write-output "[$CubeName]Processing Cube..."

$server.CaptureXml=$true

foreach ($mg in $cu.MeasureGroups)

{

$server.CaptureLog.Clear()

$server.CaptureXml=$true

#1.找到當前分區,這裏根據場景約定是取昨天

$NowPartition = ""

$NowPartition = $mg.Name +" "+[System.DateTime]::Now.AddDays(-1).ToString("yyyy-MM")

$t=[System.Datetime]::Now.Tostring("yyyy-MM-dd HH:mm")

write-output "[$t][$CubeName]Process partition for update $ProcessDate: $NowPartition"

$pt=$mg.Partitions.GetByName($NowPartition)

#2.生成增量查詢

#$PT_Date_Start=[System.DateTime]::Now.AddDays(-1).Year.ToString() +"-"+ [System.DateTime]::Now.AddDays(-1).Month.ToString("d2") +"-0"

#$tdt=[System.DateTime]::Parse($PT_Date_Start)

$PT_Date_End = [System.DateTime]::Now.AddDays(-1).ToString("yyyy-MM-dd")

$sql=$pt.Source.QueryDefinition

$sql=$sql.substring(0,$sql.LastIndexOf("BETWEEN")+8) + "'" +$PT_Date_End + " 00:00:00.000' and '" + $PT_Date_End + " 23:00:00.000'"

$qb=New-Object Microsoft.AnalysisServices.QueryBinding

$qb.DataSourceID="Noas"

$qb.QueryDefinition=$sql

$pt.Process([Microsoft.AnalysisServices.ProcessType]::ProcessAdd, $qb)

$server.CaptureXml=$false

$r = $server.ExecuteCaptureLog($true,$true)

foreach ($xr in $r)

{

foreach ($xm in $xr.Messages)

{

write-output $xm.Description

}

}

}

$t=[System.Datetime]::Now.Tostring("yyyy-MM-dd HH:mm")

write-output "[$t][$CubeName]Process Cubes OK!"

 

注意的地方:

需要注意分區的命名規則,因爲在代碼查找當前需要增量的數據在哪個分區的時候需要用到。

由於是使用腳本代碼來完成的任務,所以多少需要BI人員多少懂一點代碼的編寫,尤其是對.net framework的理解。

如何使用AMO 對象去實現一個增量更新的處理,可以參考上面代碼的示例。

 

總結:

這裏簡單描述了增量處理更新的一個場景,實際項目中Cube的增量處理方案都非常的複雜,所以還需要具體情況具體分析。但這種在代碼中通過powershell來實現的方法是比較通用的,powershell在使用上也很靈活,所以推薦各位從事BI 的朋友使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章