hadoop相關-HBase體系結構

 

 

 

HBase的體系結構遵從主從服務器架構

主:HBase Master

從:HRegion Server羣

 

HBase中所有的服務器都是通過Zookeeper來協調 ,並處理運行期間可能出現的錯誤。

 

 

一、邏輯模型

以nutch-2.0下hbase存放數據的表"webpage"爲例:

describe:

 

{NAME => 'webpage',

FAMILIES => [

 

{NAME => 'f', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', COMPRESSION => 'NONE', VERSIONS => '1', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'},
{NAME => 'h', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', COMPRESSION => 'NONE', VERSIONS => '1', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'},
{NAME => 'il', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', COMPRESSION => 'NONE', VERSIONS => '1', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'},
{NAME => 'mk', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', COMPRESSION => 'NONE', VERSIONS => '1', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'},
{NAME => 'mtdt', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', COMPRESSION => 'NONE', VERSIONS => '1', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'},
{NAME => 'ol', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', COMPRESSION => 'NONE', VERSIONS => '1', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'},
{NAME => 'p', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', COMPRESSION => 'NONE', VERSIONS => '1', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'},
{NAME => 's', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', COMPRESSION => 'NONE', VERSIONS => '1', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}

]

}

 

由表的描述(describe)可以得到表的結構,如上所示:

表名:webpage

列簇(FAMILIES):'f','h','il','mk','mtdt','ol','p','s'

一個FAMILY可以包含多個Column,webpage表中的列簇關係見nutch-2.0/conf/gora-hbase-mapping.xml,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at
  
  http://www.apache.org/licenses/LICENSE-2.0
  
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<gora-orm>
    
    <table name="webpage">
        <family name="p" maxVersions="1"/> <!-- This can also have params like compression, bloom filters -->
        <family name="f" maxVersions="1"/>
        <family name="s" maxVersions="1"/>
        <family name="il" maxVersions="1"/>
        <family name="ol" maxVersions="1"/>
        <family name="h" maxVersions="1"/>
        <family name="mtdt" maxVersions="1"/>
        <family name="mk" maxVersions="1"/>
    </table>
    <class table="webpage" keyClass="java.lang.String" name="org.apache.nutch.storage.WebPage">
        
        <!-- fetch fields                                       -->
        <field name="baseUrl" family="f" qualifier="bas"/>
        <field name="status" family="f" qualifier="st"/>
        <field name="prevFetchTime" family="f" qualifier="pts"/>
        <field name="fetchTime" family="f" qualifier="ts"/>
        <field name="fetchInterval" family="f" qualifier="fi"/>
        <field name="retriesSinceFetch" family="f" qualifier="rsf"/>
        <field name="reprUrl" family="f" qualifier="rpr"/>
        <field name="content" family="f" qualifier="cnt"/>
        <field name="contentType" family="f" qualifier="typ"/>
        <field name="protocolStatus" family="f" qualifier="prot"/>
        <field name="modifiedTime" family="f" qualifier="mod"/>
        
        <!-- parse fields                                       -->
        <field name="title" family="p" qualifier="t"/>
        <field name="text" family="p" qualifier="c"/>
        <field name="parseStatus" family="p" qualifier="st"/>
        <field name="signature" family="p" qualifier="sig"/>
        <field name="prevSignature" family="p" qualifier="psig"/>
        
        <!-- score fields                                       -->
        <field name="score" family="s" qualifier="s"/>
        <field name="headers" family="h"/>
        <field name="inlinks" family="il"/>
        <field name="outlinks" family="ol"/>
        <field name="metadata" family="mtdt"/>
        <field name="markers" family="mk"/>
    </class>
    
    <table name="host">
      <family name="mtdt" maxVersions="1"/>
      <family name="il" maxVersions="1"/>
      <family name="ol" maxVersions="1"/>
    </table>
    
    <class table="host" keyClass="java.lang.String" name="org.apache.nutch.storage.Host">
      <field name="metadata" family="mtdt"/>
      <field name="inlinks" family="il"/>
      <field name="outlinks" family="ol"/>
    </class>
    
</gora-orm>

 

webpage的邏輯結構如下圖:


 

row key: Table的主鍵,Table中的記錄按照Row Key排序,url倒排索引

timestamp: 時間戳,每次數據操作對應的時間戳,可以看作是數據的version number

Column Family:列簇,Table在水平方向有一個或者多個Column Family組成,一個Column Family中可以由任意多個Column組成,即Column Family支持動態擴展,無需預先定義Column的數量以及類型,所有Column均以二進制格式存儲,用戶需要自行進行類型轉換。列簇預先定義,列動態擴展

 

其實,只要在某一時刻tn更新了某一行(row),某一列簇:某一列的數據,在邏輯視圖中就會增加一個timestamp=tn,然後在該行、該列簇、該列存儲新增的內容,當然,如果在該時刻增加了該行多個列簇:列的數據,那麼新增的內容將對應同一個時間戳。

問題:若在某時刻刪除了某行:某列簇:某列的內容呢?

根據在下的測試,在表中沒有記錄相應的操作信息,就是直接把它給刪掉了!(有待驗證)

 

二、物理模型

hbase中的表被劃分成多個HRegion,然後存儲到HRegion Server羣當中,HBase Master Server中存儲的是數據到HRegion Server的映射。

 

在物理模型下,表的最小單位是cell ,一個cell是指由行、列簇:列所確定的單元,其中存放的內容是timestamp和value,在上面的邏輯視圖中將timestamp抽象了出來,所以會存在空白的“虛擬單元”,這些空白的“虛擬單元”實際上不會被保存,所以在物理模型下就是按列簇來保存,當某列簇中的某列新增內容時就在該列簇:列中保存timestamp和value,此處的timestamp其實表徵了版本,因爲更新內容時並不刪除原來的內容,只是增加本次的內容。而更新其他列簇 的內容時並不需要在該列簇下寫數據,其實也沒有什麼數據可寫。

 

好像說的複雜了些,其實也很簡單的道理,全是廢話。

 

三、HRegion

當表的大小超過設置值(hbase.hregion.max.filesize )的時候,HBase會自動將表劃分爲不同的區域,表是這些區域的集合,靠主鍵區分,每個區域即是一個HRegion,一個region由[startkey,endkey)表示,不同的region會被Master分配給相應的RegionServer進行管理:

圖中有三個regionserver: rs1,rs2,rs3,表由主鍵被分割成幾個部分,分配給相應的regionserver管理,其中一個regionserver可以管理不同的Hregion。

 

四、HRegionServer

 

HRegionServer主要負責響應用戶I/O請求向HDFS文件系統中讀寫數據 ,是HBase中最核心的模塊。

 

HRegionServer內部管理了一系列HRegion對象,每個HRegion對應了Table中的一個Region,HRegion中由多個HStore組成。

 

HStore存儲是HBase存儲的核心了,其中由兩部分組成,一部分是MemStore ,一部分是StoreFiles 。用戶寫入的數據首先會放入MemStore,當MemStore(大小由hbase.hregion.memstore.flush.size設置,默認64M )滿了以後會Flush成一個StoreFile(底層實現是HFile), 當StoreFile增長到一定閾值文件數量(由hbase.hstore.blockingStoreFiles設置,默認7個 ),會觸發Compact合併操作,將多個StoreFiles合併成一個StoreFile,合併過程中會進行版本合併和數據刪除,因此可以看出HBase其實只有增加數據,所有的更新和刪除操作都是在後續的compact過程中進行的,這使得用戶的寫操作只要進入內存中就可以立即返回 ,保證了HBase I/O的高性能。當StoreFiles Compact後,會逐步形成越來越大的StoreFile,當單個StoreFile大小超過一定閾值(hbase.hregion.max.filesize,默認 256M )後,會觸發Split操作,同時把當前 Region Split成2個Region,父Region會下線,新Split出的2個孩子Region會被HMaster分配到相應的HRegionServer 上,使得原先1個Region的壓力得以分流到2個Region上。

 

 

五、數據存儲格式

HBase中的所有數據文件都存儲在Hadoop HDFS文件系統上,主要包括上述提出的兩種文件類型:

1. HFile, HBase中KeyValue數據 的存儲格式,HFile是Hadoop的二進制格式文件 ,實際上StoreFile就是對HFile做了輕量級包裝 ,即StoreFile底層就是HFile

2. HLog File,HBase中WAL(Write Ahead Log) 的存儲格式,物理上是Hadoop的Sequence File

 

 

<!-- @page { margin: 2cm } TD P { margin-bottom: 0cm } P { margin-bottom: 0.21cm } -->

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章