大數據篇:Hbase


大數據篇:Hbase

  • Hbase是什么

Hbase是一個分布式、可擴展、支持海量數據存儲的NoSQL數據庫,物理結構存儲結構(K-V)。

  • 如果沒有Hbase

如何在大數據場景中,做到上億數據秒級返回。(有條件:單條數據,范圍數據)

hbase.apache.org

1 Hbase結構及數據類型

  • 邏輯結構

  • 物理結構

整張表會按照水平方向按照Row Key切割(Region)。再按垂直方向按ColumnFamily切割(Store),

  • Name Space:命名空間

    • 類似於關系型數據庫中的database概念,每個命名空間下可以放多個表,默認存在2個命名空間:hbase和default,hbase存放Hbase內置的表,default表是用戶默認使用的命名空間。(例如給order表賦予命名空間test,可以寫為test:order)
  • Row:行

    • Hbase中每行數據都由一個RowKey和多個列組成。
  • Column:列

    • Hbase中的每個列都由ColumnFamily(列族)和ColumnQualifier(列限定符)進行限定,(例如:personal_info:name,personal_info:city)
  • Cell:單元

    • 由{RowKey,ColumnFamily,ColumnQualifier,TimeStamp}唯一確定的單元,Cell中的數據是沒有類型的,全部為字節碼形式儲存。
  • Row Key:行鍵

    • Row Key在表中必須是唯一的而且必須存在的。
    • Row Key是 按照字典序一位一位比較有序排列的(有值比沒有值大)。例如row_key11 排列在row_key1和row_ley2之間。
    • 所有對表的訪問都要通過Row Key 。(單個RowKey訪問,或RowKey范圍訪問,或全表掃描)
  • ColumnFamily:列族

    • 創建Hbase表時,只需要給定CF即可,在插入數據時,列(字段)可以動態、按需增加。
    • 每個CF可以有一個或多個列成員(ColumnQualifier)。
    • 不同列族放在hdfs不同文件夾中存儲。
  • TimeStamp:時間戳

    • 用於標識數據的不同版本,如果不指定時間戳,Hbase在寫入數據時會自動加上當前系統時間戳為該字段值。

2 Hbase架構

下面從小到大解釋上圖中的各組件中的功能。

  • StoreFile

    • StoreFile為HBase真正存儲的文件,最終通過HDFS客戶端存入DataNode。(也就是linux磁盤中)
  • Store

    • 可以理解為一個切片Region中的一組列族。(如上圖一個Region中有多個Store)
    • Store中包含Mem Store(內存存儲),StoreFile(由內存刷入的數據,數量多了會合並,數據大了會切分)
  • Region

    • Region可以理解為一張表的切片,Region按照數據量大小閥值和Row key進行切分。
    • HBase自動把表水平(按行)划分成多個區域(region),每個region會保存一個表里面某段連續的數據。
    • 每個表一開始只有一個region,隨着數據不斷插入,region不斷增大,當增大到一個閥值的時候,region就會根據Row key等分為兩個新的region,以此類推。
    • Table中的行不斷增多,就會有越來越多的region,一張表數據就被保存在多個Region 上。
  • HLog

    • Hbase的預寫日志,防止特殊情況下的數據丟失。
  • RegionServer

    • 數據的操作(DML):get,put,delete
    • 管理Region:SplitRegion(切分),CompactRegion(合並)
  • Master

    • 表級別操作(DDL):create,delete,alter
    • 管理RegionServer:監控RegionServer狀態,分配Regions到RegionServer,(如有機器rs1,rs2,rs3,數據寫入rs1,rs2上的Region,r3空閑--->這時rs1被大量寫入數據達到Region上限,rs1將Region等分后,就會通知Master將其中一份發往rs3管理。)

3 命令行操作

3.1 鏈接hbase

  • 鏈接hbase
hbase shell
  • 查看幫助命令或命令詳細使用
help
help '命令'

3.2 命名空間操作

3.2.1 查詢命名空間

list_namespace

3.2.2 查詢命名空間下的表

list_namespace_tables '命名空間名'

3.2.3 創建命名空間

create_namespace '命名空間名'

3.2.4 刪除命名空間(需要namespace是空的)

drop_namespace '命名空間名'

3.3 DDL操作

3.3.1 查詢所有用戶表

list

3.3.2 創建表

create '命名空間:表', '列族1', '列族2', '列族3','列族4'...

如圖發現有一串亂亂序文件夾,這串亂序就代表了Region號

3.3.3 查看表詳情

describe '命名空間:表'

可以看出VERSIONS為1,代表這個表只能存放一個版本的數據。

3.3.4 變更表信息

主要用於修改表的版本保存信息,也可以創建表的時候指定,但是shell命令復雜,故一般使用變更命令。

alter '命名空間:表',{NAME=>'列族名',VERSIONS=>3}

3.3.5 修改表狀態(刪除前必須失效表)

  • 失效表
disable '表'
  • 啟用表
enable '表'

3.3.6 刪除表

delete '表'

3.4 DML操作

3.4.1 插入數據

put '命名空間:表','RowKey','列族:列','值'
put '命名空間:表','RowKey','列族:列','值',時間戳(版本控制)

如圖發現並沒有數據文件生成,因為數據在內存中,需要flush '表',而后就可以看見數據落地了。(flush一次就是生成一個StoreFile)

3.4.2 掃描表

#全表掃描
scan '命名空間:表'
#范圍掃描(左閉右開)
scan '命名空間:表',{STARTROW => 'RowKey',STOPROW=>'RowKey'}
#掃描N個版本的數據
scan '命名空間:表',{RAW=>true,VERSIONS=>10}

3.4.3 Flush刷寫

flush '命名空間:表'
  • 數據版本保留機制

從上面知道flush一次就是生成一個StoreFile,那么數據就會根據建表保留版本個數來存儲最近個數的數據。

比如:保留版本個數為2,那么如果插入v1,v2,v3三條數據,flush后,就只剩下v2,v3兩條數據,這時再插入v4,v5,v6三條數據,flush后,剩下的為v2,v3,v5,v6四個版本的數據(此時是2個StoreFile文件),如果發生Region合並或者分裂,那么StoreFile文件會被合並后在放入對應的Region中,這時數據就又會根據保留版本個數刪除,v2,v3,v5,v6,就變成了v5,v6。(如果沒有手動flush,或者到設置的自動flush時間,那么數據不會根據版本個數刪除)(默認超過3個StoreFile文件則會進行大合並)

  • 一個列族對應一個MemStore
  • 每個MemStore在刷寫到HDFS時,生成的StoreFile是獨立的
  • RegionServer全局MemStore刷寫時機:hbase.regionserver.global.memstore.size

  • 單個Memstore刷寫時機:hbase.hregion.memstore.flush.size

3.4.3 查詢數據

get '命名空間:表','RowKey'
get '命名空間:表','RowKey','列族'
get '命名空間:表','RowKey','列族:列'
#獲取N個版本的數據
get '命名空間:表','RowKey',{COLUMN=>'列族:列',VERSIONS=>10}

3.4.4 清空表

truncate '命名空間:表'

3.4.5 刪除數據

#delete '命名空間:表','RowKey','列族'(此命令行刪除有問題,但是API可以)
delete '命名空間:表','RowKey','列族:列'
deleteall  '命名空間:表','RowKey'

4 讀寫流程

4.1 寫流程

  1. 客戶端通過ZK查詢元數據存儲表的所在RegionServer所在位置並返回

  1. 查詢元數據,返回需要表的RegionServer

  1. 客戶端緩存信息,方便下次使用

  2. 發送PUT請求到RegionServer,寫操作日志(WAL),再寫入內存,然后同步wal到HDFS,則結束。(此步驟由事務回滾保證日志、內存都寫入成功)

4.2 讀流程

在讀取數據時候,MemStore和StoreFile一起讀取,將StoreFile中的數據放入BlockCache,然后在將內存數據和BlockCache比較時間戳做Merge,取最新的數據返回。

5 合並切分

  • 合並Compaction

由於Memstore每次刷寫都會生成一個新的HFile,且同一個字段的不同版本和不同類型有可能會分布在不同的HFile中,因此查詢時需要遍歷所有的HFile。為了減少HFile的個數,以及清理掉過期和刪除的數據,會進行StoreFile合並。

Compaction分為Minor Compaction和Major Compaction。

Minor Compaction會將臨近的若干個較小的HFile合並成一個較大的HFile,但不會清理過期和刪除的數據。

Major Compaction會將一個Store下的所有HFile合並成一個大的HFile,並且會清理掉過期和刪除的數據。

參數設置:

hbase.hregion.majorcompaction=0

hbase.hregion.majorcompaction.jitter=0

hbase.hstore.compactionThreshold=3

  • 切分

默認情況下,每個Table起初只有一個Region,隨着數據的不斷寫入,Region會自動進行拆分,剛拆分時,兩個子Region都位於當前Region Server,但處於負載均衡的考慮,HMaster有可能會將某個Region轉移給其他的Region Server。

參數設置:

hbase.hregion.max.filesize=5G (如下公式中為Max1)(可以減小該值,提高並發)

hbase.hregion.memstore.flush.size=258M (如下公式中為Max2)

每次切分將會比較Max1和Max2的值,取小的。[min(Max1,Max2 * Region個數 * 2)],其中Region個數為當前Region Server中數據該Table的Region個數。

由於自動切分無法避免熱點問題,所以在生產中我們常常使用預分區和設計RowKey避免出現熱點問題

6 優化

6.1 盡量不要使用多個列族

為了避免flush時產生多個小文件。

6.2 內存優化

主要作用來緩存Table數據,但是flush時會GC,不要太大,根據集群資源,一般分配整個Hbase集群內存的70%,16->48G就可以了

6.3 允許在HDFS中追加內容

dfs.support.append=true (hdfs-site.xml、hbase-site.xml)

6.4 優化DataNode允許最大文件打開數

dfs.datanode.max.transfer.threads=4096 (HDFS配置)

在Region Server級別的合並操作中,Region Server不可用,可以根據集群資源調整該值,增加並發。

6.5 調高RPC監聽數量

hbase.regionserver.handler.count=30

根據集群情況,可以適當增加該值,主要決定是客戶端的請求數。

6.6 優化客戶端緩存

hbase.client.write.buffer=100M (寫緩存)

調高該值,可以減少RPC調用次數,單數會消耗更多內存,根據集群資源情況設定。

6.7 合並切分優化

參考5合並切分

6.8 預分區

  • 創建表時候加入參數SPLITS
create '命名空間:表', '列族1', '列族2', '列族3','列族4'...,SPLITS=>['分區號','分區號','分區號','分區號']

根據數據量預估半年到一年的數據量,和Region最大值來選擇預分區數。

6.9 RowKey

  • 散列性:均勻分部到不同的Region里
  • 唯一性:不會重復
  • 長度:70-100位

方案一:隨機數,hash值,但是這種不能范圍查詢,沒有數據的集中性。

方案二:字符串反轉,比如時間戳反轉后就達到了散列性,但是在查看的時候集中性只是優於第一種。

  • 生產方案推薦:
#設計預分區鍵(如比如200個區) | ASCLL碼為124只有 } 和 ~ 比它大,那么不管以后的RowKey使用什么字符,都是小於這個字符的,所以可以有效的得到RowKey規律
000|
001|
......
199|


# 1 設計RowKey鍵_ASCLL碼為95
000_
001_
......
199_
# 2 根據業務唯一標識(如用戶ID,手機號,身份證)和時間維度(比如按月:202004)計算后根據分區數取余(13408657784^202004)%199=分區號
# 想以什么時間進行查詢就把什么往前提,如下數據需要查1月數據范圍就是 000_13408657784_2020-04  -> 000_13408657784_2020-04|
000_13408657784_2020-04-01 12:12:12
......
199_13408657784_2020-04-01 24:12:12


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM