1. 程式人生 > >hbase熱點問題解決(預分割槽)

hbase熱點問題解決(預分割槽)

一、出現熱點問題原因

 1、hbase的中的資料是按照字典序排序的,當大量連續的rowkey集中寫在個別的region,各個region之間資料分佈不均衡;

       2、建立表時沒有提前預分割槽,建立的表預設只有一個region,大量的資料寫入當前region;

       3、建立表已經提前預分割槽,但是設計的rowkey沒有規律可循,設計的rowkey應該由regionNo+messageId組成。

二、如何解決熱點問題       

       設計可以讓資料分佈均勻的rowkey,與nosql資料庫們一樣,rowkey是用來檢索記錄的主鍵。訪問hbase table中的行,rowkey 可以是任意字串(最大長度 是 64KB,實際應用中長度一般為 10-100bytes),在hbase內部,rowkey儲存為位元組陣列,儲存時,資料按照rowkey的字典序排序儲存。

         建立表命令:

create 'testTable',{NAME => 'cf', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE=> '0', VERSIONS => '1', COMPRESSION => 'snappy', MIN_VERSIONS =>'0', TTL => '15552000', KEEP_DELETED_CELLS => 'false', BLOCKSIZE =>'65536', IN_MEMORY => 'false', BLOCKCACHE => 'true', METADATA =>{'ENCODE_ON_DISK' => 'true'}},{SPLITS_FILE=>'/app/soft/hbaseregionsplist/region.txt'}

        region.txt內容:

        

        我這裡預分10個region,建立表之後,在hbae的ui中可以看到以下資訊,說明分預期ok了!!!

        

        1、第一種設計rowkey方式:隨機數+messageId,如果想讓最近的資料快速get到,可以將時間戳加上

             我這裡的region是0001|到0009|開頭的,因為hbase的資料是字典序排序的,所以如果我生成的                                                 rowkey=0002rer4343343422,則當前這條資料就會儲存到0001|~0002|這個region裡,使用了|,因為我的messageId都是字母和數字,|的ASCII值大於字母和數字。

                 regionNum=10,因為我預分10個region

            

                  

           這種設計的rowkey可以解決熱點問題,但是要建立關聯表,比如將rowkey儲存到資料庫或者nosql資料庫中,因為前面的regionNo是隨機的,不知道 對應資料在hbase的rowkey是多少;同一批資料,因為這個regionNo是隨機的,所以要到多個region中get資料,不能使用startkey和endkey去get資料。

          2、第二種設計rowkey的方式:通過messageId對映regionNo,這樣既可以讓資料均勻分佈到各個region中,同時可以根據startkey和endkey可以get到同一批資料

          messageId對映regionNo,使用一致性hash演算法解決,一致性雜湊演算法在1997年由麻省理工學院的Karger等人在解決分散式Cache中提出的,設計目標是為了解決因特網中的熱點(Hot spot)問題,參考(https://baike.baidu.com/item/%E4%B8%80%E8%87%B4%E6%80%A7%E5%93%88%E5%B8%8C/2460889?fr=aladdin)

(https://www.cnblogs.com/lpfuture/p/5796398.html)

public class ConsistentHash<T> implements Serializable{
    private static final long serialVersionUID = 1L;
    private  final HashFunction hashFunction;
    //每個regions的虛擬節點個數
private final int numberOfReplicas;
    //儲存虛擬節點的hash值到真實節點的對映
private final SortedMap<Long, String> circle = new TreeMap<Long, String>();
    public ConsistentHash(HashFunction hashFunction, int numberOfReplicas, Collection<String> nodes) {
        this.hashFunction = hashFunction;
        this.numberOfReplicas = numberOfReplicas;
        for (String node : nodes){
            add(node);
        }
    }
    /**
     * 新增節點
     * @param node
* @see java.util.TreeMap
     * */
public void add(String node) {
        for (int i = 0; i < numberOfReplicas; i++)
             /*
              * 不同的虛擬節點(i不同)有不同的hash值,但都對應同一個實際機器node
              * 虛擬node一般是均衡分佈在環上的,資料儲存在順時針方向的虛擬node上
              */
circle.put(hashFunction.getHashValue(node.toString() + i), node);
    }
    /**
     * 移除節點
     * @param node
* @see java.util.TreeMap
     * */
public void remove(String node) {
        for (int i = 0; i < numberOfReplicas; i++)
            circle.remove(hashFunction.getHashValue(node.toString() + i));
    }
    /**
     * 獲取對應key的hashcode值,然後根據hashcode獲取當前資料儲存的真實節點
     * */
public String get(Object key) {
        if (circle.isEmpty())
            return null;
        //獲取對應key的hashcode值
long hash = hashFunction.getHashValue((String) key);
        //資料對映在兩臺虛擬機器器所在環之間,就需要按順時針方向尋找機器
if (!circle.containsKey(hash)) {
            SortedMap<Long, String> tailMap = circle.tailMap(hash);
            hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
        }
        return circle.get(hash);
    }
    /**
     * 獲取hash環節點大小
     * @return
* */
public long getSize() {
        return circle.size();
    }
    /**
     * 獲取double型別資料的小數位後四位小數
     * @param num
* @return
* */
public String getDecimalPoint(double num){
        DecimalFormat df = new DecimalFormat("0.0000");
        return df.format(num);
    }

}

public class HashFunction implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 獲取對應字串的hashCode值
     * @param key
* @return
* */
public  long getHashValue(String key) {
        final int p = 167776199999;
        int hash = (int) 216613626111L;
        for (int i = 0; i < key.length(); i++)
            hash = (hash ^ key.charAt(i)) * p;
        hash += hash << 13;
        hash ^= hash >> 8;
        hash += hash << 3;
        hash ^= hash >> 18;
        hash += hash << 5;
        // 如果算出來的值為負數則取其絕對值
if (hash < 0)
            hash = Math.abs(hash);
        return hash;
    }}
 這樣可以通過messageId映射出regionNo,最後得到rowkey。

     我目前滿意第二種方式,然後在es中建立關聯表,get資料時,現在es中get到rowkey,然後在hbase中獲取資料,這個根據自己的業務設計。

寫的內容有問題,歡迎來吐槽,我會及時修改,謝謝!

相關推薦

hbase熱點問題解決分割槽

一、出現熱點問題原因 1、hbase的中的資料是按照字典序排序的,當大量連續的rowkey集中寫在個別的region,各個region之間資料分佈不均衡;       2、建立表時沒有提前預分割槽,建立的表預設只有一個region,大量的資料寫入當前region;     

4、CORS跨域請求限制與解決請求

test.html <script> fetch('http://localhost:8887/', { method: 'PUT', headers: { 'X-Test-Cors': '123' } }) </s

阿裏雲手動搭建k8s搭建中遇到的問題解決持續更新

服務 list work body can -s ssi add gdi ETCD搭建 systemd啟動etcd服務的時候出現錯誤:Failed at step CHDIR spawning /usr/bin/etcd: No such file or directo

HihoCoder 1640 : 命名的煩惱處理好題

最短 很多 一位 提高 表示 合並 新的 最優 位數 描述 程序員常常需要給變量命名、給函數命名、給項目命名、給團隊命名…… 好的名字可以大大提高程序員的主觀能動性,所以很多程序員在起名時都會陷入糾結和煩惱。 小Hi希望給新的項目起個拉風

xfire沖突問題解決maven配置

color group microsoft OS ring exc -c org pre 1、xfire與spring沖突解決方法,將spring從maven配置中去掉: <!-- https://mvnrepository.com/artifact

Citrix問題和解決持續更新

問題1:         手動掛載“個人網盤”後,使用者在共享資料夾中沒有建立自己的資料夾進行使用者問價的隔離,所欲使用者的檔案都相互可見? 分析:       

spark2.2.0:記錄一次資料傾斜的解決擴容join

前言: 資料傾斜,一個在大資料處理中很常見的名詞,經由前人總結,現已有不少資料傾斜的解決方案(而且會發現大資料的不同框架的資料傾斜解決思想是一致的,只是實現方法不同),本文重點記錄這次遇到spark處理資料中的傾斜問題。 老話: 菜雞一隻,本人會對文中的結論負責,如果有說錯的,還請各位批評指出

Hbase偽分散式成功實施

Hbase偽分散式(成功實施)hadoop叢集正常,zookeeper叢集正常 修改Hbase-env.sh的JAVA_HOME,改成絕對路徑。 並修改export HBASE_MANAGES_ZK=false 修改環境變數HBASE_HOME 修改hbase-site.xml 新增  

C語言處理

- 預處理 在程式編譯之前進行的處理,所有的編譯預處理命令以#開頭。分為巨集定義、檔案包含、條件編譯。 1. 巨集 巨集定義的作用是某段程式碼的別名,以#define開頭,結尾不用分號。 eg:#define PI 3.14//巨集名一般用大寫字母 在編譯預處理時,只是

atom中latex配置問題的解決元件缺失

大家好!  本文是我在經歷了漫長的探索之後終於成功在atom中配置上latex寫成的。(至於有人問我我為什麼不直接下載一個texworks或者其他,回答:就不就不就不)  首先我已經安裝了atom,atom真的是一個很有意思的軟體了,讓我驚歎的是它的package真的安裝的很

記錄某專案中的踩坑與解決持續更新

前言 最近參加了某個比賽, 我所選的賽題就是個類似知乎這樣的安卓app,由於著手近一個月了,踩了不少坑,之前沒怎麼記錄,估計事後也會忘記乾淨。 因此特開一帖,在此記錄下相關的坑。 記錄 寫完某個Recyclerview的item佈局和相關介面卡後, 然後展示的時候, 發現顯示出來的Item數量小於

記錄某項目中的踩坑與解決持續更新

class hold 數量 eat 發現 適配 比賽 攔截 綁定 前言 最近參加了某個比賽, 我所選的賽題就是個類似知乎這樣的安卓app,由於著手近一個月了,踩了不少坑,之前沒怎麽記錄,估計事後也會忘記幹凈。 因此特開一帖,在此記錄下相關的坑。 記錄 寫完某個Recyc

power designer16.5 連線資料庫以及 Could not Initialize JavaVM! 和SQLSTATE = IM014錯誤的解決詳細圖文

最近使用 power designer 時遇見了好多問題,下面分兩個方面說明。。。 首先使用power designer 怎麼連線資料庫的表等資料: 這裡面我MySQL資料庫來說: 新建一個物理模型:File —— New Model,選擇如下: 新建完成後工作空間已經有了

2018全國大學生數學建模競賽頒獎儀式直播現場

由全國大學生數學建模競賽組委會主辦、上海賽區組委會協辦、上海交通大學承辦的2018高教社杯全國大學生數學建模競賽頒獎儀式將於12月15日在上海交通大學舉行。 屆時 中國大學生線上官方微博將對頒獎儀式進行現場直播。   直播地址:點選 2018高教社杯全國大學生數學建模競賽頒獎儀式 進

Android系列Viewpager+Fragment 優化之懶載入載入的實現

今天帶來的就是fragment的優化,怎麼去實現懶載入 懶載入(預載入) 懶載入字面意思就是當需要的時候才會去載入,不需要就不要載入 為什麼Fragment需要懶載入呢,一般我們都會在onCreate()或者onCreateView()裡去啟動一些資料載入操作,比如從本

Sql Server資料庫解決單個使用者打開不了資料庫的問題

今天準備copy sql server資料庫中的.mdf檔案,但發現copy不了,於是上網搜了一下發現要分離資料庫,但是分離了一段時間系統又顯示出錯,然後分離的資料庫後面就多了單個使用者四個字,資料庫就訪問不了了。最後開啟新建查詢,執行以下指令碼便順利解決: U

【Swiper】4.3.2 自動滾屏錯位問題解決含demo

起因:Swiper由於設定了autoplay,會自己滾動,怎麼解決吶,我先升級到了4.3.2發現,預設呼叫沒有解決這個問題,查看了Swiper API 發現了個解決方式,分享給大家。PS: 查看了3.X.X 的API 感覺沒辦法解決,建議升級到4.X.X版本 , 不能完全相容

運維老司機帶你出坑:複雜故障的排查及解決案例實錄

sockets: used:已使用的所有協議套接字總量 TCP:inuse:正在使用(正在偵聽)的TCP套接字數量。其值≤ netstat –lnt | grep ^tcp | wc –l TCP:orphan:無主(不屬於任何程序)的TCP連線數(無用、待銷燬的TCP socket數) TCP:tw:等待關

HBase利用observer協處理器建立二級索引

一、協處理器—Coprocessor         1、 起源 Hbase 作為列族資料庫最經常被人詬病的特性包括:無法輕易建立“二級索引”,難以執 行求和、計數、排序等操作。比如,在舊版本的(<0.92)Hbase 中,統

【windows核心驅動開發】檔案系統微過濾驅動Minifilter——繫結指定的卷磁碟分割槽

【我的】檔案系統微過濾驅動Minifilter——繫結指定的卷(磁碟分割槽) 作者:zcr214 時間:2016/4/21 在編寫檔案系統微過濾驅動minifilter的時候,很有可能我們只對某一個特定的磁碟分割槽感興趣,而其他的如系統盤的很多IRP對於我們要編寫的驅動可