熱點問題
hbase 中的行是以 rowkey 的字典序排序的,這種設計優化了scan 操作,可以將相關的 行 以及會被一起讀取的行 存取在臨近位置,便於 scan 。 然而,糟糕的 rowkey 設計是 熱點 的源頭。 熱點發生在大量的客戶端直接訪問集群的一個或極少數節點。訪問可以是讀,寫,或者其他操作。大量訪問會使 熱點region 所在的單個機器超出自身承受能力,引起性能下降甚至是 region 不可用。這也會影響同一個 regionserver 的其他 regions,由於主機無法服務其他region 的請求。設計良好的數據訪問模式以使集群被充分,均衡的利用。
為了避免寫熱點,設計 rowkey 使得 不同行在同一個 region,但是在更多數據情況下,數據應該被寫入集群的多個region,而不是一個。下面是一些常見的避免 熱點的方法以及它們的優缺點:
1、加鹽
這里的加鹽不是密碼學中的加鹽,而是在rowkey 的前面增加隨機數。具體就是給 rowkey 分配一個隨機前綴 以使得它和之前排序不同。分配的前綴種類數量應該和你想使數據分散到不同的 region 的數量一致。 如果你有一些 熱點 rowkey 反復出現在其他分布均勻的 rwokey 中,加鹽是很有用的。考慮下面的例子:它將寫請求分散到多個 RegionServers,但是對讀造成了一些負面影響。
a-rk0001
b-rk0002
c-rk0003
a-rk0004
3、哈希
除了加鹽,你也可以使用哈希,哈希會使同一行永遠用同一個前綴加鹽。哈希也可以使負載分散到整個集群,但是讀卻是可以預測的。使用確定的哈希可以讓客戶端重構完成的 rowkey,使用Get 操作獲取正常的獲取某一行數據。
4、翻轉key
第三種防止熱點的方法是翻轉固定長度或者數字格式的rowkey。這樣可以使得rowkey中經常改變的部分(最沒意義的部分)放在前面。這樣可以有效的隨機 rowkey,但是犧牲了 rowkey 的有序性。
100kr
200kr
300kr
5、單調遞增 rowkey(時間連續序列)
當所有客戶端一段時間內一致寫入某一個region,然后再接着寫入下一個 region。例如:像單調遞增的 rowkey(時間戳) ,就會發生這種現象。應該盡量避免這種設計。
打散數據的數據+時間序列
6、盡量減少行和列的大小
在Hbase中,value永遠是和它的key一起傳輸的。當具體的值在系統間傳輸時,它的rowkey,列名,時間戳也會一起傳輸。如果你的rowkey和列名很大,甚至可以和具體的值相比較,那么你將會遇到一些有趣的情況。HBase storefiles中的索引(有助於隨機訪問)最終占據了HBase 分配的大量內存,因為具體的值和他的key很大。可以增加 block 大小使得 storefiles 索引在更大的時間間隔增加,或者修改表的模式以減小rowkey 和 列名的大小。壓縮也有助於更大的索引。
大多時候較小的低效率是無關緊要的,但是在這種情況下,任何訪問模式都需要列族名,列名,rowkey,所以它們會被訪問數十億次在你的數據中。
7、列族越短越好
盡可能使列族名越短越好,最好是一個字符。(例如:’d’ 代表data/default)。屬性名也是一樣的。
