第四章:大數據 の HBase 基礎

本課主題

  • NoSQL 數據庫介紹
  • HBase 基本操做
  • HBase 集羣架構與設計介紹
  • HBase 與HDFS的關係
  • HBase 數據拆分和緊縮

 

引言 

介紹什麼是 NoSQL,NoSQL 和 RDBMS 之間有什麼區別,有什麼埸景下須要用 NoSQL 數據庫,NoSQL 數據的優勢和缺點;談談 NoSQL 一些基本的背景以後,這章會重點深刻談討 HBase 數據庫,HBase 的原理,交換 Shell 的基本更刪改查操做,HBase 集羣體系的結構,還會談談 HBase 與 HDFS 之間的關係,它在讀寫數據時的流程,有了這些理論基礎下,就能夠對 HBase 的性能調優有更透徹的瞭解,最後會談談 HBase 的備份和複製 (HBase 進階)。但願讀者看完這篇文章html

  • 瞭解 NoSQL 數據庫與關係型數據庫的區別;
  • 瞭解 HBase 在功能, 設計和集羣架構上的角色;
  • 瞭解 HBase 中增刪改查 API 並熟識其操做;
  • 瞭解 HBase 與 HDFS, ZooKeeper 之間的關係;
  • 瞭解 HBase 是如何對數據進行拆分和緊縮;

 

NoSQL 數據庫介紹

NoSQL 數據庫和關係型數據庫的設計目的是爲了解決不一樣的問題,NoSQL 數據模型相對簡單,它適合應用靈活更強的 IT 系統,不須要預先定義表如構,並且 NoSQL 對數據庫性能要求較高,對 PB 級別的數據進行快速的檢索,不須要高度的數據一致性及廷遲性的埸景,能夠快的跟據 Key-Value 的方式來查看數據。在市埸上有四種NoSQL數據庫,分別是:算法

  • 鍵值存儲數據庫:Key-Value 的鐽值對,一般用 Hash Table 來實現,這類數據庫的查找速度快、簡單,易部署,但數據無結構化,若是區部查找會很慢,和應用埸景是內容緩存,快速的檢索數據,主要用於大量數據的高訪問量負X,也適用於一些日誌系統, e.g. Redis, Oracle BDB, Tokyo Cabinet;
  • 列存儲數據庫:以列族 Column Family 式存儲,將同一列數據存在一塊兒,鐽的特色是指向了多少個列,這些列是由列族來實現的,它的好處是查找快速,擴展性很是好以便應用海量數據存儲和處理,但功能相對侷限,對設計要求很特定的要求,很是適合分佈式文件系統 e.g. HBase、Cassandra, Accumulo, Riak;
  • 文檔存儲數據庫:Key-Value 對應的鍵值時,Value 爲結構化數據,更瞭解 Value 的內容,數據結構不嚴格,表結構可變它不須要像關係型數據庫同樣要預先定義表結構,能夠看做他是鍵值數據庫的升級版,文檔類型處理得力比較好,但查詢能力不高,缺少統一的查詢語法。使用埸景是 Web 應用,,e.g. MongoDB, CouchDB, Couchbase Server ;
  • 圖形數據庫:圖結構,它能夠提用圖結構的算法,好比最佳路線尋址,N度關係查找,使用靈活的圖形模型而且能擴展到不一樣的服務器上,但不少時候要對整個圖做計算才能得出須要的信息,這種結構不太適合分佈式的集羣方案。應用埸景:推薦系統,社交網絡和關於結構關係圖譜, e.g. Neo4J, Infinite Graph;

NoSQL 與 RDBMS 的區別

[下圖總結 NoSQL 和 RDBMS 的區別]
sql

NoSQL 與 RDBMS 最大的分別是數據量和讀寫吞吐量的不一樣,數據佈局和數據訪問頻率也不一樣,他們兩個應用解決問題的本質也不同,好比列存儲數據庫能夠快速查找的緣由是列族的設計能夠在每一次查詢中大量減小磁盤 IO 和數據量的訪問。NoSQL 數據庫很容易支持數據量達 PB 級別的數據,由於它的特性很容易支持分佈式水平擴展;但 RDBMS 只能處理 TB+ 級別的數據,若是你的數據場景是要處理不少事務性數據 e.g. 更新和刪除,那麼仍是優先選擇關係型數據庫 RBDMS,由於NoSQL數據庫不太善於頻繁的處理數據更新和刪除,由於數據是分佈在不一樣的節點上,還有數據是默認有三份副本,若是須要太量的更新操做,那麼每臺節點上的數據也有一併更新,這太太增長了解決方案的複雜性;NoSQL 聽從 CAP 和 BASE 理論,RDBMS 聽從 ACID 的理論。若是隻有上千行和上百萬行的數據,則用傅統數據庫會比較適合shell

 

HBase 介紹

HBase 是以數據爲中心,RDBMS 是以關係爲數據,HBase 是 NoSQL 數據庫中的列存儲數據庫,它有如下特色:強一致性讀寫,自動分片,HBase 經過 Region 分佈在集羣中,數據增長時,Region 會自動分割並從新分片。RegionServer 自動故障移取,HBase 支持 HDFS 以外的存儲文件,HBase 經過 MapReduce 支持大併發處理,HBase 支持以 API 方式訪問數據,HBase 以 Bloom Filters 和 Bloom Cache 對大量數據進行查詢優化。HBase 適合場景是存在隨機讀寫的埸景,每秒須要在 TB 級別數據上完成數以千計的操做,訪問的操做的方式要簡單、明確和直接,若是應用只是插入數據並且處理時須要讀取所有數據。HBase 不支持二次索引、事務性數據、關聯表的操做。HBase 的使用埸景:消息 (Message) 好比點贊,電商中的 SMS/ MMS,有隨機讀寫的能力,局部數據進行 TopN 的查詢、簡單實體、圖數據、指標。數據庫

[下圖是一張 HBase 的表,歸納了列族、列名和行之間的關係]
apache

  1. HBase 在表中存儲數據,而表數據最後存儲在 HDFS 上,數據被分割成 HDFS 塊 (Block) 存儲在集羣的多個節點上,以128G爲一個 BlockSize;
  2. HBase 是由 Column Family (列族),Column (列) 和 Row Key (行) 組成的,列族是列的一個集合,列族能夠有任意數量的列,e.g. contactinfo:fname, contactinfo:lname 它也能夠單獨對每一個列族進行存儲屬性優化,好比對 profilephoto 進行壓縮存儲。
  3. HBase 每一行都有一個 RowKey 用於快速檢索,來保證一行數據的完整性,每一個 RowKey 就相似於 RDBMS 的主鍵,HBase 表是基於 RowKey 進行快速檢索,行按照排序後進行存儲,
  4. HBase 底層磁盤上是按照 Column Family 分開進行存儲。這樣的好處是相對於行存,佔用空間會很小;
  5. HBase 中間的數據是存儲在 Cell 中,並且 Cell 是有版本化的,能夠自定義保留多少過版本,Cell 爲空時不存儲。

這只是一個概念模型,HBase 的物理模型在存儲層面上是按照列族來存儲,所以,它的設計是不建議存儲太多的列在同一個列族中。緩存

如何設計一個 HBase 的表

要設計一個 HBase 表,要考慮的有如下幾個重點:RowKey 是惟一的索引鍵,應用程式依賴行來完成快速數據訪問;RDBMS 與 HBase 的特性比較;RDBMS 與 HBase 的表設計,RowKey 的設計,列族的設計,肯定數據的訪問類型;RDBMS 與 HBase 的 Scham 設計:關係爲中心,HBase 是以數據爲中心,先肯定數據的訪問方式。ruby

HBase 的 Region 是一張表,它相似於關係型數據庫中 partition 的概念, Region 是經過 RegionSever 的一個守護進程來對外(客戶端) 提供服務的, 表被折分爲小的分區, Region 包含起始行到結束行全部的行信息,一個 RegionServer 能夠有多個 Region。例如:User 表的其中一部份經過基於 RowKey 順序的動做被拆分紅三個不一樣的小 Region 而後隨機分發在不一樣的 RegionServer 節點上來對外提供受務。bash

[下圖是一張Hbase 的 User 表,描述了一張表是如何拆分紅不一樣的 Region 而後分發給 RegionServer]服務器

 

HBase 基本操做

HBase Shell 是發送命令給 HBase 的交換式 Shell,HBase 是用 JRuby 來方問,在 terminal 上輸入 hbase shell 進入交換式界面。語法規則是以下:

command 'para1' 'para2'
command 'param1',{PARA2 => 'stringvalue', PARA3 => 'intvalue'}

經常使用的語句包括增、刪、改、查分別以 put (先新增數據,發現 rowkey 相同則修改數據)、deleteget 或 scan如下是 put/ get/ scan/ delete 的模版語句。

HBase 存在兩個自定義兩個 namespace,分別是 hbasedefault namespace。默認 hbase 是包含HBase 內部的 system namespace,若是沒有顯式定義 namespace 便會自動歸類爲 default namespace。

create_namespace 'namespaceName'
drop_namespace 'namespaceName'
alter 'namespaceName' ,{METHOD => 'set', 'PROPERTY_NAME' => 'PROPERTY_VALUE'}
create_namespace 'entertainment' 
create 'entertainment:movie',  {NAME => 'desc'}
create_namespace
  1. 在 HBase Shell 中執行 help 來查看幫助文檔 e.g. hbase> help
    hbase(main):040:0> help
    HBase Shell, version 1.2.0-cdh5.9.0, rUnknown, Fri Oct 21 01:20:14 PDT 2016
    Type 'help "COMMAND"', (e.g. 'help "get"' -- the quotes are necessary) for help on a specific command.
    Commands are grouped. Type 'help "COMMAND_GROUP"', (e.g. 'help "general"') for help on a command group.
    
    COMMAND GROUPS:
      Group name: general
      Commands: status, table_help, version, whoami
    
      Group name: ddl
      Commands: alter, alter_async, alter_status, create, describe, disable, disable_all, drop, drop_all, enable, enable_all, exists, get_table, is_disabled, is_enabled, list, locate_region, show_filters
    
      Group name: namespace
      Commands: alter_namespace, create_namespace, describe_namespace, drop_namespace, list_namespace, list_namespace_tables
    
      Group name: dml
      Commands: append, count, delete, deleteall, get, get_counter, get_splits, incr, put, scan, truncate, truncate_preserve
    
      Group name: tools
      Commands: assign, balance_switch, balancer, balancer_enabled, catalogjanitor_enabled, catalogjanitor_run, catalogjanitor_switch, close_region, compact, compact_mob, compact_rs, flush, major_compact, major_compact_mob, merge_region, move, normalize, normalizer_enabled, normalizer_switch, split, trace, unassign, wal_roll, zk_dump
    
      Group name: replication
      Commands: add_peer, append_peer_tableCFs, disable_peer, disable_table_replication, enable_peer, enable_table_replication, list_peers, list_replicated_tables, remove_peer, remove_peer_tableCFs, set_peer_tableCFs, show_peer_tableCFs
    
      Group name: snapshots
      Commands: clone_snapshot, delete_all_snapshot, delete_snapshot, list_snapshots, restore_snapshot, snapshot
    
      Group name: configuration
      Commands: update_all_config, update_config
    
      Group name: quotas
      Commands: list_quotas, set_quota
    
      Group name: security
      Commands: grant, list_security_capabilities, revoke, user_permission
    
      Group name: procedures
      Commands: abort_procedure, list_procedures
    
      Group name: visibility labels
      Commands: add_labels, clear_auths, get_auths, list_labels, set_auths, set_visibility
    
    SHELL USAGE:
    Quote all names in HBase Shell such as table and column names.  Commas delimit
    command parameters.  Type <RETURN> after entering a command to run it.
    Dictionaries of configuration used in the creation and alteration of tables are
    Ruby Hashes. They look like this:
    
      {'key1' => 'value1', 'key2' => 'value2', ...}
    
    and are opened and closed with curley-braces.  Key/values are delimited by the
    '=>' character combination.  Usually keys are predefined constants such as
    NAME, VERSIONS, COMPRESSION, etc.  Constants do not need to be quoted.  Type
    'Object.constants' to see a (messy) list of all constants in the environment.
    
    If you are using binary keys or values and need to enter them in the shell, use
    double-quote'd hexadecimal representation. For example:
    
      hbase> get 't1', "key\x03\x3f\xcd"
      hbase> get 't1', "key\003\023\011"
      hbase> put 't1', "test\xef\xff", 'f1:', "\x01\x33\x40"
    
    The HBase shell is the (J)Ruby IRB with the above HBase-specific commands added.
    For more on the HBase Shell, see http://hbase.apache.org/book.html
    hbase(main):041:0> 
    help
  2. 在 HBase Shell 中查看狀態和當前版本是用 status, version, e.g. hbase> status; hbase> version
    hbase(main):036:0> status
    1 active master, 0 backup masters, 3 servers, 0 dead, 1.3333 average load
    
    hbase(main):037:0> version
    1.2.0-cdh5.9.0, rUnknown, Fri Oct 21 01:20:14 PDT 2016
    status 和 version
  3. 在 HBase Shell 查看錶是用 list,e.g. hbase> list 
  4. 在 HBase Shell 建立表是用 create,假設有一張 movie 表,它以 row1 做爲 rowKey, ColumnFamily 和 Column 分別是 desc 和 title,如今新增一條數值爲 HomeAlone 的數據 e.g. hbase> create 'tablename', {NAME => 'ColumnFamilyName', VERSIONS => 5}
    create 'movie', {NAME => 'desc'}
    create 'movie', {NAME => 'desc', VERSIONS => 2}
    create 'movie', {NAME => 'desc'}, {NAME => 'media'}
    create 'movie','desc','media'
    create 'movie'
  5. 在 HBase Shell 新增和更新數據是用 put,先新增數據,默認會插入當前服務器時間做爲時間戳,發現 rowkey 相同便修改數據,把 movie 的數據更改成 HomeAlone 2,並插入時間戳 e.g. hbase> put 'tablename', 'rowkey', 'colfam:col', 'value' [,timestamp]
    put 'movie', 'row1', 'desc:title', 'Goblin'
    put 'movie', 'row2', 'desc:title', 'Descendants Of The Sun'
    put 'movie', 'row3', 'desc:title', 'Doctors'
    put 'movie', 'row4', 'desc:title', 'W Special'
    put 'movie'
  6. 在 HBase Shell 刪除數據是用 drop 但前提是要先 disbale 表,disbale 表禁用表的置可維護的狀態來防止客戶端的訪問,容許執行各類維護命令,e.g. hbase> disable 'tablename' ; drop 'tablename' 
    hbase(main):017:0> disable 'movie'
    0 row(s) in 2.2980 seconds
    
    hbase(main):018:0> drop 'movie'
    0 row(s) in 1.2590 seconds
    disable and drop 'movie'
  7. 在 HBase Shell 查看錶結構定義信息,包含全部表的列族名、屬性名和屬性值是用 describe, e.g. hbase> describe 'tablename'

    hbase(main):007:0> describe 'movie'
    Table movie is ENABLED                                                                                                                                                                                          
    movie                                                                                                                                                                                                           
    COLUMN FAMILIES DESCRIPTION                                                                                                                                                                                     
    {NAME => 'desc', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => 'FOREVER', KEEP_DELETED_CELLS => 'FALSE', BL
    OCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}                                                                                                                                                 
    1 row(s) in 0.0950 seconds
    describe 'movie'
  8. 在 HBase Shell 修改表結構是用 alter, 調整表的 meta,好比能夠增刪改列族信息,也能夠在線 Schama 調整功能,須要把如下參數調整爲 true
    hbase.online.schema.update.enable property = true
    e.g. hbase> alter 'table', ATTRIBUTE => 'new attribute value'
    alter 'movie', NAME => 'media', METHOD => 'delete'
    alter 'movie', NAME => 'desc', VERSIONS => 5
    alter_async 'movie', NAME => 'desc', VERSIONS => 5
    alter_status
    alter 'movie'
  9. 在 HBase Shell 查詢單條數據是用 get 能夠進行單行數據根據行鍵檢索,檢索一行數據時,最近的版本時間戳最大的版本會被返回,e.g. hbase> get 'movie', 'row1'
    hbase(main):022:0> get 'movie', 'row1'
    COLUMN                                   CELL                                                                                                                 
     desc:title                              timestamp=1502806209403, value=Goblin                                                                                
    1 row(s) in 0.0110 seconds
    
    get 'movie', 'row2'
    get 'movie', 'row2', {COLUMN => 'desc:title'}
    get 'movie', 'row2', {COLUMN => 'desc:title', VERSIONS => 2}
    get 'movie', 'row2', {COLUMN => ['desc']}
    get 'movie', 'row1'
  10. 在 HBase Shell 查詢整塊數據是用 scan,e.g. hbase> scan 'movie'
    scan 'movie' 
    scan 'movie', {LIMIT => 3}
    scan 'movie', {STARTROW => 'row1', STOPROW => 'row3'}
    scan 'movie', {COLUMN => ['desc:title','media:type']}
    scan 'movie'
  11. 在 HBase Shell 檢查表是否被停用或啓動是用 is_disabled 或者 is_enabled, e.g. hbase> is_disabled 'table'; is_enabled 'table'
    hbase(main):025:0> is_disabled 'movie'
    false                                                                                                                                                         
    0 row(s) in 0.0170 seconds
    
    hbase(main):026:0> is_enabled 'movie'
    true                                                                                                                                                          
    0 row(s) in 0.0130 seconds
    is_disabled 'movie' or is_enabled 'movie'
  12. 在 HBase Shell 刪除Cell中的數據是用 delete, e.g. hbase> delete 'tablename', 'rowkey', 'colfam:col', [,timestamp]
    delete 'movie', 'row2', 'desc:title', 1502806209427
    delete 'movie'
  13. 在 HBase Shell 刪除表的全部行的數據是用 truncate, 表的列族不愛影響 e.g. hbase> truncate 'movie'
  14. 在 HBase Shell 刪除行的全部數據是用 deleteall, e.g. hbase> deleteall 'movie', 'row1'
    hbase(main):032:0> deleteall 'movie', 'row1'
    0 row(s) in 0.0300 seconds
    deleteall 'movie', 'row1'
  15. 在 HBase Shell 計算表的總行數是用 count, e.g. hbase> count 'movie'
    hbase(main):031:0> count 'movie'
    4 row(s) in 0.0380 seconds
    
    => 4
    count 'movie'

 

HBase 集羣體系結構 

RegionServer 是安裝在 Hadoop 的 DataNode 節點上,每一個 WorkerNode 都有一個 RegionServer 的進程,分配的變化都是由 HBase Master 來管理啦,HBase Master 是監控集羣中全部 RegionServer 實例,它是全部元數據修改的接口界面。HBase Master 是協調衆多的 Region Sever 的守護進程,肯定每個 Region Sever 管理那些 Region 的數據,新增、刪除、更新數據都由產生分配變化,所以須要 HBase Master 來統一管理。HBase 集羣能夠配置多個 Master 來提供高可用,集羣受控於一個Master,ZooKeeper 服務處理 Master 之間的協調動做。 ZooKeeper 運行在集羣的 Master 節點上,啓動後全部節點會鏈接到 ZooKeeper, 以競爭的形式運行,第一個鏈接到 ZooKeeper 的會得到控制權,若是主節點的 Master 乏敗後,剩下的 Master 會競爭控制權

HBase 有兩大類的表,一類是 UserSpace,這是經過 HBase Shell 和 HBase API 建立的表,記錄了真正用戶建立的表,e.g. Moive, UserInfo;另一種是 Catalog 表,它只有 HBase 系統訪問的表,它的用途是記錄元數據的特定表,跟蹤並記錄 Region 和 Region Sever 的位置hbase:meta 是一張 HBase 的表,但不能夠經過 HBaseShell 的 list 命令查找,HBase Master 經過 ZooKeeper 可以快從 hbase:meta 定位並查找元數據表的位置。

假設如今用戶以 HBase Shell 建立了一張 UserInfo 的表, HBase 會經過如下幾個步驟來查找 HBase 的數據:

[下圖是HBase 如何通過 hbase:meta 表來查找數據]

  • 第一步:客戶端會首先鏈接 ZooKeeper 來查詢 hbase:meta 表元數據的位置;
  • 第二步:查詢 hbase:meta 表的元數據內容,來指定全部 Region 和它們的位置 (一張 UserInfo 表的數據會被拆分紅不一樣的 Region,但 hbase:meta 不會被拆分到不一樣的節點上,但願hbase:meta 是能夠集中式管理以便快速找到 meta 表的信息和檢索。)
  • 第三步:而後查詢包含 UserInfo 表數據的 Region 所在的 Region Sever,這樣就能夠獲取到數據內容並返回給客戶端,前兩步的查詢會在客戶端進行緩存,以便快速查找數據。

HBase 與 HDFS 的關係

HBase 的 RegionServer 將數據寫入 HDFS 的本地磁盤上,這樣就可使用 HDFS 存儲全部表的數據,並且 Region 是以文件的形式存儲在 HDFS 之上,它繼承了 HDFS 的特性其中包括 NameNode 避免了單點故障提供了高可用性,DataNode 上存儲了三個數據副本保障了數據的持久性和確保若是節點出現故障也能夠保護數據的可用性,能夠經過添加 DataNode 來提升數據存儲的線性擴展能力,在 HDFS 的任意位置均可以寫讀Region 的數據,允計 RegionServer 運行在集羣的任何位置上。

[下圖是 DataNode 與 RegionServer 在 WorkerNode 實現數據本地性的概念圖 ]

HBase 存儲在 HDFS 是以 HFile 的特定文件格式,它構成表的實際存儲文件,Region 的列是根據表中不一樣的列族被分開存儲,每一個表在 RegionServer 上是以 StoreFile 的形式存儲,它在 HDFS 是不一樣的獨立文件

 

HBase 數據拆分和緊縮

數據拆分

HBase 是如何進行數據拆分的? 當表在拆分的過程當中,會建立額外的兩個列 info:splitA 和 info:splitB,它表明兩個 daughter region,這兩個列的值會序列化 HRegionInfo 實列,Region 分割完畢後,這兩行會自動刪除。而後建立兩個 daughter reference 文件,daughter 文件只包含 region 拆分的位置的鍵,在主緊縮中原始數據文件會被從新寫成新 Region 目錄下的單獨文件,小的 reference 文件和原始 Region 則會被刪除掉。

[下圖是一個 Region (Start Key A 到 Start Key G) 拆分紅兩個Region:  Region1 (Start Key A 到 Start Key C) 和 Region2 (Start Key C 到 Start Key G) 的過程]

何時會獨發拆分?當有大量的新增數據到一個 Region 時,RegionServer 感知到數據量超過了預值,便會獨發 Region 拆分,在拆分過程當中要注意有如下幾點:

  1. 此時的 Region 是不能對外提供服務的,快完成整個拆分的動做
  2. 複製和拷貝動動是不可進行的
  3. RegionServer 會更新 hbase:meta 元數據信息
  4. Region 拆分完畢

Region 大小能夠基於每一張表設置,某些表的須要與默設置的 Region 大小不一樣時,經過 HTableDescriptior 和 setFileSize 事件設置,Region 的大小是容量可用性和分佈性的基本單位,因此不建議過小的數據分佈到過多的 Region 中,高 RegionCount 會影響性能,例如超過 3000 Count,但低 RegionCount 也會下降並行擴展能力,建議:每個 RegionServer 包含 20~小几百個 Region。RegionServer 會自動移動 Region 來實現集羣的負載均衡,負載均衡操做的時間是由 hbase.balancer.period 來設置的,默認是 300000 ms (5分鐘)。

小緊縮與主緊縮

HBase 是如何進行緊縮的?緊縮的目的是把幾個小的 StoreFile 合併爲一個大的文件,來減小由於須要管理過多的小文件而導的資源開銷,一般是3個小的 StoreFile 就會觸發一次 Minor Compression,能夠適當地控制 StoreFile 的數量。能夠經過 hbase.hstore.compactionThreshold,數值較大會致使緊鎖更少,可是每次緊鎖耗的時間更長,在緊鎖期間,Memstore 沒法刷新磁盤,此時若是 memstore 的內存耗盡,客戶端就會致使阻塞或者是超時。

[下圖是多個 StoreFile 小文件通過小緊縮後合併成了三個小的 StoreFile]

主緊縮 (major compaction), 讀取一個 Region 中全部 StoreFile 而且將其寫到一個 StoreFile,以前標示刪除的數據和舊版本的數據都會在物理層面上被清除掉,主緊縮默應是一週 (七天) 進行一次,能夠經過參數 hbase.hregion.majorcompaction 配置主緊縮的時間間隔 (單位是毫秒),當該參數設置爲 0 時表示禁用主緊縮,由於主緊縮是很是耗資源的,因此建議是以交錯的方法爲每一個 RegionServer 進行主緊縮,這樣能夠防止所有 RegionServer 在同一個時間內進行主緊縮。

[下圖是三個 StoreFile 通過主緊縮後合併成了一個大的 StoreFile]

在生產環境下主緊縮的最佳實踐:

  1. 由於主緊縮是一個很是耗資源的操做,因此建議在負載比較低的時候運行;
  2. 經過參數 hbase.hregion.majorcompaction 調大主緊縮的間隔時間 (單位是毫秒),同時使用腳原本執行主緊縮操做,若是腳本失敗,需將這個參數的值設置爲 0,固然這種設置同時會出現主緊縮永不發生的風險;
  3. 經過參數 hbase.hregion.majorcompaction.jitter 來確保不讓全部 RegionServer 上的主緊縮操做同時進行,默應是 0.5 (50%),每個 RegionServer 的 hbase.hregion.majorcompaction 參數的值乘以一個隨機的分數 (這個隨機分數取值區間不超過 jitter) 和hbase.hregion.majorcompaction 參數的值加或減這個值來肯定下一次主緊縮的運行時間。

例子:經過 hbase.hregion.majorcompaction x hbase.hregion.majorcompaction.jitter 兩個參數的結合來防止各個 RegionServer 上的主緊縮操做在同一個時間點上發生,假設主緊縮每7天進行一次,而後乘以 jitter 這個隨機分數 e.g. 0.5。7 天 x (0~0.5) = 0 ~ 3.5 天。而後把 7天加或者減這個值 e.g.  (7天-3.5) ~ (7天+3.5) = 3.5天 ~ 10.5 天,便會計算出下一次主緊縮發生的時間。在這個例子中,每一個 3.5 天到 10.5 天便會觸發一次主緊縮行爲

RegionServer 最終目的是要實現數據本地化,纔可以快速查找數據,HDFS 客戶端默認拷貝三份數據副本,其中第一份副本寫到本地節點上,第二和第三份則寫在不一樣機器的節點上 (RegionServer);Region 的拆分會致使 RegionServer 須要讀取非本地的 StoreFile,此時,HDFS 將會自動經過網絡拉取數據,但經過網絡讀寫數據相對地比本地讀寫數據的效率要低,要提高效率,必須儘量採用數據本地性,這也是爲何 HBase 要不定時地進行主緊縮和刷新把數據聚合在本地磁盤上來實現數據本地化,提高查詢效率。

  

總結

NoSQL 數據庫與關係型數據庫有著本質的設計與功能差異,二者之間的使用的埸景和需求都不同。關係型數據庫善於處理結構化數據和頻繁地對數據進行更新和刪除的操做,設計模型是以關係爲中心的,有一系列的功能包含提供索引,很容易實現二次排序,數據分片、能夠實現大量的關聯操做,針對事務性數據有良好的支持,不過比較難實現分佈式擴展和只能支持 TB+ 以上的數據量。NoSQL 數據庫是以數據爲中心,沒有過多對錶結構的規範,好比不須要在建立表以前先定義整個表結構,只須要定義列族和行信息便可,NoSQL 數據庫很容易實現分佈式擴展且能支持 PB+ 以上的數據量,由於分佈式和靈活的表設計,NoSQL 的應用埸景是適合快速隨機讀寫數據,但它是不支持事務性數據,e.g. CUID (增刪改查),因此NoSQL 數據庫與關係型數據庫是不能徹底替代的,只是爲不一樣的需求提出不一樣的解決方案。

HBase 的架構也是 Master-Slave 結構,HBase Master 負責協調各個節點的工做,在每一個工做節點上都佈署了一個 RegionServer,負責對外提供服務。HBase 的表是以 Region 概念來拆分,一張表能夠拆分爲不一樣的 Region 而後分發到不一樣的 RegionServer 上,每一個表在建立時只須要定義列族,HBase 是以列族形式分開存儲在 HDFS 上。

HBase 有拆分和緊縮機制,當數據量達到一個預值上限時,便會觸發拆分操做,每一個 Region 上有不少小的 StoreFile,當 StoreFile 達到必定數量,也會觸發一次小緊縮,緊縮的目的是把幾個小的 StoreFile 合併爲一個大的文件,來減小由於須要管理過多的小文件而導的資源開銷,每一段時間事後,也須要進行主緊縮,主緊縮會讀取一個 Region 中全部 StoreFile 而且將其寫到一個 StoreFile,由於 RegionServer 最終目的是要實現數據本地化來提升數據的檢索速度,因此要透過緊縮的操做來達到這個效果。

 

參考資料

[1] NoSQL 的 CAP 理論

[2] CAP理論十二年回顧:"規則"變了

[3] NoSQL 數據庫應用埸景:京東618:一箇中心五個原則,談談物流系統的大促優化實踐

[4] NoSQL開篇——爲何要使用NoSQL

[5] NoSQL架構實踐(一)——以NoSQL爲輔

[6] NoSQL架構實踐(二)——以NoSQL爲主

[7] 第五章:大數據 の HBase 進階

相關文章
相關標籤/搜索