1. HBase介紹,Hbase是什么?
HBase -- Hadoop Database ,是一個高可靠、高性能、面向列、可伸縮的分布式存儲系統。Hbase來源于Google的論文“Bigtable: 一個結構化數據的分布式存儲系統”。HBase實際上是Hadoop的一個數據庫系統,它的主要作用和傳統數據庫系統一樣存儲數據和檢索數據。
傳統關系型數據庫的一些問題:
1) 傳統的RDBMS關系型數據庫存儲一定量數據時沒有問題,但是在存儲海量數據(PB、TB級別),傳統數據庫無法支撐。
2) 性能差(數據量很大時)。
3) 面向行的,架構不夠彈性,不能任意增加列。
Hbase和傳統數據庫的表結構的差異(Hbase不同于傳統RDBMS,是面向列的):
傳統數據庫的表結構:
hbase表結構:
2. HBase架構設計
Hbase運行在Hadoop文件系統HDFS上,是建立在HDFS上的列式存儲數據庫。
- Master:Hbase的主節點(集群中的某一臺服務器),協調客戶端應用程序與RegionServer的關系,監控和記錄元數據的變化和管理。
- RegionServer:是Hbase的從節點,用region形式處理實際的表。Region是Hbase表的基礎單元組件,存儲了分布式表。Hbase集群利用Master和RegionServer來協同工作。
- Zookeeper:在Hbase中,選舉集群主節點Master,以便跟蹤可用的在線服務器,同時維護集群的元數據。一般安裝多個,用于提供Master的高可用性。
- Clinet:使用HBase RPC機制與Master和RegionServer通信。對于管理類操作(DDL操作)與Master通信,對于數據讀寫類操作與RegionServer通信。
通常情況下,Master和Hadoop的Namenode進程運行在同一主機上,與Datanode通信以讀寫Hdfs,RegionServer和Hadoop的datanode運行在同一臺主機上。
HBase具有可擴展性的原因:
- 讀取hdfs的數據,hdfs的擴展可以通過datanode的增加完成;
- 一個表的數據分成多個區域Region,每個區域都有一個專門的RegionServer負責數據管理及檢索,而RegionServer像datanode一樣可以隨意增加(RegionServer運行在Datanode的機器上,可以和datanode一樣多)。
3. HBase數據模型:
HBase不以關系設計為中心,可以根據需求隨意增加字段。每行數據提供row_key做快速索引。
行鍵:是每個記錄的唯一鍵,它在內存或磁盤中是以字節數組保存的,沒有數據類型的概念。行健的設計
列族:將相同功能或類型的列集合在一起成為列族。
除了上邊幾個概念外,還包括以下一些:
(1)版本:Hbase中沒有Insert和Update,只有put。每put一次,就會產生一個版本,默認顯示你最后一次put的內容(最新的版本),并且保留3個版本的記錄。
(2)時間戳:表示數據插入到表中的時間。
(3)單元格:最基本的存儲單元,在內部就是一個實際存儲的值。插入單元格數據時,必須包括:rowkey + column family + column + timestamp : value。
HBase的Schema由表名和列族兩項組成。另外,值結合版本信息轉為字節數組存儲在列中。
4. HBase環境搭建:
HBase分布式環境搭建,可以參考如下網址:
http://hbase.apache.org/book.html
角色規劃:
HBase的單機模式不會使用HDFS系統,而是使用本地文件系統file://來存儲數據。
(1)下載hbase對應的安裝文件,并解壓縮。
$ tar zxf hbase-0.98.6-cdh5.3.6.tar.gz -C /opt/modules/
(2)修改配置:
修改配置文件 conf/hbase-env.sh 增加Java環境變量,并且不使用HBase來管理Zookeeper:
export JAVA_HOME=/opt/modules/jdk1.7.0_67
export HBASE_MANAGES_ZK=false
修改HBase的主配置文件 conf/hbase-site.xml:
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://hadoop-senior01.pmpa.com:8020/hbase</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>hadoop-senior01.pmpa.com,hadoop-senior02.pmpa.com,hadoop-senior03.pmpa.com</value>
</property>
</configuration>
說明:
- hdfs的8020端口,接收Client連接的RPC端口,用于獲取文件系統metadata信息。
- 配置hbase.rootdir屬性時,不需要創建相應的目錄,否則就變成了migration。
修改配置文件conf/regionservers ,添寫regionserver的ip。
hadoop-senior01.pmpa.com
hadoop-senior02.pmpa.com
hadoop-senior03.pmpa.com
修改配置文件conf/backup-masters,添加作為backup master角色的主機IP。
hadoop-senior02.pmpa.com
將配置復制到其他兩個主機上:
$ scp -r hbase-0.98.6-cdh5.3.6/ natty@hadoop-senior02.pmpa.com:/opt/modules/
$ scp -r hbase-0.98.6-cdh5.3.6/ natty@hadoop-senior03.pmpa.com:/opt/modules/
(3)啟動HBase,測試安裝:
首先,需要在三臺主機啟動Zookeeper服務。
$ bin/zkServer.sh start
啟動hadoop集群的各個角色:
$ sbin/start-dfs.sh
$ sbin/start-yarn.sh
$ sbin/mr-jobhistory-daemon.sh start historyserver
在啟動HBase之前,一定確保沒有HBase進程(例如:HMaster, HRegionServer, HQuorumPeer)存在,否則會出問題。使用腳本bin/start-hbase.sh來啟動Hbase。
$ bin/start-hbase.sh
當然,也可以分角色啟動HBase,分別單獨啟動master和regionserver,啟動方法如下:
$ bin/hbase-daemon.sh start master
$ bin/hbase-daemon.sh start regionserver
查看進程是否存在:
senior01的進程角色(Master、Regionserver):
2957 QuorumPeerMain
3203 DataNode
3730 HMaster
3450 NodeManager
4120 Jps
3090 NameNode
3822 HRegionServer
senior02的進程角色(Backup Master、Regionserver):
3113 HMaster
2400 QuorumPeerMain
3281 Jps
2504 ResourceManager
2606 NodeManager
3043 HRegionServer
senior03的進程角色(Regionserver):
2422 QuorumPeerMain
3202 Jps
2561 SecondaryNameNode
3037 HRegionServer
2666 NodeManager
2828 JobHistoryServer
2486 DataNode
至此,HBase的分布式模式搭建完成。
5. HBase Shell 基本使用:
(1)在啟動了HBase之后,輸入$ bin/hbase 可以獲得很多參數:
shell Run the HBase shell
hbck Run the hbase 'fsck' tool
hlog Write-ahead-log analyzer
hfile Store file analyzer
zkcli Run the ZooKeeper shell
upgrade Upgrade hbase
master Run an HBase HMaster node
regionserver Run an HBase HRegionServer node
zookeeper Run a Zookeeper server
rest Run an HBase REST server
thrift Run the HBase Thrift server
thrift2 Run the HBase Thrift2 server
clean Run the HBase clean up script
classpath Dump hbase CLASSPATH
mapredcp Dump CLASSPATH entries required by mapreduce
pe Run PerformanceEvaluation
ltt Run LoadTestTool
version Print the version
CLASSNAME Run the class named CLASSNAME
其中,shell參數可以進入hbase 的shell命令行界面。
hlog參數很重要,可以分析和查看hbase的日志。預先寫日志(二進制日志文件),在客戶端往HBase寫操作前記錄日志。HBase與傳統數據庫有很大區別,寫操作遠遠多于讀操作(W:R約等于10:1)。同時, write-ahead log也可以防止寫丟失。
(2)啟動HBase的shell命令行:
$ bin/hbase shell
bin/hbase 命令有很多選項,直接輸入命令 bin/hbase 可以查看所有選項的幫助。例如,查看hbase版本:
$ bin/hbase version
HBase的命令行模式不支持退格鍵,輸入了錯的命令后無法修改,所以需要首先解決這個問題。我使用的SecureCRT終端,下面是SecureCRT的解決方案:
選項 --> 會話選項 -->終端 --> 仿真 --> 終端項選擇“Linux”
做了上述配置后,可以使用 Ctrl+刪除鍵(backspace) 在HBase shell中做退格操作。
(3)hbase shell命令:
HBase中沒有數據庫的概念,只有命名空間(相當于數據庫的概念)。
- 使用help命令查看命令幫助(有命令 和 命令組 的概念):
hbase(main):001:0> help
- 如果要查看create命令如何使用(查看其它命令幫助也一樣),直接在shell命令行中輸入 create:
hbase(main):002:0> create
從給出的幫助信息可以找到: hbase> create 'ns1:t1', {NAME => 'f1', VERSIONS => 5} 。其中ns1是命名空間、t1是表名、f1是列族名(可以聲明多個列族,每個大括號內是一個列族的信息)。
- 創建user表、user1表;并查看所有的表(使用list):
hbase(main):003:0> create 'user','info'
hbase(main):004:0> create 'user1',{NAME => 'info1',VERSIONS => 5}
hbase(main):005:0> list
創建完表之后,從下圖可以看到:每個HBase的表,在HDFS上對應一個目錄。
在創建表時我沒有指定namespace,默認會放在default 命名空間上。hbase命名空間是保存元數據信息的namespace。
- 查看表的信息:
hbase(main):006:0> describe 'user1'
- 向表中插入數據,使用put命令:
hbase(main):007:0> put
hbase(main):009:0> put 'user','10001','info:name', 'Jackson'
hbase(main):010:0> put 'user','10001','info:age','31'
hbase(main):011:0> put 'user','10001','info:sex','male'
hbase(main):012:0> put 'user','10001','info:address','beijing'
hbase(main):016:0> put 'user','10002','info:name', 'Lucy'
hbase(main):017:0> put 'user','10002','info:sex', 'female'
hbase(main):018:0> put 'user','10003','info:name', 'Honda'
查看put命令幫助得到put的語法:hbase> put 't1', 'r1', 'c1', 'value' t1:表名;r1:行鍵;c1:列名;'value' 是值。
- 下面查看數據,可以使用get和scan兩個命令:
hbase(main):013:0> get 'user','10001'
hbase(main):014:0> scan 'user'
hbase(main):023:0> scan 'user', {COLUMNS => ['info:name','info:age']}
hbase(main):025:0> scan 'user', {STARTROW=>'10001',STOPROW=>'10002'}
get命令一般根據行鍵獲取單條結果。
scan命令是范圍掃描,查看整個表。同時,可以在scan命令中限定范圍來查找,STARTROW、STOPROW選項是很常用的,這兩個選項需要注意的一點是,這個區間是左閉右開的,也就是“[ STARTROW,STOPROW )”,這點需要注意。
在scan數據時,可以通過STARTROW=> 和ENDROW=>來指定范圍檢索,而且支持正則表達式(前綴匹配)。
- 刪除表,在刪除(drop)前需要先禁用(disable)該表:
hbase(main):027:0> disable 'user1'
hbase(main):028:0> drop 'user1'
- 刪除表中的數據(這里新做了一張表user2,并添加了一些數據來做測試):
測試數據如下:
ROW COLUMN+CELL
01 column=info:name, timestamp=1493743972426, value=zhangsan
02 column=info:name, timestamp=1493743985575, value=lisi
02 column=info:sex, timestamp=1493744013788, value=male
03 column=info:name, timestamp=1493743996438, value=wangwu
1.刪除行中的某個列值:
hbase(main):036:0> delete 'user2','02','info:sex'
上邊命令刪除了行健為02的數據行的 info:sex列。
2.刪除整行:
hbase(main):040:0> deleteall 'user2','03'
3.清空表:
hbase(main):043:0> truncate 'user2'
Truncating 'user2' table (it may take a while):
- Disabling table...
- Dropping table...
- Creating table...
0 row(s) in 2.0170 seconds
- 創建命名空間:
hbase(main):043:0> create namespace 'ns1'
hbase(main):043:0> create table 'ns1:table1','info'
hbase(main):043:0> list
hbase(main):043:0> list_namespace 'ns1'
hbase(main):043:0> list_namespace_tables 'ns1'
HBase的命名空間類似于RDBMS中的數據庫的概念,可以在命名空間下創建表和管理表。每個命名空間對應于HDFS上的一個目錄,這個命名空間下的表的數據也存在這個目錄下。
上邊命令create namespace新建了一個命名空間ns1, 在ns1空間下創建一個有一個列族info的表table1。下面列出某個命名空間下的所有表。
默認情況,有2個命名空間,分別是default和HBase。默認建的表都在default空間,HBase空間是系統命名空間。HBase空間下有2張表,一個是meta表(用來存儲元數據,用戶表region的相關信息),一個是namespace表(用來存儲命名空間)。
6. HBase表的物理模型:
1. HBase存儲結構:
HBase是按照列存儲的,每個Column Family存儲在單獨的一個HDFS文件上。表格中的行按照Rowkey字典序進行排列,表格在行的方向上被分隔為多個Region(按行進行分隔)
HBase有一個典型的應用場景:查詢歷史訂單。訂單數據是海量的,使用RDBMS會非常緩慢。例如查詢近10天的訂單,使用HBase能完美解決。
一般地,HBase表并不多但都是很大的表(不是數據量大,而是大寬表,列可以任意添加)。
2. HBase如何來劃分Region?
HBase提供了兩種方式來劃分Region。
第一種方式,在創建表的時候劃定范圍。請看下例:
在HBase shell中,查看create命令的幫助,可以看到這樣一個實例:
create 'ns1:t1', 'f1', SPLITS => ['10', '20', '30', '40']
SPLITS關鍵字會按照RowKey劃分五個Region。rowkey在0到10的數據在region1,rowkey在10到20的在region2,依此類推。
第二種方式,按照閾值自動劃分。請看下例:
根據閾值自動劃分。Region按大小分割,每個表開始只有一個Region,隨著數據增多,當增大到一個閾值時,Region就等分成2個新Region(出現新的Region),之后出現越來越多Region。
如上圖,表A按照行被劃分成相等的4個Region,RegionServer管理Region。每個RegionServer可以管理不同表格的Region,而且每個RegionServer管理的Region數量是相同的。
當要讀取region3的數據時,就是RegionServer86來提供服務,但是region3的數據塊不一定在RegionServer86上,因為數據塊的存儲單位是block(HDFS概念),可能存儲在多個datanode上。上圖中,類似Region4和RegionServer367的對應關系稱為元數據,存儲在Zookeeper中。
Region是HBase中分布式存儲和負載均衡的最小單元,但是不是存儲的最小單元(底層存儲)。
- Region由一個或多個Store組成,每個Store保存一個Column Family列族。
- 每個Store又由有一個memStore 和 0到多個StoreFile組成。
- memStore存儲在內存中,StoreFile存儲在HDFS上。
- 每個Region還包含一個HLog(預寫式日志Write-Ahead-Log,當存儲數據時只有把數據寫入WAL和每個Store中的memStore才算成功)
3.HBase處理單點故障:
以上邊的圖為例,RegionServer367發生了宕機情況,將進行以下流程:
Zookeeper實時監控RegionServer,發現RegionServer367宕機。通知Master,Master會重新指派RegionServer7來管理原來RegionServer367管理的Regions。
7.HBase數據讀寫流程:
1. HBase檢索流程
下圖是HBase數據的檢索流程圖:
讀取數據流程:
(1)客戶端(Client)需要訪問Zookeeper集群,獲得元數據信息(表信息,每張表的Region信息,StartKey、EndKey)。
(2)Client找到Region對應的 RegionServer。這個信息存在hbase:meta中(Region和RegionServer的對應關系,也就是某個Region由哪個RegionServer來管理,存在hbase:meta表中)
(3)RegionServer響應客戶端請求。
Region對應于哪個RegionServer服務器,這個信息在元數據表中存儲。打開HBase的管理頁面(60010端口):
在Tables一欄中,有“User Tables” 和 “Catalog Tables”,查看后者:
寫數據流程:
(1)訪問Zookeeper集群,獲取該數據應該寫入哪個Region中。
(2)向region所在的Region Server發起寫請求
(3)RegionServer把數據先寫進HLog(WAL),然后寫入memStore(根據閾值flush到磁盤默認128MB)
(4)當memStore達到閾值,寫入HFile,HFile再合并為storeFile(每個storeFile達到閾值合并,compact)
(5)當StoreFile達到閾值,合并成新的更大的StoreFile
(6)如果當前的Region達到閾值,當前Region會劃分為2個新的Region(split)
有3個核心點:flush 、compact、split
2. HBase表
HBase的表分為User Tables(用戶表) 和 Catalog Tables(系統自帶表)。
HBase的所有表數據都存放在HDFS的/hbase/data目錄下,該目錄下的每一個目錄是一個命名空間(類似于RDBMS的數據庫概念),如下圖有2個命名空間(default和hbase),用戶建的表默認存在default命名空間。
下邊的命令可以查看HBase上的命名空間:
hbase(main):005:0> list_namespace
查看某個命名空間下的所有的表(查看hbase命名空間下的所有表):
hbase(main):007:0> list_namespace_tables 'hbase'
查看meta表信息:
hbase(main):008:0> scan 'hbase:meta'
用戶表由Region組成,Region信息存儲在hbase:meta中。
8. HBase數據存儲
1. HBase能高速實現數據讀寫源于HBase數據存儲
- (讀)連接Zookeeper,從Zookeeper中找要讀的數據。需要知道Rowkey在表中region的位置。
- 客戶端查找HRegionServer,HRegionServer管理眾多region。(通過Region和RegionServer的對應關系查找)
- HMaser也需要連接Zookeeper,作用是HMaster需要知道哪些HRegionServer是活動的及位置,然后管理HRegionServer。(HRegionServer的上下線)
- HBase內部是把數據寫到HDFS上的,DFS有客戶端。
- Region中包含HLog、Store。一個列族對應一個Store。Store中有多個MemStore及StoreFile。StoreFile是對HFile的封裝。StoreFile真正存儲在HDFS上。
- 所以寫數據時先往HLog上寫一份,再往MemStore上寫一份。當MemStore達到一定大小則往StoreFile上寫。若MemStore丟失,從HLog上恢復。
- 讀數據時先到MemStore上讀,再到StoreFile上讀,之后合并。
2. HBase數據存儲
HBase的所有文件都存在HDFS上主要包括HFile(Hadoop的二進制格式文件)和HLog File(Hadoop的Sequence File)。
HRegionServer內部管理一系列HRegion對象,每個對象對應table中的一個region。最好將IO特性一致的列設計為一個Column Family。
StoreFile在合并時同時進行版本合并和數據刪除。
- 當StoreFiles Compact后,逐步形成越來越大的StoreFile。
- 單個StoreFile大小超過閾值后,觸發split操作,把當前region分成2個region,region會下線,新分出的2個孩子region會被HMaster分配到相應的HRegionServer上,使得原先1個Region的壓力得以分流到2個Region上。