HBase的rowkey的設計原則

HBase的rowkey的設計原則


HBase是三維有序存儲的,通過rowkey(行鍵),column key(column family和qualifier)和TimeStamp(時
間戳)這個三個維度可以對HBase中的數據進行快速定位。
HBase中rowkey可以唯一標識一行記錄,三種查詢方式
通過get方式,指定rowkey獲取唯一一條記錄
通過scan方式,設置startRow和stopRow參數進行範圍匹配
全表掃描,即直接掃描整張表中所有行記錄


 Rowkey長度原則


rowkey是一個二進制碼流,可以是任意字符串,最大長度64kb,實際應用中一般爲10-100bytes,以byte[]形式保
存,一般設計成定長。
數據的持久化文件HFile中是按照KeyValue存儲的,如果rowkey過長,比如超過100字節,1000w行數據,光
rowkey就要佔用100*1000w=10億個字節,將近1G數據,這樣會極大影響HFile的存儲效率; MemStore將緩存部
分數據到內存,如果rowkey字段過長,內存的有效利用率就會降低,系統不能緩存更多的數據,這樣會降低檢索
效率。 目前操作系統都是64位系統,內存8字節對齊,控制在16個字節,8字節的整數倍利用了操作系統的最佳特
性。


Rowkey 散列原則


@Test
public void tesValueFilter() throws IOException {
        //1、創建過濾器
        ValueFilter filter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new
BinaryComparator("張三".getBytes()));
        //2、創建掃描器
        Scan scan = new Scan();
        //3、將過濾器設置到掃描器中
        scan.setFilter(filter);
        //4、獲取HBase的表
        Table table = connection.getTable(TableName.valueOf("user"));
        //5、掃描HBase的表(注意過濾操作是在服務器進行的,也即是在regionServer進行的)
        ResultScanner scanner = table.getScanner(scan);
        for (Result result : scanner) {
            // 6.打印數據 獲取所有的單元格
            List<Cell> cells = result.listCells();
            for (Cell cell : cells) {
                // 打印rowkey,family,qualifier,value
                System.out.println(Bytes.toString(CellUtil.cloneRow(cell))
                        + "==> " + Bytes.toString(CellUtil.cloneFamily(cell))
                        + "{" + Bytes.toString(CellUtil.cloneQualifier(cell))
                        + ":" + Bytes.toString(CellUtil.cloneValue(cell)) + "}");
            }
        }
}
建議越短越好,不要超過16個字節
如果rowkey按照時間戳的方式遞增,不要將時間放在二進制碼的前面,建議將rowkey的高位作爲散列字段,由程
序隨機生成,低位放時間字段,這樣將提高數據均衡分佈在每個RegionServer,以實現負載均衡的機率。如果沒有
散列字段,首字段直接是時間信息,所有的數據都會集中在一個RegionServer上,這樣在數據檢索的時候負載會集
中在個別的RegionServer上,造成熱點問題,會降低查詢效率。


 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,這樣的就避免了以手機號那樣比較固定開頭導致
熱點問題

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