1.本文說明
筆者最近一年從事維護(hù)Hbase相關(guān)工作,總結(jié)相關(guān)文章用于闡述對于Hbase的部分理解,本文知識點來源于
《HBase原理與實踐》第三章
2.Hbase依賴服務(wù)
2.1 正常的依賴
至少依賴ZK、HDFS,特殊場景,如Copy SnapShot和驗證集群間數(shù)據(jù)一致性,需要借助YARN集群的分布式計算能力
2.2 ZK簡介
- ZK之所以占據(jù)如此重要的地位,是因為它解決了分布式系統(tǒng)中一些最基礎(chǔ)的問題
1.提供極低延遲、超高可用的內(nèi)存KV數(shù)據(jù)庫服務(wù)
2.提供中心化的服務(wù)故障發(fā)現(xiàn)服務(wù)
3.提供分布式場景下的鎖、Counter、Queue等協(xié)調(diào)服務(wù) - ZK核心特性
1.多類型節(jié)點,ZK數(shù)據(jù)樹節(jié)點可以設(shè)置多種節(jié)點類型,每種節(jié)點類型具有不同節(jié)點特性。
2.Watcher機制,該機制是ZK實現(xiàn)的一種時間異步反饋機制,就像現(xiàn)實生活中某讀者訂閱了某個主題,這個主題一旦有任何更新都會第一時間反饋給該讀者一樣。
3.Session機制,ZK啟動時,客戶端會根據(jù)配置文件中ZK服務(wù)器列表配置項,選擇其中任意一臺服務(wù)器相連,如果連接失敗,會嘗試連接另一臺服務(wù)器,直到與一臺服務(wù)器成功創(chuàng)建連接或因為ZK服務(wù)器都不可用而失敗。
ZK對于網(wǎng)絡(luò)連接斷開和Session過期是兩種處理機制。
客戶端與服務(wù)端之間維持一個長鏈接,在Session超時時間內(nèi),服務(wù)端會不斷檢測該客戶端是否還處于正常連接,服務(wù)端會將客戶端的每次操作視為一次有效的心跳檢測來反復(fù)地進(jìn)行Session激活。因此,在正常情況下,客戶端Session是一直有效的。
當(dāng)客戶端與服務(wù)端之間的連接斷開后,用戶在客戶端可能主要看到:CONNECTION_LOSS和SESSION_EXPIRED 兩類異常。 - CONNECTION_LOSS
網(wǎng)絡(luò)一旦斷連,客戶端就會收到CONNECTION_LOSS異常,此時它會自動從ZK服務(wù)器列表中重新選擇去新的地址,并嘗試重新連接,知道最終成功連上服務(wù)器。 - SESSION_EXPIRED
客戶端與服務(wù)端斷開連接后,如果重連時間耗時太長,超過了Session超時時間,服務(wù)器會進(jìn)行Session清理,此時客戶端不知道Session已經(jīng)失效,狀態(tài)還是DISCONNECTED,如果客戶端重新連上了服務(wù)器,此時狀態(tài)會變更為SESSION_EXPIRED。 -
ZK典型使用場景
HBASE使用ZK實現(xiàn)了Master的高可用管理,RS宕機異常檢測、分布式鎖等一些列功能
分布式鎖的具體實現(xiàn)步驟
ZK-HBASE.png - Hbase中ZK的重要配置
1.hbase.zookpeer.quorum
zk集群地址,必須進(jìn)行配置
2.hbase.zookpeer.property.clientport
zk集群端口,可以不進(jìn)行配置
3.zookeeper.znode.parent
hbase的位置
4.zookeeper.session.timeout
rs與zk會話超時時間 -
ZK存儲信息
HBase-ZK存儲信息.png
2.3 HDFS簡介
HDFS本質(zhì)上是一個分布式文件系統(tǒng),可以部署在大量廉價的服務(wù)器上,提供可擴展的、高容錯性的文件讀寫服務(wù)。
Hbase項目本身并不負(fù)責(zé)文件側(cè)面的高可用和擴展性,它通過把數(shù)據(jù)存儲在HDFS上來實現(xiàn)大容量文件存儲和文件備份。
HDFS擅長的場景是大文件的順序讀、隨機讀和順序?qū)憽?/p>
- HDFS高可用服務(wù)
NN、DN、JN、ZKFC -
架構(gòu)圖如下:
image.png -
文件寫入流程
image.png - 步驟1:
DFS Client 在創(chuàng)建FSDataOutputStream時,把文件元數(shù)據(jù)發(fā)給NN,得到一個文件唯一表示的field,并向用戶返回一個OutputStream - 步驟2:
用戶拿到OutPutStream之后,開始寫數(shù)據(jù)。注意寫數(shù)據(jù)都是按照Block來寫的,不同的Block可能分布在不同的DN上,因此如果發(fā)現(xiàn)當(dāng)前的Block已經(jīng)寫滿,DFSClient就需要再發(fā)起請求向NN申請一個新的Block,在一個Block內(nèi)部,數(shù)據(jù)由若干個Packet組成,若當(dāng)前的Packet寫滿了,就放入DataQueue隊列,DataStreamer線程異步地把Packet寫入到對應(yīng)的DN。3個副本中的某個DN收到Packet之后,會先寫本地文件,然后發(fā)送一份到第2個DN,第2個執(zhí)行類似步驟后,發(fā)給第3個DN。等待所有的DN都寫完數(shù)據(jù)之后,就發(fā)送Packet的ACK給DFS Client,只有收到ACK的Packet才是寫入成功的。 - 步驟3:
用戶執(zhí)行完寫入操作后,需要關(guān)閉OutPutStream,關(guān)閉過程中,DFSClient會先把本地DataQueue中未發(fā)出去的Packet全部發(fā)送到DN,若忘記關(guān)閉,對那些已經(jīng)成功緩存在DFS Client的DataQueue中,但尚未成功寫入DN的數(shù)據(jù),就沒機會寫入DataNode中。 - FsDataOutputStream中的hflush和hsync的區(qū)別
hflush成功返回,則表示DFSClient的DataQueue中所有Packet都已經(jīng)成功發(fā)送到了3個DN上,但是對每個DN而言,數(shù)據(jù)仍然可能存放在操作系統(tǒng)的Cache上,若存在至少一個正常運行的DN,則數(shù)據(jù)不會丟失。
hsync成功返回,則表示DFSClient DataQueue中的Packet不但成功發(fā)送到3個DN,而且每個DN上的數(shù)據(jù)都持久化到了磁盤上,這樣就算所有的DN都重啟,數(shù)據(jù)仍然存在。 -
文件讀取
image.png - 讀取流程描述
1.1 DFSClient請求NN,獲取到對應(yīng)read position的Block信息(包括Block落在哪些DN上)。
1.2 DFSClient從Block對應(yīng)的DN中選擇一個合適的DN,對選中的DN創(chuàng)建一個BlockReader以進(jìn)行數(shù)據(jù)讀取。
HDFS讀取流程簡單,但對Hbase的讀取性能影響重大,尤其是Locality和短路讀這兩個最為核心的因素。 - Locality
DN本身需要消耗的內(nèi)存資源和CPU資源都非常少,主要消耗網(wǎng)絡(luò)帶寬和磁盤資源。而Hbase的RS服務(wù)本身是內(nèi)存和CPU消耗型服務(wù),于是我們把RS和DN部署在一批機器上,對DFSClient來說,一個文件在這臺機器上的locality可以定義為:
locality=該文件存儲在本地機器的字節(jié)數(shù)之和/該文件總字節(jié)數(shù) - 短路讀
短路讀是指那些Block落在和DFSClient同一臺機器上的數(shù)據(jù),可以不走TCP協(xié)議進(jìn)行讀取,而是直接由DFSClient向本機的DN請求對應(yīng)的Block文件描述符,然后創(chuàng)建一個BlockReaderLocal,通過fd進(jìn)行數(shù)據(jù)讀取,這樣就節(jié)省了走本地TCP協(xié)議棧的開銷。
測試數(shù)據(jù)表明:
locality和短路讀對Hbase的讀性能影響重大,在locality=1.0情況下,不開短路讀的p99性能要比開短路讀差10%左右。 - HDFS在Hbase系統(tǒng)中扮演的角色
1.Hbase本身并不存儲文件,它只規(guī)定文件格式以及文件內(nèi)容,實際文件存儲由HDFS實現(xiàn)。
2.HBase不提供機制保證存儲數(shù)據(jù)的高可靠性,數(shù)據(jù)的高可靠性由HDFS的多副本機制保證。
3.HBase-HDFS體系是典型的計算存儲分離架構(gòu),這種輕耦合架構(gòu)的好處是,一方面可以非常方便地使用其他存儲替代HDFS作為Hbase的存儲方案,另一方面對于云上服務(wù)來說,計算資源和存儲資源都可以獨立擴容、縮容,給云上用戶帶來了極大便利。
2.4 HBase在HDFS中的文件布局

image.png
具體的布局情況

Hbase On HDFS.png




