一、Rowkey 優化
Rowkey 是行的主鍵,它是以字典順序排序的,所以 Rowkey 的設計是至關重要的, 關系到你應用層的查詢效率,
整規化 Rowkey
有時作為 Rowkey 的欄位長度不一樣,比如 user_id, 而通過對 Rowkey 進行規整化,能夠避免 Rowkey 長度不一致,導致每次請求回傳的資料量不一,可將組合的 Rowkey 映射成等長 hash 值,
編碼 Rowkey
如果 Rowkey 是以字串形式保存,比如日期格式(yyyy-MM-dd HH:mm:ss),會造成大量存盤空間的浪費, 因此可以對字串進行數值編碼,將編碼后的數保存到 Rowkey 中,
高基維度
如果 Rowkey 由多個欄位組成,需要把高基維度放到最前面,也就是 distinct 的欄位數量在千萬以上,比如 user_id 放到前面,這樣欄位能在過濾中起到很大作用、大幅縮小查詢范圍,
加鹽
如果組合 Rowkey 的第一部分是時間戳,HBase又是按照 Rowkey 排序的,很可能鄰近的資料存到一個 HRegionServer 里,考慮到最新的資料訪問頻率最高,將導致某個 HRegionServer 讀請求負載過重,產生熱點問題,一個可行的方案是 Rowkey 前綴加亂數,這可以保證資料均勻分布,但對資料讀取造成了麻煩,和加鹽類似的方案有對 Rowkey 進行哈希、翻轉Rowkey (經常改變的部分放到前面)等,
二、資料熱點問題
資料熱點問題:熱點發生在大量的 client 直接訪問集群的一個或極少數個節點(訪問可能是讀, 寫或者其他操作),大量訪問會使熱點 HRegion 所在的單個機器超出自身承受能力,引起性能下降甚至 HRegion 不可用,這也會影響同一個 HRegionServer 上的其他HRegion,由于主機無法服務其他 HRegion 的請求,造成資源浪費,設計良好的資料訪問模式以使集群被充分、均衡的利用,
可以通過下面方式解決 HRegion 熱點問題:
-
Reverse反轉:針對固定長度的 Rowkey 反轉后存盤,這樣可以使 Rowkey 中經常改變的部分放在最前面,可以有效的隨機 Rowkey,例如手機號比較固定開頭(138、139)的熱點問題,
-
預磁區/Salt加鹽:Salt 是將每一個 Rowkey 加一個前綴,前綴使用一些隨機字符,使得資料分散在多個不同的 HRegion ,達到 HRegion 負載均衡的目標,比如在一個有 4 個 HRegion (注: 以 [ ,a)、 [a,b)、 [b,c)、 [c, )為 HRegion 起止) 的 HBase 表中, 加 Salt 前的 Rowkey:abc001、abc002、abc003 我們分別加 a、 b、 c 前綴,加 Salt 后 Rowkey 為:aabc001、b-abc002、c-abc003,可以看到,加鹽前的 Rowkey 默認會在第2個 HRegion 中, 加鹽后的 Rowkey 資料會分布在3個 HRegion 中,理論上處理后的吞吐量應是之前的3倍,
-
Hash 散列或者 Mod:Hash 散列來替代隨機 Salt 前綴的好處是能讓一個給定的行有相同的前綴,這在分散了 HRegion 負載的同時,使讀操作也能夠推斷,確定性Hash(比如 md5 后取前4位做前綴)能讓客戶端重建完整的 RowKey,可以使用 get 操作直接 get 想要的行,如果 Rowkey 是數字型別的,也可以考慮 Mod 方法,
三、HBase三維有序
Hfile 是 HBase 中 KeyValue 資料的存盤格式,從 HBase 物理資料模型中可以看出,HBase 是面向串列(簇)的存盤,每個 Cell 由 {row key,column(=< family> + < label>),version} 唯一確定的單元,他們組合在一起就是一個 KeyValue, 根據上述描述,這個 KeyValue 中的 key 就是 {row key,column(=< family> + < label>),version} ,而 value 就是 cell 中的值,
HBase 的三維有序存盤中的三維是指:rowkey( 行主鍵),column key(columnFamily+< label>), timestamp(時間戳或者版本號) 三部分組成的三維有序存盤,
Rowkey:我們在根據 rowkey 范圍查詢的時候,我們一般是知道 startRowkey,如果我們通過 scan 只傳 startRowKey:d開頭的,那么查詢的是所有比 d 大的都查了,而我們只需要 d 開頭的資料,那就要通過 endRowKey 來限制,我們可以通過設定 endRowKey 為: d 開頭,后面的根據你的 rowkey 組合來設定,一般是加比 startKey 大一位,
column key:column key 是第二維,資料按 rowkey 字典排序后,如果 rowkey 相同,則是根據 column key 來排序的,也是按字典排序,我們在設計 table 的時候要學會利用這一點,比如我們的收件箱,有時候需要按主題排序,那我們就可以把主題設定為我們的 column key,即設計為“columnFamily+主題”這樣的設計,
timestamp:時間戳,是第三維,這是個按降序排序的,即最新的資料排在最前面,
四、寫入優化
- put 是否可以批量提交:使用批量 put 介面可以減少客戶端到 HRegionServer 之間的 RPC 連接數,提高寫入性能,
- put 是否可以異步提交:業務如果可以接受例外情況下少量資料丟失的話,還可以使用異步批量提交的方式提交請求,提交分為兩階段執行:用戶提交寫請求之后,資料會寫入客戶端快取,并回傳用戶寫入成功;當客戶端快取達到閾值(默認2M)之后批量提交 HRegionServer,需要注意的是,在某些情況下客戶端例外的情況下快取資料有可能丟失,
- 寫入請求是否不均衡:如果不均衡,一方面會導致系統并發度較低,另一方面也有可能造成部分節點負載很高,進而影響其他業務,分布式系統中特別害怕一個節點負載很高的情況,一個節點負載很高可能會拖慢整個集群,這是因為很多業務會使用批量提交讀寫請求,一旦其中一部分請求落到該節點無法得到及時回應,就會導致整個批量請求超時,
- 寫入 KeyValue 資料是否太大:KeyValue 大小對寫入性能的影響巨大,一旦遇到寫入性能比較差的情況,可以考慮是否由于寫入 KeyValue 資料太大導致,
五、查詢優化
- Get 是否可以批量請求:可以減少客戶端到 HRegionServer 之間的 RPC 連接數,提高查詢性能,
- 大 scan 快取是否設定合理:scan 一次需要從服務端回傳大量的資料,客戶端發起一次請求,服務端會分多批次回傳客戶端,這樣的設計是避免一次性傳輸較多的資料給服務端及客戶端產生較大的壓力,目前資料會加載到本地的快取中,默認100條資料大小,一些大 scan 需要獲取大量的資料,傳輸數百次甚至數萬的 rpc 請求,這種情況我們建議可以適當放開快取的大小,
- 請求指定列簇或者列名:HBase 是列簇資料庫,同一個列簇的資料存盤在一塊,不同列簇是分開的,為了減小 IO,建議指定列簇或者列名,
- 離線計算訪問 HBase 建議禁止快取:當離線訪問 HBase 時,往往就是一次性的讀取,此時讀取的資料沒有必要存放在 blockcache 中,建議在讀取時禁止快取,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/271871.html
標籤:其他
上一篇:不是吧不是吧,MySQL服務無法啟動?看這里的萬能解決法!
下一篇:mysql prompt用法詳解
