Linux環境HBase安裝配置

YBCarry發表於2019-03-15

Linux環境HBase安裝配置

1. 認識HBase

(1) HBase介紹

  • HBase = Hadoop database,Hadoop資料庫
  • 開源資料庫
  • 官網:hbase.apache.org/
  • HBase源於Google的BigTable
  • Apache HBase™是Hadoop資料庫,是一個分散式,可擴充套件的大資料儲存。
  • 當需要對大資料進行隨機、實時讀/寫訪問時,請使用Apache HBase™。該專案的目標是託管非常大的表 - 數十億行X百萬列 - 在商品硬體叢集上。Apache HBase是一個開源的,分散式的,版本化的非關聯式資料庫nosql,模仿Google的Bigtable: Chang等人的結構化資料分散式儲存系統。正如Bigtable利用Google檔案系統提供的分散式資料儲存一樣,Apache HBase在Hadoop和HDFS之上提供類似Bigtable的功能。
  • HBase可執行基於Yarn平臺的計算任務,但不擅長。

(2) HBase叢集角色

  • HDFS:
    • NameNode——主節點
    • DataNode——資料儲存節點
  • Yarn:
    • ResourceManager——全域性的資源管理器
    • NodeManager——分節點資源和工作管理員
  • HBase:
    • HMaster
      • 負責Table表和RegionServer的監控管理工作
      • 處理後設資料的變更
      • 對HRegionServer進行故障轉移
      • 空閒時對資料進行負載均衡處理
      • 管理Region
      • 藉助ZooKeeper釋出位置到客戶端
    • HRegionServer
      • 負責Table資料的實際讀寫
      • 重新整理快取資料到HDFS
      • 處理Region
      • 可以進行資料壓縮
      • 維護Hlog
      • Region分片

(3) Hbase架構

Linux環境HBase安裝配置

  • HRegionServer結構:
    • HLog:儲存HBase的修改記錄
    • HRegion:根據rowkey(行鍵,類似id)分割的表的分片
    • Store:對應HBase表中的一個列族,可儲存多個欄位
    • HFile:真正的儲存檔案
    • MemStore:儲存當前的操作
    • ZooKeeper:存放資料的後設資料資訊,負責維護RegionServer中儲存的後設資料資訊
    • DFS Client:儲存資料資訊到HDFS叢集中

2. HBase-1.3.0安裝配置流程

(1) HBase準備

  • Hadoop叢集環境
  • ZooKeeper叢集環境

(2) 解壓HBase-1.3.0相關安裝包到目標目錄下:

  • tar -zxvf .tar.gz -C 目標目錄

(3) 修改配置檔案:

  • 進入hbase/conf路徑:
    • vi hbase-env.sh
    •  # The java implementation to use.  Java 1.7+ required.
       export JAVA_HOME=jdk安裝路徑
      
       # 註釋掉以下語句(jdk1.8中不需要這個配置)
       # export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS -XX:PermSize=128m -XX:MaxPermSize=128m"
       # export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS -XX:PermSize=128m -XX:MaxPermSize=128m"
      
       # Tell HBase whether it should manage it's own instance of Zookeeper or not.
       # 關閉HBase自帶的ZooKeeper
       export HBASE_MANAGES_ZK=false
      複製程式碼

  • vi hbase-site.xml
  •  <!-- 設定namenode所在位置(HDFS中存放的路徑) -->
       <property>
           <name>hbase.rootdir</name>
           <value>hdfs://bigdata01:9000/hbase</value>    
       </property>
       
       <!-- 是否開啟叢集 -->
       <property>
           <name>hbase.cluster.distributed</name>
           <value>true</value>
       </property>
       
       <!-- HBase-0.9.8之前預設埠為60000 -->
       <property>
           <name>hbase.master.port</name>
           <value>16000</value>
       </property>
       
       <!-- zookeeper叢集的位置 -->
       <property>
           <name>hbase.zookeeper.quorum</name>
           <!-- 注意不要有空格 -->   <value>bigdata01:2181,bigdata02:2181,bigdata03:2181</value>
       </property>
       
       <!-- hbase的後設資料資訊儲存在zookeeper的位置 -->
       <property>
           <name>hbase.zookeeper.property.dataDir</name>
           <value>/XXX/zookeeper-3.4.10/zkData</value>
       </property>
    複製程式碼

  • vi regionservers
  • 加入從節點主機名

(4) 解決依賴問題

  • 進入hbase/lib路徑:
    • rm -rf hadoop-*
    • rm -rf zookeeper-*
    • 把相關版本的zookeeper和hadoop的依賴包匯入到hbase/lib

(5) 軟連線hadoop配置

  • ln -s /XXX/hadoop/core-site.xml
  • ln -s /XXX/hadoop/hdfs-site.xml

(6) 拷貝配置好的HBase到其他機器上

  • scp -r hbase-1.3.0/ bigdata02:$PWD
  • scp -r hbase-1.3.0/ bigdata03:$PWD

(7) 配置環境變數:

  • 修改配置檔案:
    • vi /etc/profile
  • 增加以下內容:
    • export HBASE_HOME=/opt/module/hbase-1.3.0
    • export PATH=$PATH:$HBASE_HOME/bin
  • 宣告環境變數:
    • source /etc/profile

(8) 啟動叢集

  • 啟動主節點
    • hbase-daemon.sh start master
  • 啟動從節點
    • hbase-daemon.sh start regionserver

(9) 關閉叢集

  • 關閉主節點
    • hbase-daemon.sh stop master
  • 關閉從節點
    • hbase-daemon.sh stop regionserver

(10) UI介面

3. HBase Shell操作

(1) 啟動終端

  • hbase shell
  • 回退:ctrl + <-

(2) 操作命令:

  • 注意:
    • 若報錯:ERROR: Can't get master address from ZooKeeper; znode data == null
    • 解決方案:虛擬機器掛起,會使zookeeper不穩定,進而造成hbase不穩定,若遇到報錯,重啟HBase叢集即可。
  • 查詢表:
    • list
  • 顯示HBase伺服器狀態:
    • status '主機名'
    • 1 active master:存活的主節點
    • 0 backup masters:備份的主節點
    • 3 servers:從節點
    • 0 dead:當機
    • 0.6667 average load:平均載入時間
  • 顯示當前使用者:
    • whoami
  • 建立表:
    • create '表名', '列族1', '列族2'
  • 檢視錶:
    • 全表掃描:
      • scan '表名'
    • 指定Rowkey掃描:
      • scan '表名', {STARTROW => 'Rowkey值', STOPROW => 'Rowkey值'}
      • STOPROW為可選指令,值為實際檢視Rowkey+1
    • 檢視錶結構:
      • describe '表名'
      • 修改表結構資訊:
        • alter '表名', {NAME => '列族名', 變更欄位名 => ' '}
    • 查詢指定資料資訊:
      • 指定具體的rowkey:
        • get '表名', 'rowkey'
      • 指定具體的列:
        • get '表名', 'rowkey', '列族:列名'
      • 統計表行數:
        • count '表名'
        • 根據Rowkey進行統計
  • 表中新增資料資訊:
    • put '表名', 'rowkey', '列族:列名', '值'
    • HBase只有覆蓋沒有修改
    • 覆蓋時對應表名、rowkey、列族、列名欄位,輸入新的值資訊
  • 清空表:
    • truncate '表名'
  • 刪除表:
    • 指定表不可用:
      • disable '表名'
    • 刪除:
      • drop '表名'

(3) 退出終端

  • exit或者quit

4. HBase讀寫資料

(1) HBase讀資料流程

  • 概述:

    • 客戶端Client訪問ZooKeeper,返回-ROOT-表後設資料位置,根據後設資料位置去查詢對應的RegionServer,同時根據-ROOT-查詢到.META表,再根據.META表的後設資料查詢到Region,返回Region的業務後設資料給客戶端。

    Linux環境HBase安裝配置

  • 具體流程:

    • 客戶端Client從Region中的Store中讀取資料,若在寫資料快取memstore(存放使用者最近寫入的資料)中讀到對應資料,則直接返回資料資訊到客戶端,若memstore中不存在對應資料,則去讀資料快取blockcache中查詢,若blockcache中仍未找到,則去對應的HFile查詢資料資訊並存入blockcache,進而通過blockcache返回資料資訊到客戶端。HBase讀寫分離

Linux環境HBase安裝配置

(2) HBase寫資料流程

  • 客戶端Client傳送寫資料請求,通過ZooKeeper獲取到表的後設資料資訊,客戶端通過RPC通訊查詢到對應的RegionServer,進而找到Region,同時在HLog中記錄寫操作,通過HLog把資料資訊寫入到memstore(16KB),memstore存滿後溢寫到storeFile中,最後HDFS客戶端統一儲存到HFile。

Linux環境HBase安裝配置

5. HBase API操作

(1) 準備工作

  • 新建Maven工程,pom.xml中新增依賴:
    • <dependencies>
          <dependency>
              <groupId>org.apache.hbase</groupId>
              <artifactId>hbase-server</artifactId>
              <version>1.3.0</version>
          </dependency>
          <dependency>
              <groupId>org.apache.hbase</groupId>
              <artifactId>hbase-client</artifactId>
              <version>1.3.0</version>
          </dependency>
      </dependencies>
      複製程式碼
  • 從HBase下的conf/目錄中匯出core-site.xml,hbase-site.xml,hdfs-site.xml,匯入Maven工程的resources目錄下。
    • 注意:不進行該操作會導致與HBase連線失敗

(2) 具體操作

  • package ybcarry.hbase;
    
    
      import org.apache.hadoop.conf.Configuration;
      import org.apache.hadoop.hbase.*;
      import org.apache.hadoop.hbase.client.*;
      import org.apache.hadoop.hbase.util.Bytes;
      
      import java.io.IOException;
      import java.util.ArrayList;
      import java.util.List;
      
      /**
       * @ClassName: HbaseTest
       * @Description
       * @Author: YBCarry
       * @Date2019-03-30 21:10
       * @Version: V1.0
       **/
      
      public class HbaseTest {
      
          public static Configuration conf ;
      
          //配置資訊
          static {
              conf = HBaseConfiguration.create() ;
          }
      
          /**1. 判斷HBase中表是否存在*/
          public static boolean isExist(String tableNane) throws IOException {
      
              //舊版本操作表
              //HBaseAdmin admin = new HBaseAdmin(conf);
      
              //載入配置
              Connection connection = ConnectionFactory.createConnection(conf) ;
      
              //管理器
              HBaseAdmin admin = (HBaseAdmin)connection.getAdmin() ;
      
              return admin.tableExists(TableName.valueOf(tableNane)) ;
          }
      
          /**2. 在HBase中建立表*/
          public static void createTable(String tableName, String... columnFamilly) throws IOException {
      
              //載入配置
              Connection connection = ConnectionFactory.createConnection(conf) ;
      
              //a. 如果對錶的操作需要使用管理器
              HBaseAdmin admin = (HBaseAdmin)connection.getAdmin() ;
      
              //b. 建立描述器
              HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(tableName)) ;
      
              //c. 指定多個列族
              for (String cf : columnFamilly) {
                  htd.addFamily(new HColumnDescriptor(cf)) ;
              }
      
              //d. 建立表
              admin.createTable(htd) ;
              System.out.println("createTable----successful") ;
          }
      
          /**3. 向表中新增資料*/
          public static void addData(String tableName, String rowkey, String cf, String column, String value) throws IOException {
      
              //載入配置
              Connection connection = ConnectionFactory.createConnection(conf) ;
      
              //a. 指定表
              Table table = connection.getTable(TableName.valueOf(tableName)) ;
      
              //b. 新增資料 put方式
              Put put = new Put(Bytes.toBytes(rowkey)) ;
      
              //c. 指定新增的列族 列 值
              put.addColumn(Bytes.toBytes(cf), Bytes.toBytes(column), Bytes.toBytes(value)) ;
      
              //d. 寫入表中
              table.put(put) ;
              System.out.println("addData----successful") ;
      
          }
      
          /**4. 刪除一個rowkey*/
          public static void deleteRow(String tableName, String rowkey) throws IOException {
      
              //載入配置
              Connection connection = ConnectionFactory.createConnection(conf) ;
      
              //a. 指定表
              Table table = connection.getTable(TableName.valueOf(tableName)) ;
      
              //b. 刪除rowkey delete方式
              Delete delete = new Delete(Bytes.toBytes(rowkey)) ;
      
              //d. 執行操作
              table.delete(delete) ;
              System.out.println("deleteRow----successful") ;
          }
      
          /**5. 刪除多個rowkey*/
          public static void deleteRows(String tableName, String... rowkey) throws IOException {
      
              //載入配置
              Connection connection = ConnectionFactory.createConnection(conf) ;
      
              //a. 指定表
              Table table = connection.getTable(TableName.valueOf(tableName)) ;
      
              //b. 封裝delete操作
              List<Delete> ds = new ArrayList<Delete>() ;
      
              //c. 遍歷rowkey
              for (String rk : rowkey) {
                  Delete deletes = new Delete(Bytes.toBytes(rk)) ;
                  ds.add(deletes) ;
              }
      
              //d. 執行操作
              table.delete(ds) ;
              System.out.println("deleteRows----successful") ;
          }
      
          /**6. 全表掃描*/
          public static void scanAll(String tableName) throws IOException {
      
              //載入配置
              Connection connection = ConnectionFactory.createConnection(conf) ;
      
              //a. 指定表
              Table table = connection.getTable(TableName.valueOf(tableName)) ;
      
              //b. 掃描操作
              Scan scan = new Scan() ;
      
              //c. 獲取返回值
              ResultScanner rs = table.getScanner(scan) ;
      
              //d. 列印掃描資訊
              for (Result r : rs) {
      
                  //單元格
                  Cell[] cells = r.rawCells() ;
      
                  for (Cell cs : cells) {
                      System.out.println("RowKey:" + Bytes.toString(CellUtil.cloneRow(cs))) ;
                      System.out.println("ColumnFamilly:" + Bytes.toString(CellUtil.cloneFamily(cs))) ;
                      System.out.println("Column:" + Bytes.toString((CellUtil.cloneQualifier(cs)))) ;
                      System.out.println("Value:" + Bytes.toString((CellUtil.cloneValue(cs)))) ;
                  }
              }
      
              //成功標誌
              System.out.println("scanAll----successful") ;
          }
      
          /**7. 刪除表*/
          public static void deleteTable(String tableName) throws IOException {
      
              //載入配置
              Connection connection = ConnectionFactory.createConnection(conf) ;
      
              //a. 如果對錶的操作需要使用管理器
              HBaseAdmin admin = (HBaseAdmin)connection.getAdmin() ;
      
              //b. 棄用表
              admin.disableTable(tableName) ;
      
              //c. 刪除表
              admin.deleteTable(TableName.valueOf(tableName)) ;
      
              //成功標誌
              System.out.println("deleteTable----successful") ;
          }
      
      
          /**主函式*/
          public static void main(String[] args) throws IOException {
      
              /**1. 判斷HBase中表是否存在*/
      //        System.out.println(isExist("user")) ;
      
              /**2. 在HBase中建立表*/
      //        createTable("create1", "info1", "info2", "info3") ;
      
              /**3. 向表中新增資料:列族 列 值*/
      //        addData("create1", "xiaoming", "info1", "age", "18") ;
      //        addData("create1", "xiaoming", "info1", "sex", "man") ;
      //        addData("create1", "xiaoming", "info2", "professional", "student") ;
      //        addData("create1", "xiaohong", "info2", "professional", "teacher") ;
      
              /**4. 刪除一個rowkey*/
      //        deleteRow("create", "xiaoming") ;
      
              /**5. 刪除多個rowkey*/
      //        deleteRows("create", "xiaoming", "xiaohong") ;
      
              /**6. 全表掃描*/
      //        scanAll("create1") ;
      
              /**7. 刪除表*/
              deleteTable("create2") ;
          }
      }
    複製程式碼

相關文章