輕量級OLAP(一) Cube計算

2021-09-08 03:59:32 字數 2978 閱讀 2532

有乙個資料多維分析的任務:

初始的解決方案:spark讀取資料日誌,然後根據分析需求逐一進行map、distinct、reducebykey得到分析結果。但是,這種方案存在著非常大的缺點——重複掃瞄資料來源多次。

pig提供cube關鍵字做olap,將dimension分為了兩類:

官方doc例子如下:

salesinp = load '/pig/data/salesdata' using pigstorage(',') as

(product:chararray, year:int, region:chararray, state:chararray, city:chararray, sales:long);

cubedinp = cube salesinp by cube(product,year);

result = foreach cubedinp generate flatten(group), sum(cube.sales) as totalsales;

salesinp = load '/pig/data/salesdata' using pigstorage(',') as

(product:chararray, year:int, region:chararray, state:chararray, city:chararray, sales:long);

rolledup = cube salesinp by rollup(region,state,city);

result = foreach rolledup generate flatten(group), sum(cube.sales) as totalsales

在例子中,cube的操作相當於按維度組合對每一record進行展開並group bydimensions,與下一句foreach語句構成了dimensions + measure的資料輸出格式。

從上面介紹的pig olap方案中,我們得到靈感——面對開篇的多維分析需求,也可以每一條記錄按dimensions + measure的規則進行展開:

/**

* @param e (uid, logfact)

* @return array[((dimension order no, dimension), measure)]

*/ val source = (("00", e._2.source), e._1)

case "empty" => (("15", "a"), "useless")

} val dvcmodel = (("21", e._2.dvcmodellabel), e._1)

val vendor = (("22", e._2.vendor), e._1)

val (osall, oscollect) = ((("23", e._2.ostype), e._1), (("24", e._2.ostype), e._2.dvcmodel))

val oslabel = e._2.dvcmodellabel match

osall, oscollect, oslabel).filter(_._2 != "useless")

}

為了區別不同的維度組合,**中採取了比較low的方式——為每個維度組合進行編號以示區別。spark提供flatmap api將一行展開為多行,完美地滿足了維度展開的需求;然後通過一把group by key + distinct count即可得到結果:

val result = flatrdd.distinct()

.mapvalues(_ => 1)

.reducebykey(_ + _)

前面的分析需求比較簡單,measure均為distinct count;因而可以不必對齊dimensions + measure。然而,對於比較複雜的分析需求:

measure既有distinct count (uv) 也有count (pv),這時需要dimensions + measure的對齊,維度flatmap如下:

/**

* @param e ((adid, 2nd ad-category, 1st ad-category, uid)

* @return array[((dimension order no, dimension), measure:(adid, uid or adid, 1)]

*/def flatad(e: ((string, string, string), string)) =

val adcate = (("1", e._1._2), (e._1._1, e._2, 1))

val adparent = (("2", e._1._3), (e._1._1, e._2, 1))

array(all, adcate, adparent)

}

爾後,計算每一維度的measure(其中distinct count採用hyperloglogplus演算法的stream lib實現):

val createhll = (v: string) => 

def computeaddimention(rdd: rdd[((string, string), (string, string, int))]) = ,

(m1: (hyperloglogplus, hyperloglogplus, int),

m2: (hyperloglogplus, hyperloglogplus, int)) =>

) .mapvalues(t => (t._1.cardinality().toint, t._2.cardinality().toint, t._3))

}

其實,本文有點標題黨~~只是借了olap的殼做資料多維分析,距離真正的olap還是很遠滴……

輕量級OLAP資料分析工具發布

分析工具詳細介紹 基本資訊 使用者的資料展示需求是多種多樣的,我們的分析工具不能100 的滿足所有的展示需求。但是我們希望通過我們的分析工具的20 的 來滿足使用者資料展示的80 的需求,同時我們對剩下20 的需求提供自定義介面,允許使用者進行自定義開發。我們的分析工具是一套輕量級基於統計資料的資料...

說一下偏向鎖 輕量級鎖 重量級鎖?

1.這三種鎖是指鎖狀態,並且是針對synchronized,這三種鎖的狀態是通過物件監視器在物件頭中的字段來表明的.2.偏向鎖是指一段同步 一直被乙個執行緒所訪問,那麼該執行緒會自動獲取鎖,降低鎖的代價.3.輕量級鎖是指當鎖是偏向鎖的時候,被另乙個執行緒所訪問,偏向鎖就會公升級為輕量級鎖,其他執行緒...

peewee 乙個輕量級的ORM 四

class database last insert id cursor,model parameters return type 最後乙個插入的記錄的那行的主鍵,不一定非得叫 id rows affected cursor return type 受影響的行數 create table model...