1. 程式人生 > >hbase學習教程(三):HBase優化技巧、HBase基本命令、使用Java API對HBase伺服器進行操作

hbase學習教程(三):HBase優化技巧、HBase基本命令、使用Java API對HBase伺服器進行操作

HBase優化技巧

1 修改 linux 系統引數
Linux系統最大可開啟檔案數一般預設的引數值是1024,如果你不進行修改併發量上來的時候會出現“Too Many Open Files”的錯誤,導致整個HBase不可執行,你可以用ulimit -n 命令進行修改,或者修改/etc/security/limits.conf 和/proc/sys/fs/file-max 的引數,具體如何修改可以去Google 關鍵字 “linux limits.conf ”

2 JVM 配置
修改 hbase-env.sh 檔案中的配置引數,根據你的機器硬體和當前作業系統的JVM(32/64位)配置適當的引數
HBASE_HEAPSIZE 4000 HBase使用的 JVM 堆的大小
HBASE_OPTS “‐server ‐XX:+UseConcMarkSweepGC”JVM GC 選項
HBASE_MANAGES_ZKfalse 是否使用Zookeeper進行分散式管理

3 HBase持久化
重啟作業系統後HBase中資料全無,你可以不做任何修改的情況下,建立一張表,寫一條資料進行,然後將機器重啟,重啟後你再進入HBase的shell中使用 list 命令檢視當前所存在的表,一個都沒有了。是不是很杯具?沒有關係你可以在hbase/conf/hbase-default.xml中設定hbase.rootdir的值,來設定檔案的儲存位置指定一個資料夾 ,例如:file:///you/hbase-data/path,你建立的HBase中的表和資料就直接寫到了你的磁碟上,如圖所示:
這裡寫圖片描述
同樣你也可以指定你的分散式檔案系統HDFS的路徑例如: hdfs://NAMENODE_SERVER:PORT/HBASE_ROOTDIR,這樣就寫到了你的分散式檔案系統上了。

4 配置HBase執行引數
其次就需要對hbase/conf/hbase-default.xml 檔案進行配置,以下是我認為比較重要的配置引數

hbase.client.write.buffer
描述:這個引數可以設定寫入資料緩衝區的大小,當客戶端和伺服器端傳輸資料,伺服器為了提高系統執行效能開闢一個寫的緩衝區來處理它, 這個引數設定如果設定的大了,將會對系統的記憶體有一定的要求,直接影響系統的效能。

hbase.master.meta.thread.rescanfrequency
描述:多長時間 HMaster對系統表 root 和 meta 掃描一次,這個引數可以設定的長一些,降低系統的能耗。

hbase.regionserver.handler.count
描述:由於HBase/Hadoop的Server是採用Multiplexed, non-blocking I/O方式而設計的,所以它可以透過一個Thread來完成處理,但是由於處理Client端所呼叫的方法是Blocking I/O,所以它的設計會將Client所傳遞過來的物件先放置在Queue,並在啟動Server時就先產生一堆Handler(Thread),該Handler會透過Polling的方式來取得該物件並執行對應的方法,預設為25,根據實際場景可以設定大一些。

hbase.regionserver.thread.splitcompactcheckfrequency
描述:這個引數是表示多久去RegionServer伺服器執行一次split/compaction的時間間隔,當然split之前會先進行一個compact操作.這個compact操作可能是minor compact也可能是major compact.compact後,會從所有的Store下的所有StoreFile檔案最大的那個取midkey.這個midkey可能並不處於全部資料的mid中.一個row-key的下面的資料可能會跨不同的HRegion。

hbase.hregion.max.filesize
描述:HRegion中的HStoreFile最大值,任何表中的列族一旦超過這個大小將會被切分,而HStroeFile的預設大小是256M。

hfile.block.cache.size
描述:指定 HFile/StoreFile 快取在JVM堆中分配的百分比,預設值是0.2,意思就是20%,而如果你設定成0,就表示對該選項遮蔽。

hbase.zookeeper.property.maxClientCnxns
描述: 這項配置的選項就是從zookeeper中來的,表示ZooKeeper客戶端同時訪問的併發連線數,ZooKeeper對於HBase來說就是一個入口這個引數的值可以適當放大些。

hbase.regionserver.global.memstore.upperLimit
描述:在Region Server中所有memstores佔用堆的大小引數配置,預設值是0.4,表示40%,如果設定為0,就是對選項進行遮蔽。

hbase.hregion.memstore.flush.size
描述:Memstore中快取的內容超過配置的範圍後將會寫到磁碟上,例如:刪除操作是先寫入MemStore裡做個標記,指示那個value, column 或 family等下是要刪除的,HBase會定期對儲存檔案做一個major compaction,在那時HBase會把MemStore刷入一個新的HFile儲存檔案中。如果在一定時間範圍內沒有做major compaction,而Memstore中超出的範圍就寫入磁碟上了。

5 HBase中log4j的日誌
HBase中日誌輸出等級預設狀態下是把debug、 info 級別的日誌開啟的,可以根據自己的需要調整log級別,HBase的log4j日誌配置檔案在 hbase\conf\log4j.properties 目錄下。

HBase基本命令

下面我們再看看看HBase的一些基本操作命令,我列出了幾個常用的HBase Shell命令,如下:
名稱 命令表示式
建立表 create ‘表名稱’, ‘列名稱1’,’列名稱2’,’列名稱N’
新增記錄 put ‘表名稱’, ‘行名稱’, ‘列名稱:’, ‘值’
檢視記錄 get ‘表名稱’, ‘行名稱’
查看錶中的記錄總數 count ‘表名稱’
刪除記錄 delete ‘表名’ ,’行名稱’ , ‘列名稱’
刪除一張表 先要遮蔽該表,才能對該表進行刪除,第一步 disable ‘表名稱’ 第二步 drop ‘表名稱’
檢視所有記錄 scan “表名稱”
檢視某個表某個列中所有資料 scan “表名稱” , [‘列名稱:’]
更新記錄 就是重寫一遍進行覆蓋
如果你是一個新手隊HBase的一些命令還不算非常熟悉的話,你可以進入 hbase 的shell 模式中你可以輸入 help 命令檢視到你可以執行的命令和對該命令的說明,例如對scan這個命令,help中不僅僅提到有這個命令,還詳細的說明了scan命令中可以使用的引數和作用,例如,根據列名稱查詢的方法和帶LIMIT 、STARTROW的使用方法:
scan Scan a table; pass table name and optionally a dictionary of scanner specifications.
Scanner specifications may include one or more of the following: LIMIT, STARTROW, STOPROW, TIMESTAMP, or COLUMNS.
If no columns are specified, all columns will be scanned. To scan all members of a column family, leave the
qualifier empty as in ‘col_family:’. Examples:
hbase> scan ‘.META.’
hbase> scan ‘.META.’, {COLUMNS => ‘info:regioninfo’}
hbase> scan ‘t1’, {COLUMNS => [‘c1’, ‘c2’], LIMIT => 10, STARTROW => ‘xyz’}

使用Java API對HBase伺服器進行操作

需要下列jar包
hbase-0.20.6.jar
hadoop-core-0.20.1.jar
commons-logging-1.1.1.jar
zookeeper-3.3.0.jar
log4j-1.2.91.jar

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.io.BatchUpdate;

@SuppressWarnings(“deprecation”)
public class HBaseTestCase {

static HBaseConfiguration cfg = null;
 static {
     Configuration HBASE_CONFIG = new Configuration();
     HBASE_CONFIG.set("hbase.zookeeper.quorum", "192.168.50.216");
     HBASE_CONFIG.set("hbase.zookeeper.property.clientPort", "2181");
     cfg = new HBaseConfiguration(HBASE_CONFIG);
 }

/**
  * 建立一張表
 */
 public static void creatTable(String tablename) throws Exception {
     HBaseAdmin admin = new HBaseAdmin(cfg);
     if (admin.tableExists(tablename)) {
         System.out.println("table   Exists!!!");
     }
     else{
         HTableDescriptor tableDesc = new HTableDescriptor(tablename);
         tableDesc.addFamily(new HColumnDescriptor("name:"));
         admin.createTable(tableDesc);
         System.out.println("create table ok .");
     }

 }

/**
  * 新增一條資料
 */
 public static void addData (String tablename) throws Exception{
      HTable table = new HTable(cfg, tablename);
          BatchUpdate update = new BatchUpdate("Huangyi");  
         update.put("name:java", "http://www.javabloger.com".getBytes());  
         table.commit(update);  
     System.out.println("add data ok .");
 }

/**
  * 顯示所有資料
 */
 public static void getAllData (String tablename) throws Exception{
      HTable table = new HTable(cfg, tablename);
      Scan s = new Scan();
      ResultScanner ss = table.getScanner(s);
      for(Result r:ss){
          for(KeyValue kv:r.raw()){
             System.out.print(new String(kv.getColumn()));
             System.out.println(new String(kv.getValue()    ));
          }

     }
 }


public static void  main (String [] agrs) {
     try {
             String tablename="tablename";
             HBaseTestCase.creatTable(tablename);
             HBaseTestCase.addData(tablename);
             HBaseTestCase.getAllData(tablename);
         } 
    catch (Exception e) {
         e.printStackTrace();
     }

}

}