国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

HBase RegionServer宕機(jī)恢復(fù)

2019-11-09 13:32:08
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
問(wèn)題導(dǎo)讀:1.HBase的故障恢復(fù)有哪三種不同模式?2.HBase日志切分方法?3.Distributed Log Replay解決了哪些問(wèn)題?HBase采用類LSM的架構(gòu)體系,數(shù)據(jù)寫(xiě)入并沒(méi)有直接寫(xiě)入數(shù)據(jù)文件,而是會(huì)先寫(xiě)入緩存(Memstore),在滿足一定條件下緩存數(shù)據(jù)再會(huì)異步刷新到硬盤(pán)。為了防止數(shù)據(jù)寫(xiě)入緩存之后不會(huì)因?yàn)镽egionServer進(jìn)程發(fā)生異常導(dǎo)致數(shù)據(jù)丟失,在寫(xiě)入緩存之前會(huì)首先將數(shù)據(jù)順序?qū)懭際Log中。如果不幸一旦發(fā)生RegionServer宕機(jī)或者其他異常,這種設(shè)計(jì)可以從HLog中進(jìn)行日志回放進(jìn)行數(shù)據(jù)補(bǔ)救,保證數(shù)據(jù)不丟失。HBase故障恢復(fù)的最大看點(diǎn)就在于如何通過(guò)HLog回放補(bǔ)救丟失數(shù)據(jù)。HLog簡(jiǎn)介為了更好的理解HBase故障恢復(fù)原理,需要對(duì)HLog有簡(jiǎn)單的認(rèn)識(shí)。HLog的整個(gè)生命歷程可以使用下面一張圖來(lái)表示:1. HLog構(gòu)建:HLog的結(jié)構(gòu)示意圖:上圖可以看出,一個(gè)HLog由RegionServer上所有Region的日志數(shù)據(jù)構(gòu)成,日志數(shù)據(jù)的最小單元為<HLogKey,WALEdit>,其中HLogKey由sequenceid、writetime、clusterid、regionname以及tablename組成。其中sequenceid是日志寫(xiě)入時(shí)分配給數(shù)據(jù)的一個(gè)自增數(shù)字,先寫(xiě)入的日志數(shù)據(jù)sequenceid小,后寫(xiě)入的sequenceid大。2. HLog滾動(dòng):HBase后臺(tái)啟動(dòng)了一個(gè)線程會(huì)每隔一段時(shí)間(由參數(shù)’hbase.regionserver.logroll.period’決定,默認(rèn)1小時(shí))進(jìn)行日志滾動(dòng),即新生成一個(gè)新的日志文件。可見(jiàn),HLog日志文件并不是一個(gè)大文件,而是會(huì)產(chǎn)生很多小文件。有些同學(xué)就會(huì)問(wèn)了,為什么需要產(chǎn)生多個(gè)日志文件,一個(gè)日志文件不好嗎?這是因?yàn)殡S著數(shù)據(jù)的不斷寫(xiě)入,HLog所占空間將會(huì)變的越來(lái)越大,然而很多日志數(shù)據(jù)其實(shí)已經(jīng)沒(méi)有任何作用了,這部分?jǐn)?shù)據(jù)完全可以被刪掉。而刪除數(shù)據(jù)最好是一個(gè)文件一個(gè)文件整體刪除,因此設(shè)計(jì)了日志滾動(dòng)機(jī)制,方便文件整體刪除。類似于Binlog的處理機(jī)制。3. HLog失效:上文提到,很多日志數(shù)據(jù)在之后會(huì)因?yàn)槭нM(jìn)而可以被刪除,并且刪除操作是以文件為單元執(zhí)行的。那怎么判斷一個(gè)日志文件里面的數(shù)據(jù)失效了呢?首先從原理上講一旦數(shù)據(jù)從Memstore中落盤(pán),對(duì)應(yīng)的日志就可以被刪除,因此一個(gè)文件所有數(shù)據(jù)失效,只需要看該文件中最大sequenceid對(duì)應(yīng)的數(shù)據(jù)是否已經(jīng)落盤(pán)就可以,HBase會(huì)在每次執(zhí)行flush的時(shí)候紀(jì)錄對(duì)應(yīng)的最大的sequenceid,如果前者小于后者,則可以認(rèn)為該日志文件失效。一旦判斷失效就會(huì)將該文件從WALs文件夾移動(dòng)到OldWALs文件夾。4. HLog刪除:HMaster后臺(tái)會(huì)啟動(dòng)一個(gè)線程每隔一段時(shí)間(由參數(shù)’hbase.master.cleaner.interval’,默認(rèn)1分鐘)會(huì)檢查一次文件夾OldWALs下的所有失效日志文件,確認(rèn)是否可以被刪除,確認(rèn)之后執(zhí)行刪除操作。又有同學(xué)問(wèn)了,剛才不是已經(jīng)確認(rèn)可以被刪除了嗎?這里基于兩點(diǎn)考慮,第一對(duì)于使用HLog進(jìn)行主從復(fù)制的業(yè)務(wù)來(lái)說(shuō),第三步的確認(rèn)并不完整,需要繼續(xù)確認(rèn)是否該HLog還在應(yīng)用于主從復(fù)制;第二對(duì)于沒(méi)有執(zhí)行主從復(fù)制的業(yè)務(wù)來(lái)講,HBase依然提供了一個(gè)過(guò)期的TTL(由參數(shù)’hbase.master.logcleaner.ttl’決定,默認(rèn)10分鐘),也就是說(shuō)OldWALs里面的文件最多依然再保存10分鐘。HBase故障恢復(fù)三部曲HBase的故障恢復(fù)我們都以RegionServer宕機(jī)恢復(fù)為例,引起RegionServer宕機(jī)的原因各種各樣,有因?yàn)镕ull GC導(dǎo)致、網(wǎng)絡(luò)異常導(dǎo)致、官方Bug導(dǎo)致(close wait端口未關(guān)閉)以及DataNode異常導(dǎo)致等等。這些場(chǎng)景下一旦RegionServer發(fā)生宕機(jī),HBase都會(huì)馬上檢測(cè)到這種宕機(jī),并且在檢測(cè)到宕機(jī)之后會(huì)將宕機(jī)RegionServer上的所有Region重新分配到集群中其他正常RegionServer上去,再根據(jù)HLog進(jìn)行丟失數(shù)據(jù)恢復(fù),恢復(fù)完成之后就可以對(duì)外提供服務(wù),整個(gè)過(guò)程都是自動(dòng)完成的,并不需要人工介入。基本原理如下圖所示:HBase檢測(cè)宕機(jī)是通過(guò)Zookeeper實(shí)現(xiàn)的, 正常情況下RegionServer會(huì)周期性向Zookeeper發(fā)送心跳,一旦發(fā)生宕機(jī),心跳就會(huì)停止,超過(guò)一定時(shí)間(sessionTimeout)Zookeeper就會(huì)認(rèn)為RegionServer宕機(jī)離線,并將該消息通知給Master。上述步驟中比較特殊的是HLog切分,其他步驟相信都能夠理解,為什么需要切分HLog?大家都知道當(dāng)前(0.98)版本中一臺(tái)RegionServer只有一個(gè)HLog文件,即所有Region的日志都是混合寫(xiě)入該HLog的,然而,回放日志是以Region為單元進(jìn)行的,一個(gè)Region一個(gè)Region回放,因此在回放之前首先需要將HLog按照Region進(jìn)行分組,每個(gè)Region的日志數(shù)據(jù)放在一起,方便后面按照Region進(jìn)行回放。這個(gè)分組的過(guò)程就稱為HLog切分。根據(jù)實(shí)現(xiàn)方式的不同,HBase的故障恢復(fù)前后經(jīng)歷了三種不同模式,如下圖所示,下面會(huì)針對(duì)每一種模式進(jìn)行詳細(xì)介紹:LogSplittingHBase的最初階段是使用如下流程進(jìn)行日志切分的,整個(gè)過(guò)程都由HMaster控制執(zhí)行。如下圖所示:1. 將待切分日志文件夾重命名,為什么需要將文件夾重命名呢?這是因?yàn)樵谀承﹫?chǎng)景下RegionServer并沒(méi)有真正宕機(jī),但是HMaster會(huì)認(rèn)為其已經(jīng)宕機(jī)并進(jìn)行故障恢復(fù),比如最常見(jiàn)的RegionServer發(fā)生長(zhǎng)時(shí)間Full GC,這種場(chǎng)景下用戶并不知道RegionServer宕機(jī),所有的寫(xiě)入更新操作還會(huì)繼續(xù)發(fā)送到該RegionServer,而且由于該RegionServer自身還繼續(xù)工作所以會(huì)接收用戶的請(qǐng)求,此時(shí)如果不重命名日志文件夾,就會(huì)發(fā)生HMaster已經(jīng)在使用HLog進(jìn)行故障恢復(fù)了,但是RegionServer還在不斷寫(xiě)入HLog2. 啟動(dòng)一個(gè)讀線程依次順序讀出每個(gè)HLog中所有<HLogKey,WALEdit>數(shù)據(jù)對(duì),根據(jù)HLogKey所屬的Region不同寫(xiě)入不同的內(nèi)存buffer中,如上圖Buffer-Region1內(nèi)存存放Region1對(duì)應(yīng)的所有日志數(shù)據(jù),這樣整個(gè)HLog所有數(shù)據(jù)會(huì)被完整group到不同的buffer中3. 每個(gè)buffer會(huì)對(duì)應(yīng)啟動(dòng)一個(gè)寫(xiě)線程,負(fù)責(zé)將buffer中的數(shù)據(jù)寫(xiě)入hdfs中(對(duì)應(yīng)的路徑為/hbase/table_name/region/recoverd.edits/.tmp),再等Region重新分配到其他RegionServer之后按順序回放對(duì)應(yīng)Region的日志數(shù)據(jù)。這種日志切分可以完成最基本的任務(wù),但是效率極差,在某些場(chǎng)景下(集群整體宕機(jī))進(jìn)行恢復(fù)可能需要N個(gè)小時(shí)!也因?yàn)榛謴?fù)效率太差,所以開(kāi)發(fā)了Distributed Log Splitting架構(gòu)。Distributed Log SplittingDistributed Log Splitting是Log Splitting的分布式實(shí)現(xiàn),它借助Master和所有RegionServer的計(jì)算能力進(jìn)行日志切分,其中Master作為協(xié)調(diào)者,RegionServer作為實(shí)際的工作者。基本工作原理如下圖所示:1. Master會(huì)將待切分日志路徑發(fā)布到Zookeeper節(jié)點(diǎn)上(/hbase/splitWAL),每個(gè)日志作為一個(gè)任務(wù),每個(gè)任務(wù)都會(huì)有對(duì)應(yīng)狀態(tài),起始狀態(tài)為T(mén)ASK_UNASSIGNED2. 所有RegionServer啟動(dòng)之后都注冊(cè)在這個(gè)節(jié)點(diǎn)上等待新任務(wù),一旦Master發(fā)布任務(wù)之后,RegionServer就會(huì)搶占該任務(wù)3. 搶占任務(wù)實(shí)際上首先去查看任務(wù)狀態(tài),如果是TASK_UNASSIGNED狀態(tài),說(shuō)明當(dāng)前沒(méi)有人占有,此時(shí)就去修改該節(jié)點(diǎn)狀態(tài)為T(mén)ASK_OWNED。如果修改失敗,說(shuō)明其他RegionServer也在搶占,修改成功表明任務(wù)搶占成功。4. RegionServer搶占任務(wù)成功之后會(huì)分發(fā)給相應(yīng)線程處理,如果處理成功,會(huì)將該任務(wù)對(duì)應(yīng)zk節(jié)點(diǎn)狀態(tài)修改為T(mén)ASK_DONE,一旦失敗會(huì)修改為T(mén)ASK_ERR5. Master會(huì)一直監(jiān)聽(tīng)在該ZK節(jié)點(diǎn)上,一旦發(fā)生狀態(tài)修改就會(huì)得到通知。任務(wù)狀態(tài)變更為T(mén)ASK_ERR的話,Master會(huì)重新發(fā)布該任務(wù),而變更為T(mén)ASK_DONE的話,Master會(huì)將對(duì)應(yīng)的節(jié)點(diǎn)刪除下圖是RegionServer搶占任務(wù)以及搶占任務(wù)之后的工作流程:1. 假設(shè)Master當(dāng)前發(fā)布了4個(gè)任務(wù),即當(dāng)前需要回放4個(gè)日志文件,分別為hlog1、hlog2、hlog3和hlog42. RegionServer1搶占到了hlog1和hlog2日志,RegionServer2搶占到了hlog3日志,RegionServer3搶占到了hlog4日志3. 以RegionServer1為例,其搶占到hlog1和hlog2日志之后會(huì)分別分發(fā)給兩個(gè)HLogSplitter線程進(jìn)行處理,HLogSplitter負(fù)責(zé)對(duì)日志文件執(zhí)行具體的切分,切分思路還是首先讀出日志中每一個(gè)<HLogKey, WALEdit>數(shù)據(jù)對(duì),根據(jù)HLogKey所屬Region寫(xiě)入不同的Region Buffer4. 每個(gè)Region Buffer都會(huì)有一個(gè)對(duì)應(yīng)的寫(xiě)線程,將buffer中的日志數(shù)據(jù)寫(xiě)入hdfs中,寫(xiě)入路徑為/hbase/table/region2/seqenceid.temp,其中seqenceid是一個(gè)日志中某個(gè)region對(duì)應(yīng)的最大sequenceid5. 針對(duì)某一region回放日志只需要將該region對(duì)應(yīng)的所有文件按照sequenceid由小到大依次進(jìn)行回放即可這種Distributed Log Splitting方式可以很大程度上加快整個(gè)故障恢復(fù)的進(jìn)程,正常故障恢復(fù)時(shí)間可以降低到分鐘級(jí)別。然而,這種方式會(huì)產(chǎn)生很多日志小文件,產(chǎn)生的文件數(shù)將會(huì)是M * N,其中M是待切分的總hlog數(shù)量,N是一個(gè)宕機(jī)RegionServer上的Region個(gè)數(shù)。假如一個(gè)RegionServer上有200個(gè)Region,并且有90個(gè)hlog日志,一旦該RegionServer宕機(jī),那這種方式的恢復(fù)過(guò)程將會(huì)創(chuàng)建 90 * 200 = 18000個(gè)小文件。這還只是一個(gè)RegionServer宕機(jī)的情況,如果是整個(gè)集群宕機(jī)小文件將會(huì)更多!!!Distributed Log Replay該方案在基本流程上做了一些改動(dòng),如下圖所示:相比Distributed Log Splitting方案,流程上的改動(dòng)主要有兩點(diǎn):先重新分配Region,再切分回放HLog;Region重新分配打開(kāi)之后狀態(tài)設(shè)置為recovering,核心在于recovering狀態(tài)的Region可以對(duì)外提供寫(xiě)服務(wù),不能提供讀服務(wù),而且不能執(zhí)行split、merge等操作。DLR的HLog切分回放基本框架類似于Distributed Log Splitting,但它在分解完HLog為Region-Buffer之后并沒(méi)有去寫(xiě)入小文件,而是直接去執(zhí)行回放。這樣設(shè)計(jì)可以大大減少小文件的讀寫(xiě)IO消耗,解決DLS的切身痛點(diǎn)。可見(jiàn),在寫(xiě)可用率以及恢復(fù)性能上,DLR要遠(yuǎn)遠(yuǎn)優(yōu)于DLS方案,官方也給出了一個(gè)簡(jiǎn)單的測(cè)試報(bào)告:可見(jiàn),DLR在寫(xiě)可用恢復(fù)是最快的,讀可用恢復(fù)稍微弱一點(diǎn),但都比DLS好很多了解了DLR的解決方案后,再回頭看DLS的實(shí)現(xiàn)方案,就不禁要問(wèn)上一句:為什么DLS需要將Buffer中的數(shù)據(jù)寫(xiě)入小文件中?個(gè)人認(rèn)為原因最有可能是寫(xiě)入小文件之后,同一個(gè)Region的不同日志數(shù)據(jù)可以按照文件名中sequenceid由小到大進(jìn)行順序回放,完全可以模擬當(dāng)時(shí)數(shù)據(jù)寫(xiě)入的流程,不會(huì)有絲毫偏差。而如果不寫(xiě)小文件,很難在分布式環(huán)境下對(duì)sequenceid進(jìn)行排序,這里就有一個(gè)問(wèn)題,不按順序?qū)Log進(jìn)行回放會(huì)不會(huì)出現(xiàn)問(wèn)題?這個(gè)問(wèn)題可以分為下面兩個(gè)層面進(jìn)行討論:1. 不同時(shí)間更新的相同rowkey,不按順序回放會(huì)不會(huì)有問(wèn)題?比如WAL1中有<rowkey, t1>,WAL2中有<rowkey,t2>,正常情況下應(yīng)該先回放<rowkey,t1>對(duì)應(yīng)的日志數(shù)據(jù),再回放<rowkey,t2>對(duì)應(yīng)的日志數(shù)據(jù),如果順序顛倒會(huì)不會(huì)有問(wèn)題?第一眼看到這樣的問(wèn)題覺(jué)得一定不行啊,正常情況下<rowkey,t2>對(duì)應(yīng)的日志數(shù)據(jù)才是最后的真正數(shù)據(jù),一旦顛倒之后不就變成<rowkey,t1>對(duì)應(yīng)的日志數(shù)據(jù)了。這里需要關(guān)注更新時(shí)間的概念,rowkey回放時(shí),如果寫(xiě)入時(shí)間戳定義為回放時(shí)間的話,肯定會(huì)有異常的。但是如果回放日志數(shù)據(jù)的時(shí)候rowkey寫(xiě)入時(shí)間戳被定義為當(dāng)時(shí)rowkey數(shù)據(jù)寫(xiě)入日志的時(shí)間的話,就正常了。按照上面例子,順序即使顛倒,先寫(xiě)<rowkey,t2>再寫(xiě)<rowkey,t1>,但是寫(xiě)入數(shù)據(jù)的時(shí)間戳(版本)依然保持不變時(shí)t2和t1的話,最大版本數(shù)據(jù)還是<rowkey,t2>,用戶讀取最新數(shù)據(jù)依然是<rowkey,t2>,和回放順序并沒(méi)有關(guān)系。2. 相同時(shí)間戳更新的相同rowkey,不按順序回放會(huì)不會(huì)有問(wèn)題?比如WAL1中有<rowkey, t0>,WAL2中有<rowkey,t0>,正常情況下也應(yīng)該先回放前者,再回放后者,如果順序顛倒會(huì)不會(huì)有問(wèn)題?為什么同一時(shí)間會(huì)有多條相同rowkey的寫(xiě)入更新,而且還在不同的日志文件中?大家肯定會(huì)有這樣的疑問(wèn)。問(wèn)題中‘同一時(shí)間’的單位是ms,在很多寫(xiě)入吞吐量很大的場(chǎng)景下同一毫秒寫(xiě)入大量數(shù)據(jù)并不是不可能,那先后寫(xiě)入兩條相同rowkey的數(shù)據(jù)也必然可能,至于為什么在不同文件,假如剛好第一次更新完rowkey的時(shí)候日志截?cái)嗔耍诙胃戮蜁?huì)落入下一個(gè)日志。那這種情況下前后兩次更新時(shí)間戳還一致,顛倒順序就辦法分出哪個(gè)版本大了呀!莫慌,不是還有sequenceid~,只要在回放的時(shí)候?qū)⑷罩緮?shù)據(jù)原生sequenceid也一同寫(xiě)入,不就可以在時(shí)間戳相同的情況下根據(jù)sequenceid進(jìn)行判斷了。具體實(shí)現(xiàn)只需要寫(xiě)入一個(gè)replay標(biāo)示(用來(lái)表示該數(shù)據(jù)時(shí)回放寫(xiě)入)和相應(yīng)的sequenceid,用戶在讀取的時(shí)候如果遇到兩個(gè)都帶有replay標(biāo)示而且rowkey、cf、column、時(shí)間戳都相同的情況,還需要比較sequenceid就可以分辨出來(lái)哪個(gè)數(shù)據(jù)版本更大。具體可以參考這個(gè)官方j(luò)ira:https://issues.apache.org/jira/browse/HBASE-8701在0.95版本DLR功能已經(jīng)基本實(shí)現(xiàn),一度在0.99版本已經(jīng)設(shè)為默認(rèn),但是因?yàn)檫€是有一些功能性缺陷(主要是在rolling upgrades的場(chǎng)景下可能會(huì)導(dǎo)致數(shù)據(jù)丟失),又在1.1版本取消了默認(rèn)設(shè)置。用戶可以通過(guò)設(shè)置參數(shù)hbase.master.distributed.log.replay = true 來(lái)開(kāi)啟DLR功能,當(dāng)然前提是將HFile格式設(shè)置為V3(v3格式HFile引入了tag功能,replay標(biāo)示就是用tag進(jìn)行實(shí)現(xiàn)的)
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 崇义县| 穆棱市| 乐至县| 临江市| 凌源市| 襄汾县| 白城市| 满城县| 琼海市| 西乡县| 屯留县| 姜堰市| 巴中市| 庆云县| 常州市| 龙井市| 桐庐县| 连山| 温泉县| 岗巴县| 滕州市| 锡林浩特市| 土默特右旗| 香港| 龙州县| 桃园市| 明溪县| 视频| 广丰县| 阿坝| 肇庆市| 宾川县| 航空| 新宾| 嘉义市| 常山县| 庆城县| 永清县| 惠来县| 华池县| 垣曲县|