1. 程式人生 > >HBase核心知識點總結

HBase核心知識點總結

一、HBase介紹

1、基本概念

HBase是一種Hadoop資料庫,經常被描述為一種稀疏的,分散式的,持久化的,多維有序對映,它基於行鍵、列鍵和時間戳建立索引,是一個可以隨機訪問的儲存和檢索資料的平臺。HBase不限制儲存的資料的種類,允許動態的、靈活的資料模型,不用SQL語言,也不強調資料之間的關係。HBase被設計成在一個伺服器叢集上執行,可以相應地橫向擴充套件。

2、HBase使用場景和成功案例

  • 網際網路搜尋問題:爬蟲收集網頁,儲存到BigTable裡,MapReduce計算作業掃描全表生成搜尋索引,從BigTable中查詢搜尋結果,展示給使用者。
  • 抓取增量資料:例如,抓取監控指標,抓取使用者互動資料,遙測技術,定向投放廣告等
  • 內容服務
  • 資訊互動

3、HBase Shell命令列互動:

啟動Shell    $ hbase shell

列出所有的表   hbase >  list

建立名為mytable的表,含有一個列族hb    hbase > create ' mytable' , 'hb'

 在‘mytable’表的'first'行中的‘hb:data’列對應的資料單元中插入位元組陣列‘hello HBase’

  hbase > put  'mytable' , 'first' , 'hb:data' , 'hello HBase' 

讀取mytable表 ‘first’行的內容   hbase > get 'mytable' , 'first' 

讀取mytable表所有的內容      hbase > scan ‘mytable' 

二、入門

1、API

和資料操作有關的HBase API有5個,分別是 Get(讀),Put(寫),Delete(刪),Scan(掃描)和Increment(列值遞增)

2、操作表

首先要建立一個configuration物件

   Configuration conf = HBaseConfiguration.create();

使用eclipse時的話還必須將配置檔案新增進來。
   conf.addResource(new Path("E:\\share\\hbase-site.xml"));

     conf.addResource(new Path("E:\\share\\core-site.xml"));

    conf.addResource(new Path("E:\\share\\hdfs-site.xml"));

   使用連線池建立一張表。

   HTablePool pool = new HTablePool(conf,1);
   HTableInterface usersTable = pool.getTable("users");

3、寫操作

  用來儲存資料的命令是put,往表裡儲存資料,需要建立Put例項。並制定要加入的行

  Put put = new Put(byte[]  row) ;

  Put的add方法用來新增資料,分別設定列族,限定符以及單元格的指

  put.add(byte[] family , byte[] qualifier , byte[] value) ; 

  最後提交命令給表

  usersTable.put(put);

  usersTable.close();

  修改資料,只需重新提交一次最新的資料即可。

HBase寫操作的工作機制:

   

  HBase每次執行寫操作都會寫入兩個地方:預寫式日誌(write-ahead log,也稱HLog)和MemStore(寫入緩衝區),以保證資料持久化,只有當這兩個地方的變化資訊都寫入並確認後,才認為寫動作完成。MemStore是記憶體裡的寫入緩衝區,HBase中資料在永久寫入硬碟之前在這裡累積,當MemStore填滿後,其中的資料會刷寫到硬碟,生成一個HFile。

4、讀操作

 建立一個Get命令例項,包含要查詢的行

Get get = new Get(byte[]  row) ;

執行addColumn()或addFamily()可以設定限制條件。

將get例項提交到表會返回一個包含資料的Result例項,例項中包含行中所有列族的所有列。

Result  r = usersTable.get(get) ;

可以對result例項檢索特定的值

byte[] b = r.getValue(byte[] family , byte[] qualifier) ;

工作機制:

 

BlockCache用來儲存從HFile中讀入記憶體的頻繁訪問的資料,避免硬碟讀,每個列族都有自己的BlockCache。從HBase中讀出一行,首先會檢查MemStore等待修改的佇列,然後檢查BlockCache看包含該行的Block是否最近被訪問過,最後訪問硬碟上的對應HFile。

5、刪除操作

建立一個Delete例項,指定要刪除的行。

Delete delete = new Delete(byte[]  row) ;

可以通過deleteFamily()和deleteColumn()方法指定刪除行的一部分。

6表掃描操作

Scan scan = new Scan() 可以指定起始行和結束行。

setStartRow() , setStopRow() , setFilter()方法可以用來限制返回的資料。

addColumn()和addFamily()方法還可以指定列和列族。

HBase模式的資料模型包括:

表:HBase用表來組織資料。

行:在表裡,資料按行儲存,行由行鍵唯一標識。行鍵沒有資料型別,為位元組陣列byte[]。

列族:行裡的資料按照列族分組,列族必須事先定義並且不輕易修改。表中每行擁有相同的列族。

列限定符:列族裡的資料通過列限定符或列來定位,列限定符不必事先定義。

單元:儲存在單元裡的資料稱為單元值,值是位元組陣列。單元由行鍵,列族或列限定符一起確定。

時間版本:單元值有時間版本,是一個long型別。

一個HBase資料座標的例子:

 

HBase可以看做是一個鍵值資料庫。HBase的設計是面向半結構化資料的,資料記錄可能包含不一致的列,不確定大小等。

三、分散式的HBase、HDFS和MapReduce

1、分散式模式的HBase

HBase將表會切分成小的資料單位叫region,分配到多臺伺服器。託管region的伺服器叫做RegionServer。一般情況下,RgionServer和HDFS DataNode並列配置在同一物理硬體上,RegionServer本質上是HDFS客戶端,在上面儲存訪問資料,HMaster分配region給RegionServer,每個RegionServer託管多個region。

 

HBase中的兩個特殊的表,-ROOT-和.META.,用來查詢各種表的region位置在哪。-ROOT-指向.META.表的region,.META.表指向託管待查詢的region的RegionServer。

一次客戶端查詢過程的3層分散式B+樹如下圖:

 

HBase頂層結構圖:

 

zookeeper負責跟蹤region伺服器,儲存root region的地址。

Client負責與zookeeper子叢集以及HRegionServer聯絡。

HMaster負責在啟動HBase時,把所有的region分配到每個HRegion Server上,也包括-ROOT-和.META.表。

HRegionServer負責開啟region,並建立對應的HRegion例項。HRegion被開啟後,它為每個表的HColumnFamily建立一個Store例項。每個Store例項包含一個或多個StoreFile例項,它們是實際資料儲存檔案HFile的輕量級封裝。每個Store有其對應的一個MemStore,一個HRegionServer共享一個HLog例項。

一次基本的流程:

a、 客戶端通過zookeeper獲取含有-ROOT-的region伺服器名。

b、 通過含有-ROOT-的region伺服器查詢含有.META.表中對應的region伺服器名。

c、  查詢.META.伺服器獲取客戶端查詢的行鍵資料所在的region伺服器名。

d、 通過行鍵資料所在的region伺服器獲取資料。

HFile結構圖:

 

Trailer有指向其他塊的指標,Index塊記錄Data和Meta塊的偏移量,Data和Meta塊儲存資料。預設大小是64KB。每個塊包含一個Magic頭部和一定數量的序列化的KeyValue例項。

KeyValue格式:

 

該結構以兩個分別表示鍵長度和值長度的定長數字開始,鍵包含了行鍵,列族名和列限定符,時間戳等。

預寫日誌WAL:

每次更新都會寫入日誌,只有寫入成功才會通知客戶端操作成功,然後伺服器可以按需自由地批量處理或聚合記憶體中的資料。

編輯流在memstore和WAL之間分流的過程:

 

處理過程:客戶端通過RPC呼叫將KeyValue物件例項傳送到含有匹配region的HRegionServer。接著這些例項被髮送到管理相應行的HRegion例項,資料被寫入到WAL,然後被放入到實際擁有記錄的儲存檔案的MemStore中。當memstore中的資料達到一定的大小以後,資料會非同步地連續寫入到檔案系統中,WAL能保證這一過程的資料不會丟失。

2、HBase和MapReduce

從MapReduce應用訪問HBase有3種方式:

作業開始時可以用HBase作為資料來源,作業結束時可以用HBase接收資料,任務過程中用HBase共享資源。

  • 使用HBase作為資料來源

階段map

protected void map(ImmutableBytesWritable rowkey,Result result,Context context){

};

從HBase表中讀取的作業以[rowkey:scan result]格式接收[k1,v1]鍵值對,對應的型別是ImmutableBytesWritable和Result。

建立例項掃描表中所有的行

Scan scan = new Scan();

scan.addColumn(…);

接下來在MapReduce中使用Scan例項。

TableMapReduceUtil.initTableMapperJob(tablename,scan,map.class,

輸出鍵的型別.class,輸出值的型別.class,job);

  • 使用HBase接收資料

reduce階段

protected void reduce(

ImmutableBytesWritable rowkey,Iterable<put>values,Context context){

};

把reducer填入到作業配置中,

TableMapReduceUtil.initTableReducerJob(tablename,reduce.class,job);

3、HBase實現可靠性和可用性

HDFS作為底層儲存,為叢集裡的所有RegionServer提供單一名稱空間,一個RegionServer讀寫資料可以為其它所有RegionServer讀寫。如果一個RegionServer出現故障,任何其他RegionServer都可以從底層檔案系統讀取資料,基於儲存在HDFS裡的HFile開始提供服務。接管這個RegionServerz服務的region。

四、優化HBase

1、隨機讀密集型

優化方向:高效利用快取和更好的索引

  •  增加快取使用的堆的百分比,通過引數 hfile.block.cache.size 配置。
  • 減少MemStore佔用的百分比,通過hbase.regionserver.global.memstore.lowerLimit和hbase.regionserver.global.memstore.upperLimit來調節。
  • 使用更小的資料塊,使索引的粒度更細。
  • 開啟布隆過濾器,以減少為查詢指定行的Key Value物件而讀取的HFile的數量。
  • 設定激進快取,可以提升隨機讀效能。
  • 關閉沒有被用到隨機讀的列族,提升快取命中率。

2、順序讀密集型

優化方向:減少使用快取。

  • 增大資料塊的大小,使每次硬碟尋道時間取出的資料更多。
  • 設定較高的掃描器快取值,以便在執行大規模順序讀時每次RPC請求掃描器可以取回更多行。 引數 hbase.client.scanner.caching 定義了在掃描器上呼叫next方法時取回的行的數量。
  • 關閉資料塊的快取,避免翻騰快取的次數太多。通過Scan.setCacheBlocks(false)設定。
  • 關閉表的快取,以便在每次掃描時不再翻騰快取。
  • 3、寫密集型

優化方向:不要太頻繁刷寫,合併或者拆分。

  • 調高底層儲存檔案(HStoreFile)的最大大小,region越大意味著在寫的時候拆分越少。通過引數 hbase.hregion.max.filesize設定。
  • 增大MemStore的大小,通過引數hbase.hregion.memstore.flush.size調節。刷寫到HDFS的資料越多,生產的HFile越大,會在寫的時候減少生成檔案的數量,從而減少合併的次數。
  • 在每臺RegionServer上增加分配給MemStore的堆比例。把upperLimit設為能夠容納每個region的MemStore乘以每個RegionServer上預期region的數量。
  • 垃圾回收優化,在hbase-env.sh檔案裡設定,可以設定初始值為:-Xmx8g  -Xms8g  -Xmn128m  -XX:+UseParNewGC  -XX:+UseConcMarkSweepGC

   -XX:CMSInitiatingOccupancyFraction=70

  • 開啟MemStore-Local Allocation Buffer這個特性,有助於防止堆的碎片化。 通過引數hbase.hregion.memstore.mslab.enabled設定

4、混合型

優化方向:需要反覆嘗試各種組合,然後執行測試,得到最佳結果。

影響效能的因素還包括:

  • 壓縮:可以減少叢集上的IO壓力
  • 好的行鍵設計
  • 在預期叢集負載最小的時候手工處理大合併
  • 優化RegionServer處理程式計數