基於HBase做Storm 實時計算指標儲存

2021-09-23 07:10:49 字數 4190 閱讀 2154

基於 hbase 做 storm 實時計算指標儲存

hbase 實時指標儲存是我入職樂視雲後對原有的實時系統改造的

hbase 儲存設計

storm 結果如何儲存到 hbase

hbase 寫入效能優化

與傳統方案 (redis/mysql) 對比

樂視雲內部用 storm 做 cdn,點播,直播流量的計算,同時還有慢速比,卡頓比等統計指標。相應的指標會由指標名稱,業務型別,客戶,地域,isp 等多個維度組成。指標計算乙個比較大的問題是 key 的集合很大。

舉個例子,假設我們有客戶 10w,計算指標假設 100 個,5 個 isp,30 個地域,這樣就有億級以上的 key 了,我們還要統計分鐘級別,小時級別,天級別,月級別。所以寫入量和儲存量都不小。

如果採用 redis/memcached 寫入速度是沒有問題的,畢竟完全的記憶體操作。但是 key 集合太大,其實壓力也蠻大的,我去的時候因為加了指標,結果導致 memcache 被寫爆了,所以緊急做了擴容。

首先是 redis 查起來的太麻煩。客戶端為了某個查詢,需要彙總成千上萬個 key。。。業務方表示很蛋疼,我們也表示很蛋疼

其次,記憶體是有限的,只能存當天的。以前的資料需要轉存。

第三,你還是繞不過持久化儲存,於是引入 mysql,現在是每天一張表。那 redis 匯入到 mysql 本身就麻煩。所以工作量多了,查詢也麻煩,查乙個月半年的資料就**了。

鑑於以上原因,我們就想著有沒有更合適的方案。

我們首先就想到了 hbase,因為 hbase 還是具有蠻強悍的寫入性功能以及優秀的可擴充套件性。而事實上經過調研,我們發現 hbase 還是非常適合指標查詢的,可以有效的通過列來減少 key 的數量。

我們現在上圖:

這裡,我們一行可以追蹤某個指標一天的情況。如果加再加個維度,無非增加一條記錄。而如果是 redis,可能就多了一倍,也就是 2880 個 key 了。

我們知道 hbase 是可以多列族,多 column,schemaless 的。所以這裡,我們建了乙個列族,在該列族上,直接建了 1440 個 column。column 的數目和時間粒度有關。如果是一分鐘粒度,會有 1440 個,如果是五分鐘粒度的會有 288 個,如果是小時粒度的,會有 24 個。不同的粒度,我們會建不同的表。

寫入的時候,我們可以定位到 rowkey,以及對應的 column,這裡一般不會存在併發寫。當然 hbase 的 increment 已經解決了併發問題,但是會造成一定的效能影響。

查詢的時候,可根據天的區間查出一條相應的記錄。我們是直接把記錄都取出來,column 只是乙個 int/long 型別,所以 1440 個 column 資料也不算大。

storm 計算這一塊,還有乙個比較有意思的地方。假設 a 指標是五分鐘粒度的,也就是說我們會儲存 a 指標每個五分鐘的值。但是在實際做儲存的時候,他並不是五分鐘結束後就往 hbase 裡儲存,而是每隔(幾秒/或者一定條數後)就 increment 到 hbase 中,然後清除重新計數。

這裡其實我要強調的是,到 hbase 並不是覆蓋某個 rowkey 特定的 cloumn 值,而是在它原有的基礎上,做加法。這樣做可以防止時間週期比較長的指標,其累計值不會因為有拓撲當掉了而丟失資料(其實還是會丟的,但可能損失的計數比較少而已)。

丟資料比如你 kill-9 了。

大家可以想象一下,如果我計算乙個五分鐘的指標,到第三分鐘掛掉了,此時累計值是 1000,接著拓撲重啟了,五分鐘還沒完,剩下的兩分鐘它會接著累計,此時是 500。如果是覆蓋寫,就會得到不正確的結果,實際上整個完整的計數是 1500。

防止拓撲當掉並不是這樣設計的主要原因,還有一點是計算延時了,比如某個資料片段因為某個原因,延時了十分鐘才到 storm 實時計算集群,這個時候新得到的值還可以加回去,如果是覆蓋,資料就錯誤了。

所以 hbase 儲存這塊就變成做加法操作而不僅僅是簡單的更新了。目前 hbase 新增了計數的功能 (incrment),但是我發現跨行,沒有批量更新的的介面。

而 hbase 的 client 也是非常的奇特,比如 htablepool 竟然是物件池而不是鏈結池,多個 htable 物件是共享乙個 connection 鏈結的。當然,這裡 htable 的 connection 會比較複雜,因為要連 zookeeper 還有各個 region。

又沒有批量介面,乙個 client 只能有乙個 connection 鏈結,所以導致客戶端的寫入量死活上不去。16 臺 32g,24 核的伺服器,我做了預分割槽 (60個左右),用了四十個程序,300 個左右的執行緒去寫,也就只能寫到 60000/s 而已。

但實際併發應該是只有 40 左右的。300 個執行緒並沒有起到太多作用。

還有就是,hbase 的 incrementcolumnvalue 的效能確實不高。至少和批量 put 差距很大。

但在我們的測試中,還是比較平穩的,整個寫入狀態。抖動不大。

這裡要強調一點,hbase 看場景,在我們這個場景下是預分割槽是非常重要的。否則一開始都集中在一台機器的乙個 regin 上寫,估計很快寫的程序就都堵住了。上線就會掛。

所以我事先收集了幾天的 key,然後預先根據 key 的分布做了分割槽。我測試過,在我們的集群上,到了 60 個分割槽就是乙個瓶頸,再加分割槽已經不能提公升寫入量。

寫入我們也做了些優化,因為寫的執行緒和 storm 是混用的(其實就是 storm 在寫)。我們不能堵住了 storm。

當使用者提交了n條記錄進行更新操作,我會做如下操作:

將n條分成10份,每份n/10條。

每個jvm例項會構建乙個擁有10個執行緒的執行緒池。

執行緒池中的每個執行緒都會維護乙個connection(通過threadlocal完成)。

執行緒會對自己的這n/10條資料順序進行incrementcolumnvalue。

做這個優化的原因是我上面提到的,htable 的連線池是共享 connnection 的。我們這裡是為了讓每個執行緒都有乙個 connection。具體分成多少份(我這裡採用的是 10),是需要根據 cpu 來考量的。我們的伺服器 cpu 並不是很多。值不是越大越好。如果太大,比如我起了 40 個虛擬機器。每個虛擬機器 10 個執行緒,那麼會有 400 個到 zookeeper 和 hbase 的連線。值設定的過大,會對 zookeeper 有一定的壓力。

這種方案我測試的結果是:

吞吐量上去了。在 1500w 左右的測試資料中,原有的方式大概平均只有 3w/s 左右的寫入量。 通過新的方式,大概可以提高到 5.4w/s,只要 4 分鐘左右就能完成 1500w 條資料的寫入。

峰值略微提公升了一些。之前大約 6.1w/s,現在可以達到 6.6w/s。

因為我用同一集群上的 spark 模擬的提交,所以可能會對 hbase 的寫入有一點影響,如果想要繼續提公升寫入效能,只能重寫 hbase 這塊客戶端的**。

我們總結下上面的內容:

redis/mysql 儲存方案存在的一些缺點。

hbase 表結構設計,充分李永樂 hbase 自身的特點,有效的減少key的數量,提高查詢效率。

storm 寫入方案,用以保證出現資料延時或者 storm 拓撲當掉後不會導致資料不可用。

我們再看看整個儲存體系完整的拓撲圖。

第五個圓圈是為了在實時計算出錯時,通過 spark/mr 進行資料恢復。

第二個圓圈和第四個圓圈是為了做維度複製,比如我計算了五分鐘的值,這些值其實可以自動疊加到對應的小時和天上。我們稱為**程式

第三個圓圈就是對外吐出資料了,由我們的統一查詢引擎對外提供支援查詢支援了。

我們對查詢做乙個推演。如果我要給使用者繪製流量的乙個月曲線圖。曲線的最小粒度是小時,小時的值是取 12 個五分鐘裡最高的值,我們看看需要取多少條記錄完成這個查詢。

我們需要取 31 條五分鐘的記錄,每條記錄有 288 個點,對這 288 個點分成 24 份(具體就是把分鐘去掉 groupby 一下),求出每份裡的最大值(每組 sortby 一下),這樣就得到了 24 個值。

我取過兩天的,整個 http 響應時間可以控制 50ms 左右(本機測試)。

上面的整體架構中,**程式是為了緩解實時寫入 hbase 的壓力,同時我們還利用 mr/spark 做為恢復機制,如果實時計算產生問題,我們可以在小時內完成恢復操作,比如日誌的收集程式、分揀程式、以及格式化程式。格式化程式處理完之後是 kafka,storm 對接的是 kafka 和 hbase。

上面就是今天分享的內容了。

基於HBase做Storm 實時計算指標儲存

基於hbase做storm 實時計算指標儲存 舉個例子,假設我們有客戶 10w,計算指標假設 100 個,5 個 isp,30 個地域,這樣就有億級以上的 key 了,我們還要統計分鐘級別,小時級別,天級別,月級別。所以寫入量和儲存量都不小。如果採用 redis memcached 寫入速度是沒有問...

hbase基於solr的實時索引

實時查詢方案 hbase key value store solr web前端實時查詢展示 1.hbase 提供海量資料儲存 2.solr提供索引構建與查詢 3.key value store 提供自動化索引構建 從hbase到solr 使用流程 前提 cdh5.3.2solr集群搭建好,cdh5....

關於Storm實時往HBase存資料的效能優化

在開發中根據業務邏輯,需要儲存在storm中每個spout和bolt中產生的資料到hbase表中。在程式調優的過程中不斷調整和優化了幾種方案。這是首先考慮和測試的選擇,也是最先放棄的選擇,短時多次建立連線會造成資源的浪費和排隊,儲存的時間的過長也會影響topology流的穩定性和實時性。8.16補充...