修改HBase的rowkey设计把应用的QPS从5W提升到50W
摘要:?正確設計Hbase的rowkey可以讓你的應用飛起來,前提是你需要了解一些Hbase的存儲機制。
UTT是Aliexpress的營銷消息運營平臺,運營希望促銷活動時APP消息推送的QPS達到34W。
UTT剛接入APP消息推送時,QPS只能達到5W,離運營的要求有很大的距離。
通過改造,QPS達到了50W,其中最主要的改造是對Hbase的rowkey的改造。
首先介紹一下UTT大致工作流程:
1、運營人員在UTT的小二控制臺配置運營任務(job),在任務中設置商品選擇參數、目標人群參數和消息發送渠道;
2、UTT調用算法平臺計算出要發送的消息,數據生成在阿里云飛天系統的云梯表中;
3、UTT把云梯表中的數據導入到hbase,并生成N個可以并發執行的發送任務(segment),segment的信息存儲在mysql表中;
4、UTT按計劃發送時間撈取segment,把存儲在Hbase中的segment對應的消息讀取出來調用阿里巴巴移動消息推送網關發送出去。
步驟1、2、3是提前執行的,我們要優化的是步驟4。
改造中,我們主要做了如下幾件事:
1、修改了Hbase的rowkey規則和數據讀取方式;
2、優化了記錄發送進度的邏輯;
3、優化了消息發送到阿里巴巴移動消息推送網關的流程。
其中最主要的是對Hbase的rowkey的修改。
改造前的rowkey設計:
rowkey=segmentSalt+”_"+dataIndexInSegment+”_”+segmentId+”_”+jobTime+”_”+jobId
說明如下:
job:job對應運營在后臺頁面配置的任務,一個job可能多次運行,用jobId+jobTime可以唯一標識一個job的一次發送任務。
segment:一個job的一次發送任務拆分為多個segment,每個segment對應10萬條消息。多個segment的消息可以并行發送。
segmentSalt:4位的隨機字母,每個segment有一個salt,用于把數據均勻分散到Hbase的不同region中;
dataIndexInSegment:每條消息在segment中的序號,從0到99999;
改造前UTT按計劃發送時間撈出要發送的segment后,從按0到99999的順序從Hbase中讀取消息,然后發送出去。為了提高效率使用了hbase的批量get方法。
這個設計存在一個很大的問題,同一個segment里的相鄰消息的rowkey不是連續的,之間可能隔的非常遠。
如下圖所示,10000號消息rowkey和10000
1號消息rowkey之間可能隔了很多rowkey。
這會帶來啥問題?這就需要了解Hbase的存儲機制。
Hbase的存儲是以storeFile為單位,以LSM樹(Log-structured merge tree)方式存儲。
此結構優化寫性能,犧牲讀性能。寫數據的時候先按rowkey計算出region和store,順序寫入到store的memeStoreFile中,memoStoreFile達到指定大小后flush到磁盤的storeFile中。因此同一個store里,多個storeFile的rowkey的范圍是會有重疊的。
按rowkey讀取數據時,計算該rowkey可能存儲的storeFile,把這些storeFile全部讀取到內存中,最后把多個storeFile里查詢到的結果合并后輸出。
為了提高讀性能,Hbase會在后臺把多個storeFile進行merge,形成rowkey范圍互不重疊的storeFile。
另外Hbase采用按列值KV方式存儲數據,也就是說每個列的值都是獨立存儲的。每個列值KV對里的key包括了rowkey和列名,key里的大部分數據是重復的,storeFile采用壓縮算法減小空間。
改造前同一個segment里的消息的rowkey很分散,讀取一個segment的消息時要從磁盤上裝載大量的storeFile,消耗大量的cpu進行解壓縮,這也會導致storeFile 的cache命中率不高。并且讀出來的大部分storeFile是沒有包含所需數據的。
分析UTT的場景,多個segment是并發讀寫的,每個segment有segmentSalt,保證了讀寫均勻分布到Hbase的不同region。如果讀取一個segment的消息時能從盡量少的storeFile讀取數據,就能夠減少磁盤IO,減少解壓縮及數據查找的CPU,還能提高storeFile cache的命中率。
改造后的rowkey設計:
rowkey=segmentSalt+”_”+jobTime+”_”+jobId+”_”+segmentId+”_”+dataIndexInSegment(前補零到定長5位)
這樣多個segment并發讀寫均勻分散到不同region,同一個segment的消息順序寫到相同的storeFile中,讀取的時候不再使用get方法而是使用scan方法。最后qps提升了一個數量級。
附一個hbase的知識腦圖,不知道作者是誰,挺好的。
原文鏈接?
本文為云棲社區原創內容,未經允許不得轉載。
總結
以上是生活随笔為你收集整理的修改HBase的rowkey设计把应用的QPS从5W提升到50W的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PyODPS DataFrame:统一的
- 下一篇: 企业如何采用机器学习