第二天:Hbase進階

2. HBase安裝

HBase = Hadoop database

1. Zookeeper正常部署

首先保證Zookeeper集羣的正常部署,並啓動之:

[atguigu@hadoop102 zookeeper-3.4.10]$ bin/zkServer.sh start
[atguigu@hadoop103 zookeeper-3.4.10]$ bin/zkServer.sh start
[atguigu@hadoop104 zookeeper-3.4.10]$ bin/zkServer.sh start

2 Hadoop正常部署

Hadoop集羣的正常部署並啓動:

[atguigu@hadoop102 hadoop-2.7.2]$ sbin/start-dfs.sh
[atguigu@hadoop103 hadoop-2.7.2]$ sbin/start-yarn.sh

3. HBase的解壓

解壓HBase到指定目錄:

[atguigu@hadoop102 software]$ tar -zxvf hbase-1.3.1-bin.tar.gz -C /opt/module

4. HBase的配置文件

修改HBase對應的配置文件。

  1. hbase-env.sh修改內容:
export JAVA_HOME=/opt/module/jdk1.8.0_144
export HBASE_MANAGES_ZK=false # 不用HBase自帶的zk關聯機制
  1. hbase-site.xml修改內容:
<configuration>
	<property>     
		<name>hbase.rootdir</name>     
		<value>hdfs://hadoop102:9000/hbase</value>   
	</property>

	<property>   
		<name>hbase.cluster.distributed</name>
		<value>true</value>
	</property>

   <!-- 0.98後的新變動,之前版本沒有.port,默認端口爲60000 -->
	<property>
		<name>hbase.master.port</name>
		<value>16000</value>
	</property>

	<property>   
		<name>hbase.zookeeper.quorum</name>
	     <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
	</property>

	<property>   
		<name>hbase.zookeeper.property.dataDir</name>
	     <value>/opt/module/zookeeper-3.4.10/zkData</value>
	</property>
</configuration>
  1. 修改regionservers跟HDFS中slaves類似:
hadoop102
hadoop103
hadoop104
  1. 軟連接hadoop配置文件到hbase:
[atguigu@hadoop102 module]$ ln -s /opt/module/hadoop-2.7.2/etc/hadoop/core-site.xml 
/opt/module/hbase/conf/core-site.xml
[atguigu@hadoop102 module]$ ln -s /opt/module/hadoop-2.7.2/etc/hadoop/hdfs-site.xml 
/opt/module/hbase/conf/hdfs-site.xml

5. HBase遠程發送到其他集羣

[atguigu@hadoop102 module]$ xsync hbase/ 

6 HBase服務的啓動

1.啓動方式1

[atguigu@hadoop102 hbase]$ bin/hbase-daemon.sh start master
[atguigu@hadoop102 hbase]$ bin/hbase-daemon.sh start regionserver

提示:如果集羣之間的節點時間不同步,會導致regionserver無法啓動,拋出ClockOutOfSyncException異常。
修復提示:
a、同步時間服務
請參看幫助文檔:《Hadoop入門》
b、屬性:hbase.master.maxclockskew設置更大的值

<property>
        <name>hbase.master.maxclockskew</name>
        <value>180000</value>
        <description>Time difference of regionserver from master</description>
 </property>

2.啓動方式2推薦

[atguigu@hadoop102 hbase]$ bin/start-hbase.sh
對應的停止服務:
[atguigu@hadoop102 hbase]$ bin/stop-hbase.sh

7. 查看HBase頁面

啓動成功後,可以通過“host:port”的方式來訪問HBase管理頁面,例如:

http://hadoop102:16010 

3. HBase Shell 操作

Shell基本操作 指南

命名 描述 語法
help ‘命名名’ 查看命令的使用描述 help ‘命令名’
whoami 我是誰 whoami
version 返回hbase版本信息 version
status 返回hbase集羣的狀態信息 status
table_help 查看如何操作表 table_help
create 創建表 create ‘表名’, ‘列族名1’, ‘列族名2’, ‘列族名N’
alter 修改列族 添加一個列族:alter ‘表名’, ‘列族名’ ;刪除列族:alter ‘表名’, {NAME=> ‘列族名’, METHOD=> ‘delete’}
describe 顯示錶相關的詳細信息 describe ‘表名’
list 列出hbase中存在的所有表 list
exists 測試表是否存在 exists ‘表名’
put 添加或修改的表的值 put ‘表名’, ‘行鍵’, ‘列族名’, ‘列值’ ; put ‘表名’, ‘行鍵’, ‘列族名:列名’, ‘列值’
scan 通過對錶的掃描來獲取對用的值 scan ‘表名’ ; 掃描某個列族: scan ‘表名’, {COLUMN=>‘列族名’} 掃描某個列族的某個列: scan ‘表名’, {COLUMN=>‘列族名:列名’} ; 查詢同一個列族的多個列: scan ‘表名’, {COLUMNS => [ ‘列族名1:列名1’, ‘列族名1:列名2’, …]}
get 獲取行或單元(cell)的值 get ‘表名’, ‘行鍵’ get ‘表名’, ‘行鍵’, ‘列族名’
count 統計表中行的數量 count ‘表名’
incr 增加指定錶行或列的值 incr ‘表名’, ‘行鍵’, ‘列族:列名’, 步長值
get_counter 獲取計數器 get_counter ‘表名’, ‘行鍵’, ‘列族:列名’
delete 刪除指定對象的值(可以爲表,行,列對應的值,另外也可以指定時間戳的值) 刪除列族的某個列: delete ‘表名’, ‘行鍵’, ‘列族名:列名’
deleteall 刪除指定行的所有元素值 deleteall ‘表名’, ‘行鍵’
truncate 重新創建指定表 truncate ‘表名’
enable 使表有效 enable ‘表名’
is_enabled 是否啓用 is_enabled ‘表名’
disable 使表無效 disable ‘表名’
is_disabled 是否無效 is_disabled ‘表名’
drop 刪除表 drop的表必須是disable的 disable
shutdown 關閉hbase集羣(與exit不同)
tools 列出hbase所支持的工具
exit 退出hbase shell

基本操作

  1. 進入HBase客戶端命令行
[atguigu@hadoop102 hbase]$ bin/hbase shell
  1. 查看幫助命令
hbase(main):092:0> help 'delete'
Put a delete cell value at specified table/row/column and optionally
timestamp coordinates.  Deletes must match the deleted cell's
coordinates exactly.  When scanning, a delete cell suppresses older
versions. To delete a cell from  't1' at row 'r1' under column 'c1'
marked with the time 'ts1', do:

  hbase> delete 'ns1:t1', 'r1', 'c1', ts1
  hbase> delete 't1', 'r1', 'c1', ts1
  hbase> delete 't1', 'r1', 'c1', ts1, {VISIBILITY=>'PRIVATE|SECRET'}

The same command can also be run on a table reference. Suppose you had a reference
t to table 't1', the corresponding command would be:

  hbase> t.delete 'r1', 'c1',  ts1
  hbase> t.delete 'r1', 'c1',  ts1, {VISIBILITY=>'PRIVATE|SECRET'}
hbase(main):093:0> 

hbase(main):001:0> help
COMMAND GROUPS:
  Group name: general
  Commands: processlist, status, table_help, version, whoami

  Group name: ddl 數據庫的增刪改查操作
  Commands: alter, alter_async, alter_status, clone_table_schema, create, describe, disable, disable_all, drop, drop_all, enable, enable_all, exists, get_table, is_disabled, is_enabled, list, list_regions, locate_region, show_filters

  Group name: namespace  類似與mysql中的database操作
  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
.......
For more on the HBase Shell, see http://hbase.apache.org/book.html
  1. 查看當前數據庫中有哪些表
hbase(main):002:0> list
TABLE                                                                                                                                                                                                                                         
sowhat                                                                                                                                                                                                                                        
mygraph                                                                                                                                                                                                                                       
user 

表的操作

  1. 創建表
    注意:創建表時只需要指定列族名稱,不需要指定列名。
# 語法
create '表名', {NAME => '列族名1'}, {NAME => '列族名2'}, {NAME => '列族名3'}
# 此種方式是上上面的簡寫方式,使用上面方式可以爲列族指定更多的屬性,如VERSIONS、TTL、BLOCKCACHE、CONFIGURATION等屬性
create '表名', '列族名1', '列族名2', '列族名3'

create '表名', {NAME => '列族名1', VERSIONS => 版本號, TTL => 過期時間, BLOCKCACHE => true}
# 示例
create 'tbl_user', 'info', 'detail'
create 't1', {NAME => 'f1', VERSIONS => 1, TTL => 2592000, BLOCKCACHE => true}
create 'sowhat','info'
  1. 插入數據到表
    put 表名,序列號key,列族:列名,字段值
hbase(main):003:0> put 'sowhat','1001','info:sex','male'
hbase(main):004:0> put 'sowhat','1001','info:age','18'
hbase(main):005:0> put 'sowhat','1002','info:name','Janna'
hbase(main):006:0> put 'sowhat','1002','info:sex','female'
hbase(main):007:0> put 'sowhat','1002','info:age','20'
  1. 掃描查看錶數據
hbase(main):008:0> scan 'sowhat'
hbase(main):012:0> scan 'sowhat'
ROW                                      COLUMN+CELL                                                                                                           
 1001                                    column=info:age, timestamp=1592444447588, value=18                                                                    
 1001                                    column=info:sex, timestamp=1592444439067, value=male                                                                  
 1002                                    column=info:age, timestamp=1592444470614, value=20                                                                    
 1002                                    column=info:name, timestamp=1592444462987, value=Janna                                                                
 1002                                    column=info:sex, timestamp=1592444466848, value=female  
---
hbase(main):009:0> scan 'sowhat',{STARTROW => '1001', STOPROW  => '1001'}  指定範圍 左閉右開[start,end)這樣的格式,必須大寫!
ROW                                      COLUMN+CELL                                                                                                           
 1001                                    column=info:age, timestamp=1592444447588, value=18                                                                    
 1001                                    column=info:sex, timestamp=1592444439067, value=male  
---
hbase(main):010:0> scan 'sowhat',{STARTROW => '1001'}
ROW                                      COLUMN+CELL                                                                                                           
 1001                                    column=info:age, timestamp=1592444447588, value=18                                                                    
 1001                                    column=info:sex, timestamp=1592444439067, value=male                                                                  
 1002                                    column=info:age, timestamp=1592444470614, value=20                                                                    
 1002                                    column=info:name, timestamp=1592444462987, value=Janna                                                                
 1002                                    column=info:sex, timestamp=1592444466848, value=female     
---
  1. 查看錶結構
hbase(main):011:0> describe 'sowhat'   desc  'sowhat' 也可以
Table sowhat is ENABLED                                                                                                                                        
sowhat                                                                                                                                                         
COLUMN FAMILIES DESCRIPTION                                                                                                                                    
{NAME => 'info', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'fal
se', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN_
MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}    
  1. 更新指定字段的數據
hbase(main):012:0> put 'sowhat','1001','info:name','Nick'
hbase(main):013:0> put 'sowhat','1001','info:age','100'
hbase(main):013:0> scan 'sowhat'
ROW                                                          COLUMN+CELL                                                                                                                                                                      
 1001                                                        column=info:age, timestamp=1592445694183, value=100                                                                                                                              
 1001                                                        column=info:name, timestamp=1592445681869, value=Nick                                                                                                                            
 1001                                                        column=info:sex, timestamp=1592444439067, value=male                                                                                                                             
 1002                                                        column=info:age, timestamp=1592444470614, value=20                                                                                                                               
 1002                                                        column=info:name, timestamp=1592444462987, value=Janna                                                                                                                           
 1002                                                        column=info:sex, timestamp=1592444466848, value=female                                                                                                                           
2 row(s)
  1. 查看“指定行”或“指定列族:列”的數據
hbase(main):025:0> get 'sowhat','1001'
COLUMN                                                       CELL                                                                                                                                                                             
 info:age                                                    timestamp=1592445694183, value=100                                                                                                                                               
 info:name                                                   timestamp=1592445681869, value=Nick                                                                                                                                              
 info:sex                                                    timestamp=1592444439067, value=male                                                                                                                                              
1 row(s)
Took 0.0215 seconds                                                                                                                                                                                                                           
hbase(main):026:0> get 'sowhat','1001','info:name'
COLUMN                                                       CELL                                                                                                                                                                             
 info:name                                                   timestamp=1592445681869, value=Nick                                                                                                                                              
1 row(s)
Took 0.0146 seconds 
  1. 統計表數據行數
hbase(main):027:0> count 'sowhat'
2 row(s)
Took 0.0558 seconds                                                                                                                                                                                                                           
=> 2
  1. 刪除數據
    刪除某rowkey的全部數據:
hbase(main):016:0> deleteall 'sowhat','1001'

刪除某rowkey的某一列數據:

hbase(main):017:0> delete 'sowhat','1002','info:sex'
  1. 清空表數據
hbase(main):032:0> truncate 'sowhat'
Truncating 'sowhat' table (it may take a while):
Disabling table...
Truncating table...
Took 2.0702 seconds                                                                                                                                                                                                                           
hbase(main):033:0> scan 'sowhat'
ROW                                                          COLUMN+CELL                                                                                                                                                                      
0 row(s)

提示:清空表的操作順序爲先disable,然後再truncate,在HBase 2.2版本上操作時候沒顯示必須disable。
10. 刪除表
首先需要先讓該表爲disable狀態:

hbase(main):019:0> disable 'sowhat'

然後才能drop這個表:

hbase(main):020:0> drop 'sowhat'

提示:如果直接drop表,會報錯:ERROR: Table sowhat is enabled. Disable it first.
11. 變更表信息
默認情況下,列族只存儲一個版本的數據,如果需要存儲多個版本的數據,則需要修改列族的屬性。修改後可通過desc命令查看。

put 'sowhat','1001','info:name','Nick'
put 'sowhat','1001','info:name','Nick1'
put 'sowhat','1001','info:name','Nick2'
put 'sowhat','1001','info:name','Nick3'
put 'sowhat','1001','info:name','Nick4'
hbase(main):022:0> alter 'sowhat',{NAME=>'info',VERSIONS=>3}
hbase(main):022:0> get 'sowhat','1001',{COLUMN=>'info:name',VERSIONS=>3}

COLUMN                                                       CELL                                                                                                                                                                             
 info:name                                                   timestamp=1592446266614, value=Nick4                                                                                                                                             
 info:name                                                   timestamp=1592446264202, value=Nick3                                                                                                                                             
 info:name                                                   timestamp=1592446262438, value=Nick2                                                                                                                                             
1 row(s)
put 'sowhat','1001','info:name', 'Nick0', 1592446266615  put數據的時候指定時間
  1. alter 增刪列族
# 語法 
alter '表名', '列族名'

# 示例
alter 'tbl_user', 'address'

# 語法 
alter '表名', {NAME=> '列族名', METHOD=> 'delete'}

# 示例
alter 'tbl_user', {NAME=> 'address', METHOD=> 'delete'}

# 修改f1列族的版本爲5
alter 't1', NAME => 'f1', VERSIONS => 5

# 修改多個列族,修改f2爲內存,版本號爲5
alter 't1', 'f1', {NAME => 'f2', IN_MEMORY => true}, {NAME => 'f3', VERSIONS => 5}

# 也可以修改table-scope屬性,例如MAX_FILESIZE, READONLY,MEMSTORE_FLUSHSIZE, DEFERRED_LOG_FLUSH等。
# 例如,修改region的最大大小爲128MB:
alter 't1', MAX_FILESIZE => '134217728'
  1. 查看所有數據類型
scan 'sowhat',{RAW=>TRUE,VERSIONS=>10}

在這裏插入圖片描述

4. HBase數據結構

1. RowKey

跟nosql數據庫一樣RowKey就是用來檢索記錄的主鍵,訪問HBase 表中的行只有如下三種方式。

  1. 通過單個RowKey訪問
get 'sowhat','1001'
  1. 通過RowKey的range訪問
scan 'sowhat',{STARTROW => '1001', STOPROW  => '1003'} 
  1. 全表掃描
    RowKey行鍵 (RowKey)可以是任意字符串(最大長度是64KB,實際應用中長度一般爲 10-100bytes),在HBASE內部,RowKey保存爲字節數組。存儲時,數據按照RowKey的字典序(byte order)排序存儲。設計RowKey時,要充分排序存儲這個特性,將經常一起讀取的行存儲放到一起。(位置相關性)
scan 'sowhat'

2. Column Family

列族:HBASE表中的每個列,都歸屬於某個列族。列族是表的schema的一部分(而列不是),必須在使用表之前定義。列名都以列族作爲前綴。例如 courses:historycourses:math都屬於courses 這個列族。

3. Cell

由{rowkey, column Family:columu, version} 唯一確定的單元。cell中的數據是沒有類型的,全部是字節碼形式存貯。
關鍵字:無類型字節碼

4. Time Stamp

HBase 中通過rowkeycolumns確定的爲一個存貯單元稱爲cell。每個 cell都保存 着同一份數據的多個版本。版本通過時間戳來索引。時間戳的類型是 64位整型。時間戳可以由HBase(在數據寫入時自動 )賦值,此時時間戳是精確到毫秒 的當前系統時間。時間戳也可以由客戶顯式賦值。如果應用程序要避免數據版 本衝突,就必須自己生成具有唯一性的時間戳。每個 cell中,不同版本的數據按照時間倒序排序,即最新的數據排在最前面
爲了避免數據存在過多版本造成的的管理 (包括存貯和索引)負擔,HBase提供 了兩種數據版本回收方式。一是保存數據的最後n個版本,二是保存最近一段 時間內的版本(比如最近七天)。用戶可以針對每個列族進行設置。

5. 命名空間

命名空間的結構:
在這裏插入圖片描述

  1. Table:表,所有的表都是命名空間的成員,即表必屬於某個命名空間,如果沒有指定,則在default默認的命名空間中。
  2. RegionServer group:一個命名空間包含了默認的RegionServer Group。
  3. Permission:權限,命名空間能夠讓我們來定義訪問控制列表ACL(Access Control List)。例如,創建表,讀取表,刪除,更新等等操作。
  4. Quota:限額,可以強制一個命名空間可包含的region的數量。

4. HBase 原理

HBase是一個寫比讀快的 框架

寫原理

在這裏插入圖片描述
在這裏插入圖片描述
比如執行給table1裏面rowkey=11050的數據插入數據則看如下操作。

  1. 先跟ZK 詢問 /hbase/meta-region-server裏面的 meta數據存儲位置。
  2. 客戶1找到的位置到對應的機器上查找regions數據存儲概要。一般一行就是存儲該數據的表明,rowkey開始位置,rowkey結束位置,根據合適的範圍查找到對應的 regionServer,然後再根據數據信息 找到對應的region,然後數據寫到WAL中,再到MemCache,再到HFile(KV格式存儲)。

寫流程:

  1. Client 先訪問 zookeeper,獲取 hbase:meta 表位於哪個 Region Server。
  2. 訪問對應的 Region Server,獲取 hbase:meta 表,根據讀請求的 namespace:table/rowkey,查詢出目標數據位於哪個 Region Server 中的哪個 Region 中。並將該 table 的 region 信息以及 meta 表的位置信息緩存在客戶端的 meta cache,方便下次訪問。
  3. 與目標 Region Server 進行通訊;
  4. 將數據順序寫入(追加)到 WAL
  5. 將數據寫入對應的 MemStore,數據會在 MemStore 進行排序
  6. 向客戶端發送 ack;
  7. 等達到 MemStore 的刷寫時機後,將數據刷寫到 HFile
  8. 在web頁面查看的時候會隨機的給每一個region生成一個隨機編號。

PS ZK數據查找跟更新的 流程

zk ==> meta ==> regionserver ==> RegionIP 

HBase0.9版本前 meta數據又要被切分 -root-

zk ==> -root- ==>  meta ==> regionserver ==> RegionIP 

讀原理

在這裏插入圖片描述

  1. Client 先訪問 zookeeper,獲取 hbase:meta 表位於哪個 Region Server。
  2. 訪問對應的 Region Server,獲取 hbase:meta 表,根據讀請求的 namespace:table/rowkey, 查詢出目標數據位於哪個 Region Server 中的哪個 Region 中。並將該 table 的 region 信息以 及 meta 表的位置信息緩存在客戶端的 meta cache,方便下次訪問。
  3. 與目標 Region Server 進行通訊;
  4. 分別在 Block Cache(讀緩存),MemStore 和 Store File(HFile)中查詢目標數據,並將 查到的所有數據進行合併。此處所有數據是指同一條數據的不同版本(time stamp)或者不 同的類型(Put/Delete)。
  5. 將從文件HFile中查詢到的數據塊(Block,HFile 數據存儲單元,默認大小爲 64KB)緩存到 Block Cache。
  6. 將合併後的最終結果,然後返回時間最新的數據返回給客戶端。
  7. hbase中兩種緩存機制 memstore和blockcache詳解

重點:不要理解爲讀數據先從MemStore中讀取,然後讀BlockCache中,如果沒有再從HFile中讀取,然後將數據寫入到BlockCache中。因爲如果下面這樣的操作怎麼辦?

  • 創建表,寫入數據,刷新到磁盤中,

create stu ‘info’
put ‘stu’,‘info:name’,‘sowhat’
flush
bin/hbase org.apache.hadoop.hbase.io.hfile.HFile -a -b -e -k -p -f 列族文件在HDFS中路徑, 目的確保數據刷新到本地了

在這裏插入圖片描述

  • 插入一個比 sowhat時間早的數據,

put ‘stu’,‘info:name’,‘sowhat1412’,早點的時間戳。

  • 直接scan查詢可以看到 結果還是sowhat,說明數據每次都是把磁盤數據讀取了放到BlockCache中,然後跟MemCache數據合併!比較時間戳,返回時間戳最新的數據。也就是每次都要涉及到磁盤到讀取。

結論:HBase 把磁盤跟內存數據一起讀,然後把磁盤數據放到BlockCache中,BlockCache是磁盤數據的緩存。讀比寫慢的工具。

Scanner

查詢流程的形象圖
在這裏插入圖片描述

Flush

一般情況下一個Region中有多個列族,而整個region中有列族跟store是一 一對應的。對於用戶來說數據寫到MemStore中就算完成了,但是對於底層代碼來說只有數據刷到硬盤中才算徹底搞定了!因爲數據是要寫入到WAL(Hlog)中再寫入到MemStore中的,所以刷寫的時候,也有WAL個數的配置。配置文件

  1. WAL 個數 .

當 WAL 文件的數量超過 hbase.regionserver.max.logs,region 會按照時間順序依次進行刷寫,直到 WAL 文件數量減小到 hbase.regionserver.max.log 以下(該屬性名已經廢棄
現無需手動設置,最大值爲 32)。比如我的堆內存0.4= 1T,那麼我的Hlog文件可能也是大小1T,這樣如果一個HLog文件大小爲512M 則可能出現 10242個,所以需合理配置。

  1. hbase.regionserver.global.memstore.size

regionServer的全局memstore的大小,超過該大小會觸發flush到磁盤的操作,默認是堆大小的40%,而且regionserver級別的 , flush會阻塞客戶端讀寫。

  1. hbase.regionserver.global.memstore.size.lower.limit

可以理解爲一個安全的設置,有時候集羣的“寫負載”非常高,寫入量一直超過flush的量,這時,我們就希望memstore不要超過一定的安全設置。 在這種情況下,寫操作就要被阻塞一直到memstore恢復到一個“可管理”的大小, 這個大小就是默認值是堆大小 * 0.4 * 0.95,也就是當regionserver級別的flush操作發送後,會阻塞客戶端寫,一直阻塞到整個regionserver級別的memstore的大小爲 堆大小 * 0.4 *0.95爲止

  1. hbase.regionserver.optionalcacheflushinterval

內存中的文件在自動刷新之前能夠存活的最長時間,默認是1h,表示最後一條數據後的1小時。

  1. hbase.hregion.memstore.flush.size

單個region裏memstore的緩存大小,超過那麼整個HRegion就會flush,默認128M

StoreFile Compaction

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

Compaction 分爲兩種,分別是 Minor CompactionMajor Compaction。Minor Compaction會將臨近的若干個較小的 HFile 合併成一個較大的 HFile,但不會清理過期和刪除的數據。 Major Compaction 會將一個 Store 下的所有的 HFile 合併成一個大 HFile,並且會清理掉過期和刪除的數據。
在這裏插入圖片描述

數據刪除時間

create ‘stu4’,‘info’
put ‘stu4’,‘1001’,‘info:name’,‘xianyi’
put ‘stu4’,‘1001’,‘info:name’,‘yuyang’
flush ‘stu4’ 刷新一個文件
put ‘stu4’,‘1001’,‘info:name’,‘xianyu’ 顯示
flush ‘stu4’ 增加個文件
put ‘stu4’,‘1002’,‘info:name’,‘xianyi’ 顯示
flush ‘stu4’
compact 三個以上的文件調用小文件合併會自動觸發大文件合併,
scan ‘stu4’,{RAW=>TRUE,VERSIONS=>10}
只會顯示兩個文件

數據刪除只有在flush 跟上面的大合併(Major compaction)的時候執行。

  1. flush 可以刪除在同一個內存中的數據,flush只會操作當前內存。並且寫入本地後 內存數據會丟失。
  2. Major compaction 大合併時候會自動把所以數據排序刪除舊數據。

put ‘stu4’,‘1001’,‘info:name’,‘zhangsan’
put ‘stu4’,‘1001’,‘info:name’,‘lisi’
put ‘stu4’,‘1001’,‘info:name’,‘wangwu’
flush ‘stu4’
put ‘stu4’,‘1001’,‘info:name’,‘zhaoliu’ 此時查看可以看到zhaoliu
delete ‘stu4’,‘1001’,‘info:name’ 目的是刪除1001的 name屬性!
scan ‘stu4’,{ROW=>TRUE,VERSIONS=>10} 會顯示zhaoliu 但顯示已經刪除了。此時flush ‘stu4’ 再查看數據,會發現Type=DeleteColumn還存在。沒有刪除掉,因爲這個DeleteColumn還要用來刪除flush 磁盤裏的zhangsan,lisi,wangwu這三個數據。 而刪除的標準就是調用大合併的時候!

Region Split

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

Region Split 時機:

  1. 當 1 個 region 中的某個 Store 下所有 StoreFile 的總大小超過 hbase.hregion.max.filesize(默認10G), 該 Region 就會進行拆分(0.94 版本之前)。
  2. 當 1 個 region 中的某個 Store 下所有 StoreFile 的總大小超過 Min(R^2 * “hbase.hregion.memstore.flush.size”,hbase.hregion.max.filesize"),該 Region 就會進行拆分,其 中 R 爲當前 Region Server 中屬於該 Table 的個數(0.94 版本之後)。hbase.hregion.memstore.flush.size=128M

第一次的閾值是128,
切分後結果64 , 64
第二次閾值512M
64,512 ⇒ 54 + 256 + 256
最後會形成一個 64M…10G 的這樣Region隊列,會產生數據傾斜問題。
解決方法:提前做好Region組的規劃,0-1k,1k-2k,2k-3k這樣的。

官方不建議用多個列族,比如有CF1,CF2,CF3,但是 CF1數據很多而CF2跟CF3數據很少,那麼當觸發了region切分的時候,會把CF2跟CF3分成若干小份,不利於系統維護。

參考

HBase配置文件

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