今天早上分享了下HBase,分享的時候同事提出了一些問題,可能大部分有有這樣的困惑,彙總下來:html
答:java
As HBase runs on HDFS (and each StoreFile is written as a file on HDFS), it is important to have an understanding of the HDFS Architecture especially in terms of how it stores files, handles failovers, and replicates blocks.node
To operate with the most efficiency, HBase needs data to be available locally. Therefore, it is a good practice to run an HDFS DataNode on each RegionServerapache
Hbase運行在HDFS之上,每一個StoreFile都被寫成一個HDFS的文件,能理解HDFS的架構,它是如何存儲文件,處理故障轉移和複製塊很重要緩存
大多數狀況下,Hbase將數據存儲在HDFS之上,像Hfile和WALs(主要爲了防止RegionServer出現故障)都會存儲在HDFS上,HDFS提供對Hbase數據的可靠性和保證,爲了最大化的操做效率,Hbase也須要本地的數據是可靠的,所以最好是在每個RegionServer上運行DataNode。bash
當有問題出現的時候,最好同時檢查HDFS和Hbase的日誌,由於日誌可能再兩個地方都有記錄。服務器
另外,HBase不支持一臺用HDFS,一臺不用HDFS,在徹底分佈式的場景中,多個Hbase的實例運行在集羣的多個服務器上面,通常要設置兩個屬性:架構
hbase.rootdir指向一個HDFS的文件系統併發
hbase.cluster.distributed屬性設置爲true。app
以下:能夠看到HBase只能指向某一種文件系統的路徑上,並且想要HBase徹底的分佈式,必需要設置上面兩個屬性。
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://namenode.example.org:8020/hbase</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>node-a.example.com,node-b.example.com,node-c.example.com</value>
</property>
</configuration>
複製代碼
HBase是HDFS的客戶端,Hbase使用的是DFSClient來和HDFS交互,能夠看到配置就是Hbase指向HDFS的那個位置,HBase經過Ip port訪問HDFS。
參見:hbase.apache.org/book.html#_…
答:HBase和HDFS並非強制的綁定在一塊兒的,HBase徹底可使用本地文件系統,好比mac的文件系統,Linux的ext3,ext2等等,均可以運行Hbase。
Hlog其實就是WAL的實現, 它記錄Hbase中全部的數據改變,若是在RegionServer在MemStore刷新到磁盤以前,不能訪問或者掛掉了,WAL能夠保證數據的改變從新再進行一次。
The Write Ahead Log (WAL) records all changes to data in HBase, to file-based storage, WAL ensures that the changes to the data can be replayed
根據官網描述,HLog默認寫到磁盤上,即HDFS上,咱們在使用Hbase的時候能夠設置WAL的持久化方式,有如下四種:
Mutation.setDurability(Durability.SKIP_WAL)
複製代碼
所以默認方式下,WAL是寫到HDFS之上,會盡量的走持久化,而不是在內存中久留,可能再數據改變的時候通過內存,而後就馬上寫到HDFS上面了。
官方的命令是能夠修改列簇的名字的,列簇的添加,刪除,修改都是能夠的。可是能不能修改取決因而否配置了這個屬性:
hbase.online.schema.update.enable
// 給t1表新增f1列簇
alter 't1', NAME => 'f1', VERSIONS => 5
// 刪除ns1:t1表的f1列簇
alter 'ns1:t1', NAME => 'f1', METHOD => 'delete'
複製代碼
可是就像MySQL咱們能夠修改列的名字,在數據量很大的狀況下,咱們通常不會修改原有的列名。
客戶端首先經過hbase:meta表找到服務指定範圍的行的RegionServer,在定位到是哪一個Region以後,客戶端直接聯繫RegionServer,而沒有通過Master,而後發出讀寫請求。當Region被Master從新分配,或者某個RegionSever掛掉的時候,客戶端會從新的查詢索引表hbase:meta 來決定新的region位置。當RegionServer掛掉的時候,Master節點是能夠感知到的,Master作RegionServer的協調工做,會通知RegionSever,在客戶端查的時候也知道數據改變了,能夠再次請求索引表hbase:meta。
The HBase client finds the RegionServers that are serving the particular row range of interest. It does this by querying the
hbase:meta
table. See hbase:meta for details. After locating the required region(s), the client contacts the RegionServer serving that region, rather than going through the master, and issues the read or write request. This information is cached in the client so that subsequent requests need not go through the lookup process. Should a region be reassigned either by the master load balancer or because a RegionServer has died, the client will requery the catalog tables to determine the new location of the user region.
一個常問的問題就是Master掛掉的時候,Hbase會發生什麼事情,由於Hbase客戶端是直接和RegionServer進行通訊,並且hbase:meta表並無存在Master節點上,Master只是進行RegionServer的故障恢復和Region的切分,所以在Master掛掉的短期內,Hbase還能正常的工做,只不過要儘量快的修復Master。
Master節點感知的元數據改變是粒度比較大的,好比表改變,列簇改變,Region的切分,合併,移動,都不是頻繁的發生的狀況。
A common dist-list question involves what happens to an HBase cluster when the Master goes down. Because the HBase client talks directly to the RegionServers, the cluster can still function in a "steady state". Additionally, per Catalog Tables,
hbase:meta
exists as an HBase table and is not resident in the Master. However, the Master controls critical functions such as RegionServer failover and completing region splits. So while the cluster can still run for a short time without the Master, the Master should be restarted as soon as possible.
Master通常運行在NameNode上面,沒有存儲元數據。
另外多說下,Master是能夠有多個的,若是主Master掛掉了,剩餘的Master會競爭Master的角色。
If run in a multi-Master environment, all Masters compete to run the cluster. If the active Master loses its lease in ZooKeeper (or the Master shuts down), then the remaining Masters jostle to take over the Master role.
發送一個key,裏面具體怎麼獲取數據的?
由於每個用戶表Region都是一個RowKey Range,meta Region中記錄了每個用戶表Region的路由以及狀態信息,以RegionName(包含表名,Region StartKey,Region ID,副本ID等信息)做爲RowKey。
Region只要不被遷移,那麼獲取的該Region的路由信息就是一直有效的,所以,HBase Client有一個Cache機制來緩存Region的路由信息,避免每次讀寫都要去訪問ZooKeeper或者meta Region。
相似於Client發送建表到Master的流程,Client發送寫數據請求到RegionServer,也是經過RPC的方式。只是,Client到Master以及Client到RegionServer,採用了不一樣的RPC服務接口。
RegionServer的RPC Server側,接收到來自Client端的RPC請求之後,將該請求交給Handler線程處理。若是是single put,則該步驟比較簡單,由於在發送過來的請求參數MutateRequest中,已經攜帶了這條記錄所關聯的Region,那麼直接將該請求轉發給對應的Region便可。
HBase也採用了LSM-Tree的架構設計:LSM-Tree利用了傳統機械硬盤的「順序讀寫速度遠高於隨機讀寫速度」的特色。隨機寫入的數據,若是直接去改寫每個Region上的數據文件,那麼吞吐量是很是差的。所以,每個Region中隨機寫入的數據,都暫時先緩存在內存中(HBase中存放這部份內存數據的模塊稱之爲MemStore,這裏僅僅引出概念,下一章節詳細介紹),爲了保障數據可靠性,將這些隨機寫入的數據順序寫入到一個稱之爲WAL(Write-Ahead-Log)的日誌文件中.
WAL中的數據按時間順序組織:若是位於內存中的數據還沒有持久化,並且忽然遇到了機器斷電,只須要將WAL中的數據回放到Region中便可
若是一個WAL中所關聯的全部的Region中的數據,都已經被持久化存儲了,那麼,這個WAL文件會被暫時歸檔到另一個目錄中
在0.94版本以前,Region中的寫入順序是先寫WAL再寫MemStore,這與WAL的定義也相符。
但在0.94版本中,將這二者的順序顛倒了,當時顛倒的初衷,是爲了使得行鎖可以在WAL sync以前先釋放,從而能夠提高針對單行數據的更新性能。詳細問題單,請參考HBASE-4528。
在2.0版本中,這一行爲又被改回去了,緣由在於修改了行鎖機制之後(下面章節將講到),發現了一些性能降低,而HBASE-4528中的優化卻沒法再發揮做用,詳情請參考HBASE-15158。改動以後的邏輯也更簡潔了。
至此,這條數據已經被同時成功寫到了WAL以及MemStore中, 當MemStore達到閾值的時候,會被刷新到磁盤上進行持久化存儲,而若是服務器掛掉了,則能夠經過WAL進行數據恢復。
參考:一條數據的HBase之旅,簡明HBase入門教程-Write全流程
像上面提到的Hlog是存儲在磁盤上面的,不是內存型存儲不須要淘汰策略,要解決的就是磁盤存滿以後怎麼辦?磁盤滿了確定是存不進去了,通常狀況下咱們都會有磁盤利用率的檢測工具,在磁盤到達必定程度以後進行通知,HDFS是能夠無限擴容的,就是多加臺服務器的事情。
在以前的版本中,行級別的任何併發寫入/更新都是互斥的,由一個行鎖控制。但在2.0版本中,這一點行爲發生了變化,多個線程能夠同時更新一行數據,這裏的考慮點爲:
後續單獨整理
Hbase備份和恢復,屬於比較大的知識塊,後續單獨整理