有乙個資料多維分析的任務:
初始的解決方案: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...