天天看點

--- HBase學習筆記 (叁)- HBase進階HBase協處理器簡介HBase實戰:開發RegionObserver協處理器HBase實戰:HBase協處理器加載

文章目錄

    • Hbase概念
      • Hbase資料存儲過程·
      • compaction分兩種:
      • compact促發條件:
    • Hbase優化政策
      • hbase優化
      • HBase優化政策一:服務端優化政策
      • HBase優化政策二:常用優化政策
      • HBase優化政策三:讀寫優化政策
  • HBase協處理器簡介
  • HBase實戰:開發RegionObserver協處理器
  • HBase實戰:HBase協處理器加載

什麼導緻hbase性能下降?

  • jvm記憶體配置設定與gc回收政策
  • 與hbase運作機制相關的部配置設定置不合理
  • 表結構設計及使用者使用方式不合理

Hbase概念

Hbase資料存儲過程·

  • Hbase寫入時當memstore達到一定的大小會flush到磁盤儲存成 HFile, 當hfile小檔案太多會執行compact操作進行合并。(當一個hstore裡隻包含一個hfile時;查詢效率才是最大化。因為hfile小檔案過多會影響查詢時長,合并後才可以提高查詢效率。)
  • 當region的大小達到某一門檻值之後, 會執行split操作

compaction分兩種:

  • Minor compaction: 選取一些小的 、 相鄰的storefile将他們合并成一個更大的storefile
  • Major compaction: 将所有的storefile合并成一個storefile, 清理無意義資料、被删除的資料、ttl過期資料 、 版本号超過設定版本号的資料;資源消耗最大。
  • Split: 當一個region達到一定的大小就會自動split成兩個region

compact促發條件:

  • Memstore被flush到磁盤,
  • 使用者執行shell指令compact, Major_compact 或者調用了相應的api
  • Hbase背景線程周期性觸發檢查

Hbase優化政策

hbase優化

  • 常見服務端配置優化
  • 常用優化政策 (以實際需求為主)
  • Hbase讀/寫性能優化

HBase優化政策一:服務端優化政策

  • Jvm設定與gc設定
  • hbase-site. xml 部分屬性配置

    max.filesize預設10G;

    majorcompaction預設1天建議0,通過手動合并,因為需要用到很長時間;

    min預設3;

    --- HBase學習筆記 (叁)- HBase進階HBase協處理器簡介HBase實戰:開發RegionObserver協處理器HBase實戰:HBase協處理器加載

    cache.size在偏向讀的業務當中可以适當調大一些。

    flush.size可以設定大一點;

    block.multiplier建議設定成5;如果太大會有記憶體溢出的危險。

    --- HBase學習筆記 (叁)- HBase進階HBase協處理器簡介HBase實戰:開發RegionObserver協處理器HBase實戰:HBase協處理器加載
    (hbase.hstore.blockingStoreFiles:預設為7,如果任何一個store(非.META.表裡的store)的storefile的檔案數大于該值,則在flush memstore前先進行split或者compact,同時把該region添加到flushQueue,延時重新整理,這期間會阻塞寫操作直到compact完成或者超過hbase.hstore.blockingWaitTime(預設90s)配置的時間,可以設定為30,避免memstore不及時flush。當regionserver運作日志中出現大量的“Region <regionName> has too many store files; delaying flush up to 90000ms"時,說明這個值需要調整了)

HBase優化政策二:常用優化政策

HBase常優用化

-預先分區 -RowKey優化 -Column優化 -Schema優化

  • 預先分區
    • 建立hbase表的時候會自動建立一個region分區(hbase預設建一個regionserver上建region;後期資料大會分為兩個region)
    • 建立hbase表的時候預先建立一些空的regions(減少io操作;通過預先分區;解決資料傾斜問題;将頻繁通路的資料放到多個region中;将不常通路的分區放到一個或幾個region中)
  • Rowkey優化
    • 利用hbase預設排序特點, 将一起通路的資料放到一起
    • 防止熱點問題(大量的client集中通路一個節點), 避免使用時序或者單調的遞增遞減等
  • Column優化
    • 列族的名稱和列的描述命名盡量簡短(過長會占據記憶體空間)
    • 同一張表中columnfamily的數量不要超過 3 個
  • Schema優化
    • 寬表: 一種 “列多行少” 的設計(事物性能好;hbase的事物建立在行的基礎上的;行少插入的時候可以有很好的保障)
    • 高表: 一種 “列少行多” 的設計(查詢性能好;查詢的條件放入rowkey中我們可以緩存更多的行;中繼資料來講開銷大因為行多rowkey多)

      hbase主要在于不必苛刻設計于哪種;主要取決于業務。

HBase優化政策三:讀寫優化政策

  • Hbase寫優化政策
    • 同步批量送出or異步批量送出
    • WAL優化, 是否必須, 持久化等級

預設時同步送出資料的;異步送出是可能丢失一些資料的;在業允許的情況下可以開啟。

WAL預設是開啟的;一方面確定資料緩存丢失了也可以資料恢複;另一方面是為了叢集間的異步複制;更關注寫入的吞吐量的時候可以關閉WAL或者采用異步寫入。

  • Hbase讀優化政策
    • 用戶端: Scan緩存設定, 批量擷取
    • 服務端: blockcache配置是否合理, Hfile是否過多
    • 表結構的設計問題

在設定scan檢索的時候可以設定scan的cache;scan在檢索的時候不會一次将資料加載到本地;而是多次rpc請求加載(防止影響其他業務或者資料量大造成記憶體溢出);cache預設100條大小設定的大一點可以減少rpc的請求資料次數。

查詢資料的時候blockcache如果不能命中;還要去Hfile裡拉取資料。

Hfile不能過多;過多會導緻查詢緩慢;需要compact合并。

HBase協處理器簡介

  • HBase coprocessor
    • Hbase協處理器受bigtable協處理器的啟發, 為使用者提供類庫和運作時環境, 使得代碼能夠在hbase regionserver和master上處理
    • 系統協處理器and表協處理器(coprocessor分為兩類協處理器)
    • Observer and Endpoint(HBase 提供的coprocessor插件)
    • 系統協處理器: 全局加載到regionserver托管的所有表和region上(針對整個叢集)
    • 表協處理器: 使用者可以指定一張表使用協處理器(針對單張表)
    • 觀察者 (Observer): 類似于關系資料庫的觸發器
    • 終端 (Endpoint): 動态的終端有點像存儲過程
  • Observer
    • Regionobserver: 提供用戶端的資料操縱事件鈎子: Get, Put,Delete, Scan等
    • Masterobserver: 提供DDL類型的操作鈎子。如建立、删除修改資料表等
    • Walobserver: 提供wal相關操作鈎子
  • Observer應用場景
    • 安全性: 例如執行get或put操作前, 通過preget或preput方法檢查, 是否允許該操作
    • 引用完整性限制: hbase并不支援關系型資料庫中的引用完整性限制概念, 即通常所說的外鍵;我們可以使用協處理器增強這種限制
  • Endpoint
    • endpoint是動态rpc插件的接口, 它的實作代碼被安裝在伺服器端, 進而能夠通過hbase Rpc喚醒
    • 調用接口, 它們的實作代碼會被目标regionserver遠端執行·
    • 典型的案例: 一個大table有幾百個region, 需要計算某列的平均值或者總和

HBase實戰:開發RegionObserver協處理器

◆實作一個endpoint類型的協處理器

  • 待整理

◆實作一個regionobserver類型的協處理器

package com.kun.hbase;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Durability;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
import org.apache.hadoop.hbase.util.Bytes;



/**
 * Created by jixin on 18-2-25.
 */
public class RegionObserverTest extends BaseRegionObserver {

  private byte[] columnFamily = Bytes.toBytes("cf");
  private byte[] countCol = Bytes.toBytes("countCol");
  private byte[] unDeleteCol = Bytes.toBytes("unDeleteCol");
  private RegionCoprocessorEnvironment environment;

  //regionserver 打開region前執行
  @Override
  public void start(CoprocessorEnvironment e) throws IOException {
    environment = (RegionCoprocessorEnvironment) e;
  }

  //RegionServer關閉region前調用
  @Override
  public void stop(CoprocessorEnvironment e) throws IOException {

  }

  /**
   * 需求一
   * 1. cf:countCol 進行累加操作。 每次插入的時候都要與之前的值進行相加
   * 需要重載prePut方法
   */

  @Override
  public void prePut(ObserverContext<RegionCoprocessorEnvironment> e, Put put, WALEdit edit,
      Durability durability) throws IOException {
    if (put.has(columnFamily, countCol)) {//擷取old countcol value
      Result rs = e.getEnvironment().getRegion().get(new Get(put.getRow()));
      int oldNum = 0;
      for (Cell cell : rs.rawCells()) {
        if (CellUtil.matchingColumn(cell, columnFamily, countCol)) {
          oldNum = Integer.valueOf(Bytes.toString(CellUtil.cloneValue(cell)));
        }
      }

      //擷取new countcol value
      List<Cell> cells = put.get(columnFamily, countCol);
      int newNum = 0;
      for (Cell cell : cells) {
        if (CellUtil.matchingColumn(cell, columnFamily, countCol)) {
          newNum = Integer.valueOf(Bytes.toString(CellUtil.cloneValue(cell)));
        }
      }

      //sum AND update Put執行個體
      put.addColumn(columnFamily, countCol, Bytes.toBytes(String.valueOf(oldNum + newNum)));
    }
  }

  /**
   * 需求二
   * 2. 不能直接删除unDeleteCol    删除countCol的時候将unDeleteCol一同删除
   * 需要重載preDelete方法
   */
  @Override
  public void preDelete(ObserverContext<RegionCoprocessorEnvironment> e, Delete delete,
      WALEdit edit,
      Durability durability) throws IOException {
    //判斷是否操作删除了cf列族
    List<Cell> cells = delete.getFamilyCellMap().get(columnFamily);
    if (cells == null || cells.size() == 0) {
      return;
    }

    boolean deleteFlag = false;
    for (Cell cell : cells) {
      byte[] qualifier = CellUtil.cloneQualifier(cell);

      if (Arrays.equals(qualifier, unDeleteCol)) {
        throw new IOException("can not delete unDel column");
      }

      if (Arrays.equals(qualifier, countCol)) {
        deleteFlag = true;
      }
    }

    if (deleteFlag) {
      delete.addColumn(columnFamily, unDeleteCol);
    }
  }

}

           

HBase實戰:HBase協處理器加載

  • 待整理
  • 配置檔案加載: 即通過hbase-site. Xml檔案配置加載, 一般這樣的協處理器是系統級别的.
    --- HBase學習筆記 (叁)- HBase進階HBase協處理器簡介HBase實戰:開發RegionObserver協處理器HBase實戰:HBase協處理器加載
    --- HBase學習筆記 (叁)- HBase進階HBase協處理器簡介HBase實戰:開發RegionObserver協處理器HBase實戰:HBase協處理器加載
  • Shell加載: 可以通過alter指令來對表進行schema修改來加載協處理器
  • shell加載;jar包|全類名|優先級(會自動配置設定)|協處理器相關參數
    --- HBase學習筆記 (叁)- HBase進階HBase協處理器簡介HBase實戰:開發RegionObserver協處理器HBase實戰:HBase協處理器加載

    首先對regionobserver進行編譯 mvn clean install

    上傳到hdfs叢集中

    測試協處理器

    --- HBase學習筆記 (叁)- HBase進階HBase協處理器簡介HBase實戰:開發RegionObserver協處理器HBase實戰:HBase協處理器加載
    --- HBase學習筆記 (叁)- HBase進階HBase協處理器簡介HBase實戰:開發RegionObserver協處理器HBase實戰:HBase協處理器加載
    --- HBase學習筆記 (叁)- HBase進階HBase協處理器簡介HBase實戰:開發RegionObserver協處理器HBase實戰:HBase協處理器加載
    --- HBase學習筆記 (叁)- HBase進階HBase協處理器簡介HBase實戰:開發RegionObserver協處理器HBase實戰:HBase協處理器加載
    --- HBase學習筆記 (叁)- HBase進階HBase協處理器簡介HBase實戰:開發RegionObserver協處理器HBase實戰:HBase協處理器加載
    --- HBase學習筆記 (叁)- HBase進階HBase協處理器簡介HBase實戰:開發RegionObserver協處理器HBase實戰:HBase協處理器加載
    --- HBase學習筆記 (叁)- HBase進階HBase協處理器簡介HBase實戰:開發RegionObserver協處理器HBase實戰:HBase協處理器加載
  • 通過api代碼加載: 即通過api的方式來加載協處理器

    配置檔案加載

Hbase解除安裝/更新協處理器

  • 重複加載的第二個coprocessor執行個體不會發揮作用
  • 要完成解除安裝/更新就需要重新開機JVM, 也就是重新開機regionserver