icecube,BI笔记之--- Cube增量处理的一个场景的处理方案

增量处理概述: 通常来说Cube会随着时间的积累而日渐增长,这样一来如果每次都是全量处理的话会导致处理时间逐渐变长。所以对于大规模的 Cube,为了追求处理时间和性能,都会采取增量处理的方案。 场景: 根据数据仓库的数据结构以及业务含义的不通,数据的组织会有差异,这里讨论的是增量处理的其中一个场景,其中: 事实表是以日期键为主键(数据的生成日期),根据日期有建立为月的分区。 并且事实数据是不发生变化的,只随日期的增长而增长。Cube的处理周期为天,Cube的分区是按月进行的分区。 这种场景多发生在分析状态数据,比如分析IIS日。 问题: 关于增量处理的一般过程,可以参考我的这篇笔记。 在SSIS下有Cube process的任务包,在这个下面指定增量处理的时候,只能把针对的是哪一个分区写死,而不能去动态判断,如下图: 这样就需要使用脚本代码来实现。 imageicecube,BI笔记之--- Cube增量处理的一个场景的处理方案 方案: 如上,可以用脚本代码来实现,网上关于如何用脚本模块的实现方法很多,都是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 的朋友使用。
Tags:  cube娱乐公司 icube cube魔方 cubec60 icecube

延伸阅读

最新评论

发表评论