經(jīng)典Hbase面試7題(附答案)
?Hbase
Hbase是怎么寫數(shù)據(jù)的??
HDFS和HBase各自使用場(chǎng)景?
Hbase的存儲(chǔ)結(jié)構(gòu)?
熱點(diǎn)現(xiàn)象(數(shù)據(jù)傾斜)怎么產(chǎn)生的,以及解決方法有哪些?
HBase的 rowkey 設(shè)計(jì)原則?
HBase的列簇設(shè)計(jì)?
HBase 中 compact 用途是什么,什么時(shí)候觸發(fā),分為哪兩種,有什么區(qū)別
1. Hbase是怎么寫數(shù)據(jù)的?
Client寫入 -> 存入MemStore,一直到MemStore滿 -> Flush成一個(gè)StoreFile,直至增長(zhǎng)到一定閾值 -> 觸發(fā)Compact合并操作 -> 多個(gè)StoreFile合并成一個(gè)StoreFile,同時(shí)進(jìn)行版本合并和數(shù)據(jù)刪除 -> 當(dāng)StoreFiles Compact后,逐步形成越來(lái)越大的StoreFile -> 單個(gè)StoreFile大小超過(guò)一定閾值后(默認(rèn)10G),觸發(fā)Split操作,把當(dāng)前Region Split成2個(gè)Region,Region會(huì)下線,新Split出的2個(gè)孩子Region會(huì)被HMaster分配到相應(yīng)的HRegionServer 上,使得原先1個(gè)Region的壓力得以分流到2個(gè)Region上
由此過(guò)程可知,HBase只是增加數(shù)據(jù),沒(méi)有更新和刪除操作,用戶的更新和刪除都是邏輯層面的,在物理層面,更新只是追加操作,刪除只是標(biāo)記操作。
用戶寫操作只需要進(jìn)入到內(nèi)存即可立即返回,從而保證I/O高性能。
2. HDFS和HBase各自使用場(chǎng)景
首先一點(diǎn)需要明白:Hbase是基于HDFS來(lái)存儲(chǔ)的。
HDFS:?
一次性寫入,多次讀取。
保證數(shù)據(jù)的一致性。
主要是可以部署在許多廉價(jià)機(jī)器中,通過(guò)多副本提高可靠性,提供了容錯(cuò)和恢復(fù)機(jī)制。
HBase:?
瞬間寫入量很大,數(shù)據(jù)庫(kù)不好支撐或需要很高成本支撐的場(chǎng)景。
數(shù)據(jù)需要長(zhǎng)久保存,且量會(huì)持久增長(zhǎng)到比較大的場(chǎng)景。
HBase不適用與有 join,多級(jí)索引,表關(guān)系復(fù)雜的數(shù)據(jù)模型。
大數(shù)據(jù)量(100s TB級(jí)數(shù)據(jù))且有快速隨機(jī)訪問(wèn)的需求。如:淘寶的交易歷史記錄。數(shù)據(jù)量巨大無(wú)容置疑,面向普通用戶的請(qǐng)求必然要即時(shí)響應(yīng)。
業(yè)務(wù)場(chǎng)景簡(jiǎn)單,不需要關(guān)系數(shù)據(jù)庫(kù)中很多特性(例如交叉列、交叉表,事務(wù),連接等等)。
3. Hbase的存儲(chǔ)結(jié)構(gòu)
Hbase 中的每張表都通過(guò)行鍵(rowkey)按照一定的范圍被分割成多個(gè)子表(HRegion),默認(rèn)一個(gè)HRegion 超過(guò)256M 就要被分割成兩個(gè),由HRegionServer管理,管理哪些 HRegion 由 Hmaster 分配。HRegion 存取一個(gè)子表時(shí),會(huì)創(chuàng)建一個(gè) HRegion 對(duì)象,然后對(duì)表的每個(gè)列族(Column Family)創(chuàng)建一個(gè) store 實(shí)例, 每個(gè) store 都會(huì)有 0 個(gè)或多個(gè) StoreFile 與之對(duì)應(yīng),每個(gè) StoreFile 都會(huì)對(duì)應(yīng)一個(gè)HFile,HFile 就是實(shí)際的存儲(chǔ)文件,一個(gè) HRegion 還擁有一個(gè) MemStore實(shí)例。
4. 熱點(diǎn)現(xiàn)象(數(shù)據(jù)傾斜)怎么產(chǎn)生的,以及解決方法有哪些
熱點(diǎn)現(xiàn)象:
某個(gè)小的時(shí)段內(nèi),對(duì)HBase的讀寫請(qǐng)求集中到極少數(shù)的Region上,導(dǎo)致這些region所在的RegionServer處理請(qǐng)求量驟增,負(fù)載量明顯偏大,而其他的RgionServer明顯空閑。
熱點(diǎn)現(xiàn)象出現(xiàn)的原因:
HBase中的行是按照rowkey的字典順序排序的,這種設(shè)計(jì)優(yōu)化了scan操作,可以將相關(guān)的行以及會(huì)被一起讀取的行存取在臨近位置,便于scan。然而糟糕的rowkey設(shè)計(jì)是熱點(diǎn)的源頭。
熱點(diǎn)發(fā)生在大量的client直接訪問(wèn)集群的一個(gè)或極少數(shù)個(gè)節(jié)點(diǎn)(訪問(wèn)可能是讀,寫或者其他操作)。大量訪問(wèn)會(huì)使熱點(diǎn)region所在的單個(gè)機(jī)器超出自身承受能力,引起性能下降甚至region不可用,這也會(huì)影響同一個(gè)RegionServer上的其他region,由于主機(jī)無(wú)法服務(wù)其他region的請(qǐng)求。
熱點(diǎn)現(xiàn)象解決辦法:
為了避免寫熱點(diǎn),設(shè)計(jì)rowkey使得不同行在同一個(gè)region,但是在更多數(shù)據(jù)情況下,數(shù)據(jù)應(yīng)該被寫入集群的多個(gè)region,而不是一個(gè)。常見(jiàn)的方法有以下這些:
加鹽:在rowkey的前面增加隨機(jī)數(shù),使得它和之前的rowkey的開(kāi)頭不同。分配的前綴種類數(shù)量應(yīng)該和你想使用數(shù)據(jù)分散到不同的region的數(shù)量一致。加鹽之后的rowkey就會(huì)根據(jù)隨機(jī)生成的前綴分散到各個(gè)region上,以避免熱點(diǎn)。
哈希:哈希可以使負(fù)載分散到整個(gè)集群,但是讀卻是可以預(yù)測(cè)的。使用確定的哈希可以讓客戶端重構(gòu)完整的rowkey,可以使用get操作準(zhǔn)確獲取某一個(gè)行數(shù)據(jù)
反轉(zhuǎn):第三種防止熱點(diǎn)的方法時(shí)反轉(zhuǎn)固定長(zhǎng)度或者數(shù)字格式的rowkey。這樣可以使得rowkey中經(jīng)常改變的部分(最沒(méi)有意義的部分)放在前面。這樣可以有效的隨機(jī)rowkey,但是犧牲了rowkey的有序性。反轉(zhuǎn)rowkey的例子以手機(jī)號(hào)為rowkey,可以將手機(jī)號(hào)反轉(zhuǎn)后的字符串作為rowkey,這樣的就避免了以手機(jī)號(hào)那樣比較固定開(kāi)頭導(dǎo)致熱點(diǎn)問(wèn)題
時(shí)間戳反轉(zhuǎn):一個(gè)常見(jiàn)的數(shù)據(jù)處理問(wèn)題是快速獲取數(shù)據(jù)的最近版本,使用反轉(zhuǎn)的時(shí)間戳作為rowkey的一部分對(duì)這個(gè)問(wèn)題十分有用,可以用 Long.Max_Value - timestamp 追加到key的末尾,例如[key][reverse_timestamp],[key]的最新值可以通過(guò)scan [key]獲得[key]的第一條記錄,因?yàn)镠Base中rowkey是有序的,第一條記錄是最后錄入的數(shù)據(jù)。
比如需要保存一個(gè)用戶的操作記錄,按照操作時(shí)間倒序排序,在設(shè)計(jì)rowkey的時(shí)候,可以這樣設(shè)計(jì)[userId反轉(zhuǎn)] [Long.Max_Value - timestamp],在查詢用戶的所有操作記錄數(shù)據(jù)的時(shí)候,直接指定反轉(zhuǎn)后的userId,startRow是[userId反轉(zhuǎn)][000000000000],stopRow是[userId反轉(zhuǎn)][Long.Max_Value - timestamp]
如果需要查詢某段時(shí)間的操作記錄,startRow是[user反轉(zhuǎn)][Long.Max_Value - 起始時(shí)間],stopRow是[userId反轉(zhuǎn)][Long.Max_Value - 結(jié)束時(shí)間]HBase建表預(yù)分區(qū):創(chuàng)建HBase表時(shí),就預(yù)先根據(jù)可能的RowKey劃分出多個(gè)region而不是默認(rèn)的一個(gè),從而可以將后續(xù)的讀寫操作負(fù)載均衡到不同的region上,避免熱點(diǎn)現(xiàn)象。
5. HBase的 rowkey 設(shè)計(jì)原則
長(zhǎng)度原則:100字節(jié)以內(nèi),8的倍數(shù)最好,可能的情況下越短越好。因?yàn)镠File是按照 keyvalue 存儲(chǔ)的,過(guò)長(zhǎng)的rowkey會(huì)影響存儲(chǔ)效率;其次,過(guò)長(zhǎng)的rowkey在memstore中較大,影響緩沖效果,降低檢索效率。最后,操作系統(tǒng)大多為64位,8的倍數(shù),充分利用操作系統(tǒng)的最佳性能。
散列原則:高位散列,低位時(shí)間字段。避免熱點(diǎn)問(wèn)題。
唯一原則:分利用這個(gè)排序的特點(diǎn),將經(jīng)常讀取的數(shù)據(jù)存儲(chǔ)到一塊,將最近可能會(huì)被訪問(wèn) 的數(shù)據(jù)放到一塊。
6. HBase的列簇設(shè)計(jì)
原則:在合理范圍內(nèi)能盡量少的減少列簇就盡量減少列簇,因?yàn)榱写厥枪蚕韗egion的,每個(gè)列簇?cái)?shù)據(jù)相差太大導(dǎo)致查詢效率低下。
最優(yōu):將所有相關(guān)性很強(qiáng)的 key-value 都放在同一個(gè)列簇下,這樣既能做到查詢效率最高,也能保持盡可能少的訪問(wèn)不同的磁盤文件。以用戶信息為例,可以將必須的基本信息存放在一個(gè)列族,而一些附加的額外信息可以放在另一列族。
7. HBase 中 compact 用途是什么,什么時(shí)候觸發(fā),分為哪兩種,有什么區(qū)別
在 hbase 中每當(dāng)有 memstore 數(shù)據(jù) flush 到磁盤之后,就形成一個(gè) storefile,當(dāng) storeFile的數(shù)量達(dá)到一定程度后,就需要將 storefile 文件來(lái)進(jìn)行 compaction 操作。
Compact 的作用:?
合并文件
清除過(guò)期,多余版本的數(shù)據(jù)
提高讀寫數(shù)據(jù)的效率
HBase 中實(shí)現(xiàn)了兩種 compaction 的方式:minor and major. 這兩種 compaction 方式的區(qū)別是:
Minor 操作只用來(lái)做部分文件的合并操作以及包括 minVersion=0 并且設(shè)置 ttl 的過(guò)期版本清理,不做任何刪除數(shù)據(jù)、多版本數(shù)據(jù)的清理工作。
Major 操作是對(duì) Region 下的 HStore 下的所有 StoreFile 執(zhí)行合并操作,最終的結(jié)果是整理合并出一個(gè)文件。
