一種HBase的表region切分和rowkey設計方案


場景

HBase的region隨着大小的不斷變大會觸發一個閾值,默認為256M,一旦觸發那么他就會自動的分裂開來,隨着region變多hbase管理起來也越發困難,性能也會明顯下降。當然更多的region使得高並發成為可能。一種較好的實踐方案就是一方面預切分HBase的region,確定region的個數,保證並發性能,另一方面設置較高的region size分裂閾值,保證region數量不變。

方案

預切分方法:

./bin/hbase org.apache.hadoop.hbase.util.RegionSplitter -c 500 test -f t1:t2:t3

上面的命令行工具給以為你切分一個500region的test表,分別包含了三個列族:t1,t2,t3。

然后在hbase-site.xml設置hbase.hregion.max.filesize為104857600(=1024*1024*100=100G),設置為100G,這樣很長一段時間內不會出現region分裂。建議一個節點分到1000region,可以滿足並發,而且不至於讓master壓力過大。

rowkey設計方案:

需要指出的是這種預切分方法用了一種默認算法md5stringsplit來分配region的startkey,endkey。這種得到的是一個8位的右移一位的md5的字符串。實際上就是md5前八位然后右移。這樣在設計rowkey的時候就要千萬注意了!因為這樣分配出來的region是00000000~7fffffff。所以為了讓rowkey能夠均勻落入到這個范圍需要md5(id)>>1 + id。提示一下:如果你使用的md5(id)+id的方法設計了rowkey,入庫時如果數據量很大則會導致hot region。rs就會頻繁的掛掉了,因為大部分數據都落入最后一個region了。

rowkey生成的具體的java代碼如下:

private String makeRowKey(String id){
        String md5_content = null;
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.reset();
            messageDigest.update(id.getBytes());
            byte[] bytes = messageDigest.digest();
            md5_content = new String(Hex.encodeHex(bytes));
        } catch (NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        }
        //turn right md5
        String right_md5_id = Integer.toHexString(Integer.parseInt(md5_content.substring(0,7),16)>>1);
        while(right_md5_id.length()<7){
            right_md5_id = "0" + right_md5_id;
        }
        return right_md5_id + "::" + id;
    }

這樣做的好處就是在寫入數據時可以使rowkey均勻的寫入,當然讀取的時候還需要拿着id變成md5再去讀取,批量讀取與時間戳前置方法相比肯定沒有任何優勢了。不過隨機讀取也會使rs的負載均衡。

上面的這種設計適合絕大多數場景。可以作為一個良好的實踐。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM