Kylin效能調優記 業務技術兩手抓

2021-07-15 08:41:34 字數 3954 閱讀 6469

最近開始使用了新版本的kylin,在此之前對於新版本的了解只是**實現和一些簡單的新功能測試,但是並沒有匯入實際場景的資料做分析和查詢,線上hadoop穩定之後,逐漸得將一些老需求往新的環境遷移,基於以前的調研,新版本(v2,版本為1.5.2)的kylin提供了幾個比較顯著的功能和優化:

有了這麼多新的特性和效能提公升,經常拿新版本來應付使用者的需求:新版本實現了***功能,肯定效能會很好,等到新版本穩定了再來搞這個需求吧。等到我們的新版本上線了,業務需求真正上來之後,才發現用起來沒有相當的那麼簡單,對於kylin這種直接面向使用者需求的服務,對於一些特殊的需求更是要不斷打磨和調整才能達到更好的效能。本文整理在接入雲**乙個較為複雜的需求的實現和中間調優的過程,一方面開拓一下自己的思路,另外也使得讀者能改更好的使用kylin。

kylin 1.3.0之前的版本對於這種需求的確有點無能為力,我們使用了最簡單的方式實現,建立乙個包含所有維度、所有度量的cube,其中10個度量為count distinct,使用hyperloglog實現的近似去重計數演算法,這種做法能夠可以說是最原始的,每次查詢時如果不進行任何過濾則需要從hbase中掃瞄幾百萬條記錄才能滿足topn的查詢,每一條記錄還都包含hyperloglog序列化的值(讀取到記憶體之後還需要對hyperloglog進行反序列化),top的查詢速度可想而知,正常情況(沒有併發)下能夠在1、2分鐘出結果,偶爾還會有乙個查詢把服務搞掛(順便吐槽一下我們使用對的虛擬機器)。查詢以天的資料就這種情況了,對於跨天的資料更不敢嘗試了。

這種狀況肯定無法滿足需求方,只能等著新版本落地之後使用topn度量。

面對這樣的現實,感覺對於去重計數無能為力了,尤其像這種包含10個distinct count度量的cube,需求方也意識到這種困境,對需求做出了一定的讓步:不需要跨天計算topn的song_id了,只需要根據每一天的pv或者uv值計算topn,這樣就不需要distinct count了,而且還能保證每天的統計值是精確的。如果希望計算大的時間週期的topn,則通過建立乙個新的cube實現每個自然周、自然月的統計。對於這樣的需求簡化,可以大大提公升cube的建立,首先需要對資料來源做一些改變(這種改變通常是view來完成),將原始表按照歌曲id、使用者id和其它的維度進行聚合(group by,保證轉換後的新錶每乙個使用者對於每一首歌曲只儲存一條記錄),pv則直接根據計算sum(操作次數),uv通過表示式if(sum(操作次數) > 0, 1, 0)確定每乙個userid對每乙個songid在當天是否進行了某種操作,這樣我們就得到如圖2中格式的表:

這個表中可以保證歌曲id+使用者id是唯一的(其它的維度是歌曲的屬性,乙個歌曲只對應相同的屬性),對於kylin來說原始資料量也變小了(還是每天幾億條記錄),接下來新建的cube由於資料來源保證每一條記錄不是同乙個使用者對同一首歌曲的操作,因此所有的度量都可以用sum來實現(去重計數也可以通過對sum(是否***)統計精確的計數值),這樣對於kylin的負擔減少了一大部分,但是掃瞄記錄數還是這麼多(cube中最大的維度為歌曲,每次查詢都需要攜帶,查詢時掃瞄記錄數始終保持在歌曲id的個數),但是build效能提公升了,查詢效能也由於掃瞄資料量減少(乙個sum度量占用的儲存空間只有8位元組)而提公升,但是還是需要30+秒。

此時,新版本終於在公司內部落地了,彷彿看到了新的曙光。

新版本有了topn度量了,但是目前只支援最大top 1000,可以通過直接改cube的json定義改變成最大得到5000,於是嘗試了幾種使用topn的方案。

第一種是將所有維度放在乙個cube中然後對於每乙個pv和uv建立乙個topn度量。這樣build速度還是挺快的,但是查詢時大約需要25秒+,最坑爹的是,建立topn時需要指定乙個指標列(做sum,根據該列的sum值排序)和乙個聚合列(歌曲id),使用乙個聚合列建立的多個topn度量居然只有查詢第乙個度量時才有結果,使用其他指標查詢topn時返回的聚合值總是null,難道我要為每乙個指標都建乙個cube,每乙個只包含乙個topn度量?

第二種方案是不使用全部維度,而只使用在計算topn時需要做過濾的列,例如支付型別、圈子id等維度建包含topn的cube,這樣通過抽取部分維度建立乙個小cube用來計算topn,然後再使用計算出來的一批批歌曲id從大cube(包含全部維度的cube)中取出這個id對應的其它指標和屬性資訊。這樣做的弊端是對於查詢不友好,查詢時需要執行兩條sql並且在前端進行分頁,如果效能可以接受也就認了,但是現實總是那麼殘酷,當建立了乙個這樣的cube(包含歌曲id和其他幾個成員值很少的維度)進行build資料時,讓人意想不到的事情發生了,計算第二層cuboid的任務居然跑了3個小時才勉強跑完,接下來的任務就更不敢想象了,mr任務的task使用cpu總是100%,通過單機的測試發現多個topn的值進行merge的效能非常差,尤其是n比較大的時候(而且kylin內部會把n放大50倍以減少誤差),看來這個方案連測試查詢效能的機會都沒有了。

嘗試了這兩個方案之後我開始慢慢的失去信心了,但是想到了kylin新版本的並行掃瞄會對效能有所提公升,於是就建立了乙個小cube(包含歌曲id和幾個過濾維度,和全部的sum度量)用於計算topn,整個cube計算一天的資料只需要不到1g的儲存,想必掃瞄效能會更好吧,查詢測試發現在不加任何過濾條件的情況下對任意指標的topn查詢大約不到15s,但是掃瞄的記錄數仍然是幾百w(歌曲id的數目),可見並行掃瞄帶來的效能提公升,但是掃瞄記錄數仍然是乙個繞不過去的坎。

在經歷這麼多打擊之後,實在有點不知所措了,感覺歌曲id的數目始終是限制查詢效能的最大障礙,畢竟要想計算topn肯定要檢視每乙個歌曲id的統計值,然後再排序,避免不了這麼多的掃瞄,唯一的方法也就是減小region的大小,使得一天的資料分布在更多的region中,增大並行度,但這也不是最終的解決方案啊,怎麼減小掃瞄記錄數呢?

此時需要對圖2中的記錄格式再進行整理,通過group by 歌曲id,***(其他維度)統計出每一首歌曲的操作次數和操作人數,然後再根據操作次數的值確定index的值。得到新的記錄格式如圖3.

接下來感覺是走投無路之後的各種猜測,例如猜測shard by設定true or false是否對效能有很大的影響,經過檢視原始碼發現shard by只是為了決定該列的值是否參與一致性雜湊中桶號的計算,只不過是為了更好的打散rowkey的分布,對於儲存和查詢效能提公升不是太明顯,思來想去還是不合理,既然加了過濾不應該還要掃瞄全部的歌曲id,是不是cube中rowkey的順序錯了,查了一下cube的定義,發現index維度被放在rowkey的最後一行,這顯然是不了解kylin是如何確定掃瞄範圍的!kylin儲存在hbase中的記錄是rowkey是根據定義cube時確定的rowkey順序確定的,把如果查詢的時候對某乙個維度進行範圍過濾,kylin則會根據過濾的範圍確定掃瞄的區間以減小掃瞄記錄數,如果把這個維度放到rowkey的最後,則將這種過濾帶來的減小掃瞄區間的作用降到了最低。

重新修改cube把index維度在rowkey中的位置提公升到最前面之後重新build,此後再執行相同的查詢速度有了質的飛躍,降低到了1s以內。根據index的範圍不同掃瞄記錄數也隨著改變,但是對於查詢topn一般只需要使用index >= 6的過濾條件,這種條件下掃瞄記錄數可以降低到幾萬,並且保證了全部歌曲id可以被查詢。

本文記錄了雲**的乙個比較常見的topn的需求的優化,在整個優化的過程中在技術和業務上都給與了充分的考慮,在滿足查詢需求的前提下,查詢效能從最初的上百秒提公升到1秒以內,這個過程讓我充分意識到了解資料特徵和業務的重要性,以前遇到問題總是想著是否能夠進行演算法的優化,是否可以加機器解決,但是當這些都不能再有改進的空間時,轉換一下思路,思考一下是否可以從業務資料入手進行優化,可能會取得更好的效果。

隨著kylin 2.x的落地使用,對於業務的支援也更有信心了,尤其是並行查詢和endpoint coprocessor對效能的提公升,但是對於開源技術來說,如何正確的使用才是最困難的問題,我們也會在探索kylin使用的路上越走越遠。

最後,通過本次調優,我發現了乙個以前沒有注意到的問題:薛之謙最近真的挺火,不相信的話可以檢視一下網易雲**熱歌榜。

效能調優記

效能問題多是多方面的問題的堆積 最近部署服務的虛擬機器降低規格 為了和某公司較勁 在效能測試過程中,很不幸的發現系統cpu佔比週期性的衝高。使用top命令,可以觀察到idle週期性的會為0,同時會有較多的資料庫連線出現 從解決問題的角度看 1.由於是效能測試環境,環境中資料較多。當資料查詢方法不當是...

技術難點 Spark效能調優 RDD運算元調優篇

不廢話,直接進入正題!1.rdd復用 在對rdd進行運算元時,要避免相同的運算元和計算邏輯之下對rdd進行重複的計算,如下圖所示 對上圖中的rdd計算架構進行修改,得到如下圖所示的優化結果 2.盡早filter 獲取到初始rdd後,應該考慮盡早地過濾掉不需要的資料,進而減少對記憶體的占用,從而提公升...

剖析資料庫效能調優技術之索引調優

剖析資料庫效能調優技術之索引調優 2008 1 28 9 37 00 by iulu 一 概述 隨著資料庫在各個領域的使用不斷增長,越來越多的應用提出了高效能的要求。資料庫效能調優是知識密集型的學科,需要綜合考慮各種複雜的因素 資料庫緩衝區的大小 索引的建立 語句改寫等等。總之,資料庫效能調優的目的...