Hbase學習筆記——rowkey

案例

Reliable and Scalable Data Ingestion at Airbnb
https://www.slideshare.net/HadoopSummit/reliable-and-scalable-data-ingestion-at-airbnb-63920989

Apache HBase at Airbnb
https://www.slideshare.net/HBaseCon/apache-hbase-at-airbnb

Airbnb軟件工程師丁辰 - Airbnb的Streaming ETL
https://myslide.cn/slides/3473

  

在Airbnb的rowkey設計案例中,使用了hash法避免了寫入熱點問題,其中

Event_key標識了一條日誌的唯一性,用於將來自Kafka的日誌數據進行去重;

Shard_id是將Event_key進行hash(可以參考es的路由哈希算法Hashing.murmur3_128)之後,對Shard_num進行取餘後的結果,Shard_num感覺應該是當前hbase表region server的總數,由於airbnb在hbase中存儲的是實時日誌數據,並開啓了Hbase的TTL,所以當前hbase表中的數據總量應該是可預測的,即region server數量不會無限增加

Shard_key應該就是當前業務的region_start_keys+shard_id,比如當前業務分配的前綴爲00000,同時規劃了100個table regions給這個業務,即00-99,那麼Shard_key的範圍就是0000000-0000099

rowkey就是Shard_key.Event_key,比如0000000.air_events.canaryevent.016230-a3db-434e

 

 

 

rowkey設計原則

1.rowkey長度原則:rowkey是一個二進制碼流,可以是任意字符串,最大長度 64kb ,實際應用中一般爲10-100bytes,以 byte[] 形式保存,一般設計成定長。

建議越短越好,不要超過16個字節,原因如下:

  1. 數據的持久化文件HFile中是按照KeyValue存儲的,如果rowkey過長,比如超過100字節,1000w行數據,光rowkey就要佔用100*1000w=10億個字節,將近1G數據,這樣會極大影響HFile的存儲效率;

  2. MemStore將緩存部分數據到內存,如果rowkey字段過長,內存的有效利用率就會降低,系統不能緩存更多的數據,這樣會降低檢索效率。

  3. 目前操作系統都是64位系統,內存8字節對齊,控制在16個字節,8字節的整數倍利用了操作系統的最佳特性。

2.rowkey散列原則:如果rowkey按照時間戳的方式遞增,不要將時間放在二進制碼的前面,建議將rowkey的高位作爲散列字段,由程序隨機生成,低位放時間字段,這樣將提高數據均衡分佈在每個RegionServer,以實現負載均衡的機率。

如果沒有散列字段,首字段直接是時間信息,所有的數據都會集中在一個RegionServer上,這樣在數據檢索的時候負載會集中在個別的RegionServer上,造成熱點問題,會降低查詢效率。

3.rowkey唯一原則:必須在設計上保證其唯一性,rowkey是按照字典順序排序存儲的,因此,設計rowkey的時候,要充分利用這個排序的特點,將經常讀取的數據存儲到一塊,將最近可能會被訪問的數據放到一塊。

 

熱點問題

        HBase中的行是按照rowkey的字典順序排序的,這種設計優化了scan操作,可以將相關的行以及會被一起讀取的行存取在臨近位置,便於scan。然而糟糕的rowkey設計是熱點的源頭。

  熱點發生在大量的client直接訪問集羣的一個或極少數個節點(訪問可能是讀,寫或者其他操作)。大量訪問會使熱點region所在的單個機器超出自身承受能力,引起性能下降甚至region不可用,這也會影響同一個RegionServer上的其他region,由於主機無法服務其他region的請求。

        設計良好的數據訪問模式以使集羣被充分,均衡的利用。爲了避免寫熱點,設計rowkey使得不同行在同一個region,但是在更多數據情況下,數據應該被寫入集羣的多個region,而不是一個。下面是一些常見的避免熱點的方法以及它們的優缺點:

1.加鹽

        這裏所說的加鹽不是密碼學中的加鹽,而是在rowkey的前面增加隨機數,具體就是給rowkey分配一個隨機前綴以使得它和之前的rowkey的開頭不同。分配的前綴種類數量應該和你想使用數據分散到不同的region的數量一致。加鹽之後的rowkey就會根據隨機生成的前綴分散到各個region上,以避免熱點。

2.哈希

        哈希會使同一行永遠用一個前綴加鹽。哈希也可以使負載分散到整個集羣,但是讀卻是可以預測的。使用確定的哈希可以讓客戶端重構完整的rowkey,可以使用get操作準確獲取某一個行數據。

3.反轉

第三種防止熱點的方法時反轉固定長度或者數字格式的rowkey。這樣可以使得rowkey中經常改變的部分(最沒有意義的部分)放在前面。這樣可以有效的隨機rowkey,但是犧牲了rowkey的有序性。

反轉rowkey的例子以手機號爲rowkey,可以將手機號反轉後的字符串作爲rowkey,這樣的就避免了以手機號那樣比較固定開頭導致熱點問題

4.時間戳反轉

        一個常見的數據處理問題是快速獲取數據的最近版本,使用反轉的時間戳作爲rowkey的一部分對這個問題十分有用,可以用 Long.Max_Value - timestamp 追加到key的末尾,例如 [key][reverse_timestamp] , [key] 的最新值可以通過scan [key]獲得[key]的第一條記錄,因爲HBase中rowkey是有序的,第一條記錄是最後錄入的數據。

 

其他一些建議:

        儘量減少行鍵和列族的大小在HBase中,value永遠和它的key一起傳輸的。當具體的值在系統間傳輸時,它的rowkey,列名,時間戳也會一起傳輸。如果你的rowkey和列名很大,這個時候它們將會佔用大量的存儲空間。

        列族儘可能越短越好,最好是一個字符。

        冗長的屬性名雖然可讀性好,但是更短的屬性名存儲在HBase中會更好。

 

轉自:

HBase的rowKey設計技巧

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章