kylin構建cube優化

2022-07-03 17:03:20 字數 4452 閱讀 2882

下面通過對kylin構建cube流程的分析來介紹cube優化思路。

kylin會在cube構建的第一步先構建一張hive的中間表,該錶關聯了所有的事實表和維度表,也就是一張寬表。

優化點:

1. hive表分割槽優化,在構建寬表的時候,kylin需要遍歷hive表,事實表和維度表如果是分割槽表,那麼會減少遍歷時間

2. hive相關配置調整,join相關配置,mapreduce相關配置等

建立完成後,為了防止檔案大小不一致的情況,kylin又基於hive做了一次重均衡操作,

** `createflathivetablestep`

通過hyperloglog 演算法找出去重後的維度列,如果某個維度的基數很大,那麼這種維度為被稱為ultra high cardinality column(uhc),也就是超高基數維度。那麼如何處理這類維度呢?

比如時間戳維度基數可能是億級的,可以轉成為日期,基數降到幾十萬.

kylin通過mapreduce進行此步驟,在reduce端,乙個維度用乙個reduce去重,因此當某個維度的基數很大時,會導致該維度所在的reduce執行很慢,甚至記憶體溢位,為了應對這種場景,kylin提供了兩種解決方案

1. 全域性唯一維度,也就是在count_dintinct中選擇0錯誤率的統計分析。

2. 需要被shard by的維度,在rowkey構建時配置的維度。

接著可以通過配置`kylin.engine.mr.uhc-reducer-count=1`來宣告這些列需要被分割成多少個reducer執行

當然,kylin也支援基於cuboid個數來進行reducer個數的分配,`kylin.engine.mr.hll-max-reducer-number=1`,預設情況下kylin不開啟此功能,可以修改配置來提高最小個數;然後通過配置`kylin.engine.mr.per-reducer-hll-cuboid-number`來調整具體的reduce數量

int ncuboids =cube.getcuboidscheduler().getallcuboidids().size();

int shardbase = (ncuboids - 1) / cube.getconfig().gethadoopjobperreducerhllcuboidnumber() + 1;

int hllmaxreducernumber =cube.getconfig().gethadoopjobhllmaxreducernumber();

if (shardbase >hllmaxreducernumber)

最終的reducer數量由uhc和cuboids兩個部分相加得到,具體**參考

# 配置uhc增加另外步驟,需要配置zk的位址(作為全域性分布式鎖使用)

# 因為在跑mapreduce的過程中,kylin沒有將hbase-site.xml等配置上傳到yarn,所以只能在kylin.properties中額外配置一遍

kylin.engine.mr.build-uhc-dict-in-additional-step=true

kylin.env.zookeeper-connect-string=host:port,host:port

** `factdistinctcolumnsjob`, `uhcdictionaryjob`

找出所有維度的基數後,kyin為每個維度構建乙個資料字典,字典的metadata儲存在hdfs上,實際資料儲存在hbase

字典在hdfs的路徑規則為

kylin/kylin_meta_data/kylin-$jobid/%cubeid/metadata/dict/$catalog.$table/$dimension/$uuid.dict

字典資料在hbase的rowkey規則為

/dict/$catalog.$table/$dimension/$uuid.dict

過長的rowkey會占用很大的儲存空間,所以需要對rowkey長度進行控制。

當前kylin直接在當前程序內做了字典編碼,也就是把string對映成int,如果維度列的基數很大,那麼可能會出現記憶體溢位的情況(當列的基礎大於1kw),這時候就需要考慮更改維度列的編碼方式,改用`fixed_length`等。如果乙個維度的長度超過`fixed_length`,那麼超過的部分會被截斷。

對rowkey的構建也有一定的要求,一般而言,需要把基數大的字段放在前面,這樣可以在scan的過程中盡可能的跳過更多的rowkey。

另一方面將基數小的列放在rowkey的後面,可以減少構建的重複計算,有些cuboid可以通過乙個以上的父cuboid聚合而成,在這種情況下,kylin將會選擇最小的父cuboid。例如,ab能夠通過abc(id:1110)和abd(id:1101)聚合生成,因此abd會被作為父cuboid使用,因為它的id比abc要小。基於以上處理,如果d的基數很小,那麼此次聚合操作就會花費很小的代價。因此,當設計cube的rowkey順序的時候,請記住,將低基數的維度列放在尾部。這不僅對cube的構建過程有好處,而且對cube查詢也有好處,因為後聚合(應該是指在hbase查詢對應cuboid的過程)也遵循這個規則。

在構建rowkey過程中,有乙個選項,可以宣告哪個維度用於shard。

這個shard的作用是,將該shard維度和總shard數hash,得到的hash結果插入到encoding後的rowkey中,這樣就可以讓該維度下相同的資料盡可能的分配到乙個shard中,而在hbase儲存裡,乙個shard對應的是乙個region,這樣處理另乙個好處是,在聚合的時候可以很好的把相同資料合併一起,減少網路傳輸io。參考類`rowkeyencoder`。乙個encoding的rowkey的結構是這樣的

head+shard+dim1+dim2+…+dimn

乙個segment的總shard數計算方式如下,參考類`createhtablejob`,其中,estimatedsize引數類`cubestatsreader.estimatecuboidstoragesize`

int shardnum = (int) (estimatedsize * magic / mbperregion + 1);

因此,宣告的shard維度最好是被頻繁group by的維度或者是基數很大的維度,這樣在coprocess處理的時候可以加速

可以選擇spark或者mapreduce來構建cube,通常來說,構建引擎的選擇方式是這樣的

記憶體消耗型的cube選擇mapreduce,例如count distinct, top-n

簡單的cube選擇spark,例如sum/min/max/count

spark引擎

spark構建引擎採用` by-layer`演算法,也就是分層計算

比如有3個維度abc,cube會構建a,b,c,ab,ac,abc6種組合,這裡就有3層,

第1層:a,b,c

第2層:ab,ac

第3層:abc

每一層在計算對於spark而言都是乙個action,並且該層計算的rdd會依賴其上一層的結果繼續計算,這樣避免了很大重複性計算工作。

**` sparkcubingbylayer`

參考《kylin介紹》中的cube設計模式

kylin將生成的cube通過生成hfile的方式匯入到hbase,這個優化點可以配置hbase的相關引數。

region數量預設是1,如果資料量大的話可以提高region數量

region大小預設是5gb,也就是hbae官方建議的大小;如果cube大小比這個值小太多,可以減小單region的大小

hfile檔案大小,預設是1gb,由於是通過mapreduce寫入的,小檔案意味著寫入快,但是讀取慢,大檔案意味著寫入慢,讀取快

**`cubehfilejob`

清理hive中的中間表,

清理hbase表

清理hdfs資料

清理命令

# 檢視需要清理的資料

./bin/kylin.sh org.apache.kylin.tool.storagecleanupjob --delete false

# 清理

./bin/kylin.sh org.apache.kylin.tool.storagecleanupjob --delete true

// clean參考

基於kylin的ui,可以看到kylin在構建cube時各個流程的耗時,可以依據這些耗時做相應的優化,常見的,可以從耗時最長的步驟開始優化,比如:

遇到建立hive中間表時間很長,考慮對hive表進行分割槽處理,對錶中的檔案格式更改,使用orc,parquet等高效能的檔案格式

遇到cube構建時間過長,檢視cube設計是否合理,維度的組合關係是否可以再減少,構建引擎是否可以優化

優化的思路還是以cube為中心,優化cube的整個生命週期,其中涉及到的所有元件都是優化點,具體情況還是要和實際的資料維度和業務結合起來。

// 官方文件

// 官方文件,cube效能優化

Kylin實戰 建立cube的優化

背景 kylin的維度組合優化 1 mandatory維度 2 hierarchy維度 3 derived維度 4 聯合維度 kylin的rowkey優化 1 編碼 2 順序 3 分片 了解olap cube的人都會知道,建立cube的過程中往往會出現 維度 問題。kylin是典型的multidim...

Kylin 增量構建

segment示意圖 乙個cube,可以包含多個cuboid,而segment是指定時間範圍的cube,可以理解為cube的分割槽。對應就是hbase中的一張表。該表中包含了所有的cuboid。例如 以下為針對某個cube的segment segment名稱 分割槽時間 hbase表名 201910...

Kylin 剪枝優化及其方法

在沒有採取任何的優化措施的時候,kylin會對每乙個維度組合進行預計算,若有4個維度,則會有將近2 4 16個cuboid需要進行計算。但是我們知道很多維度是 檢查cube的數量 檢查被物化的cube數量 meterialized 檢查cube的大小 expansion rate 0 1000 是乙...