HBase運維記錄

一、前言

前面自查出過一篇HBase補充學習(一),最近算是實戰的過程中發現了一些其他的自己學習的時候尚未注意到的點,有的很簡單但是以前尚未意識到的點,有的從未學習過順便學習到的點,以此開一篇博客進行記錄。不定時更新~

二、補充內容

2.1 HBase Shell與HBase API的思想問題

遇到了一個問題,在程序端已經實現通過API查看HBase表,但有一個需求需要去回到命令行進行查看,但是擁有的信息是表名、列族名和列名和一個value值,需要對value爲依據進行模糊查詢,在API中使用SingleColumnValueFilter過濾器完成,但如何在Shell中實現想了好久,一度以爲Shell不支持過濾器以及單值過濾、通配符、模糊查詢等等

真的是個很低級的意識錯誤,試想API的產生就是爲那些不習慣操縱命令行的人員提供便利,實際上就是對Shell命令的一個封裝,執行API實際上底層也是執行Shell命令,那麼既然API支持的東西在Shell命令中自然也是支持的,於是進行一番查找,果真是有的。這是一個意識錯誤,值得記錄。

//API操作
SingleColumnValueFilter filter =
                    new SingleColumnValueFilter(Bytes.toBytes(column_family_name), Bytes.toBytes(column_name), CompareOperator.EQUAL, Bytes.toBytes(value));

//Shell命令
scan 'table_name',{FILTER=>"SingleColumnValueFilter('cf_name','cq_name',=,'substring:value')"}

舉個例子,hbase_test表中有一個f列族,列族中有placeno和devmac兩個列,現在對devmac使用單列值過濾器,將所有demac值子串中含有3524子串的行輸出,語法如下,結果可以看到過濾器使用成功,將所有包含3524的row1和row2輸出(值得注意的是輸出的是符合條件的所有的行的所有列,如row1行把placeno也輸出了)這個單值過濾器很好用,適用於只瞭解單列值的情況下對錶進行過濾掃描出符合條件的所有數據。

再加一個與正則表達式匹配,順便學習正則語法:https://www.runoob.com/regexp/regexp-syntax.html

^單純表示正則表達式的開頭,*表示前面的那個字符可沒有可有一次可有多次,所以下圖第一句是匹配所有子串至少存在3524的數據,第二句是匹配所有子串至少存在35245的數據。

2.2 HBase數據輸出文本格式問題

有一個需求是需要hbase scan掃描的結果輸出到文本格式方便查看,百度搜索使用echo命令完成,過程中遇到一個小問題值得記錄,echo中如果scan命令使用到了""需要使用轉義字符,否則echo會報錯。

如下圖,在linux命令行中輸入echo命令,將scan的結果輸出到myTest.txt中:

echo "scan 'hbase_test',{FILTER=>\"SingleColumnValueFilter('f','devmac',=,'substring:3524')\"}" | ./hbase shell > myTest.txt

查看導入scan結果的myTest.txt:可以發現結果是會顯示hbase的進入shell命令、版本、scan命令以及scan結果。

如果沒有使用轉義符,會提示bash: syntax error near unexpected token `('

嘗試過將FILTER後的SingleColumnValueFilter雙引號改爲單引號,echo命令執行成功,但是最後生成的txt文件會顯示scan命令有誤。(有誤的原因是scan的FILTER讀不出單引號下的SingleColumnValueFilter)

2.3 短暫性RIT問題

項目中HBase運行的時候通過網頁監控查看到很多table所在的onlineregion爲0,也即所在的region沒上線,但這個時候hbase集羣中的所有regionserver實際上都是正常上線的,區別是每個regionserver上的region數相比之前大大減少,在Web界面可看到的是有一部table屬於RIT狀態(Region In Transition空洞狀態),發現上述有些onlineregion爲0的表所在的region都處於RIT狀態,需要解決region的RIT狀態(長期處於RIT狀態,將影響數據的讀取)。另外發現一點就是這些region都正處於PENDING_OPEN狀態,如何解決這個問題?

實際上這個要回歸於HBase Region的split和compact機制(參考HBase補充學習(一)region切分和合並部分),在region分割之後,子region和父region間,查子region的數據實際上是子region通過reference文件找到父region對應的hfile查找,只有當compact的時候會將hfile中的數據轉移到子region對應的hfile中,再定期去刪除reference。而region在上線是會經歷pending-open、opening最後到open狀態表明完成上線(close過程參考http://hbasefly.com/2016/09/08/hbase-rit/),Web頁面上可見region處於pending-open狀態,說明region在上線的過程中出現了問題,使用HBase提供的hbck工具(檢查.META.表,hbase hbck命令)來檢查hbase集羣的數據一致性問題(以region爲單位進行一致性檢查)。

更多使用方法可參考:https://www.zhyea.com/2017/07/29/hbase-hbck-usage.html

                                    https://blog.csdn.net/oppo62258801/article/details/84246409

首先在hbase/bin下使用hbase hbck 'table_name'查看該表所在region的運維日誌,根據日誌排查處於pending-open的原因,經過排查發現是查不到reference文件,

這個時候有兩種可能性。第一種排查子region對應的父region還在不在(在hdfs目錄下查看),如果不在則直接刪除reference文件(說明此時子region已經有了分割繼承的數據,但最好還是備份一下reference以免誤判)並使用assgin 'sub_region'重新上線子region;第二種如果父region還在(一定不要刪Reference!此處切記切記一定不要相信網站上一搜ERROR:Found lingering reference file前幾篇超級雷同文章的第二方案選擇刪除reference,要是刪了老哥們就找不到數據了,可能解決的方法就是憑記憶/.META.找到父region然後重新分割或者父region到子region數據賦值?千萬別輕易刪東西!!),使用命令hbase -hbck -fixReferenceFiles 'table_name'修復,如果還不行使用hbase -hbck -fixAssignments 'table_name'重新分配region。(實際上這個hbase機制有關,可能等它自己更新compact一下就可解決,但是如果長期是處於RIT,就得用用hbck工具查查哪出了問題,根據打印日誌中的ERROR去排查解決問題)

後面可能是等待了一會hbase自動給好了,初步猜測可能是比較巧的遇到了hbase region上線的時期(hbase自帶hbck功能,碰巧親眼遇到了短暫的RIT,以爲是永久RIT所以去進行了排查...不過也慶幸是短暫RIT)

解決問題參考鏈接:https://blog.csdn.net/lvwenyuan_1/article/details/78579116

解決這個問題的感悟:遇到甲方的問題先往簡單的錯誤上排查,別輕易給自己加難度。就拿這個RIT問題來講,首先得有RegionServer啓動後其上的Region是慢慢啓動的基本認知,這個啓動過程並非一蹴而就,啓動過程中需要經歷pending-open、opening和ope狀態,那麼很有可能在某個過程去看恰好遇到一部分region正處於啓動狀態,所以首先可以讓等5-10分鐘再進行查看,看看是否RIT有減少,如果有說明確實剛剛是遇到短暫RIT了,如果沒有或者還有增加那麼就需要擼起袖子用上hbck進行排查了。(同時還有一點注意到Web頁面上的一些時間很重要,可以獲得他是啥時候啓動的關鍵點,要是早點看到或許可以早些聯想到現在集羣正處於啓動排列期,人很有可能是查看剛好遇到了region排列等待open時期)

2.4 永久性RIT問題

說來也巧,2.3遇到region短暫處於狀態轉移rit以爲是出現了問題進行排查,後續發現只是恰好碰到hbase中region短期切分region狀態轉變處於短期region in transition(遷移狀態),region遷移之後即會恢復正常。

HBase中region會因爲切分、合併、上線、下線等都需要時間而存在短期的rit、空洞、不一致等,只要是短期那麼就是正常的。但是如果處於長期RIT,那麼一定是有問題了,且這個問題需要人爲排查定位干預解決,不然會影響hbase正常的使用。最近就遇到幾個region處於永久RIT的問題了,也算是費了不少時間去研究,學到了不少東西,在此進行記錄。

確保.META.、table、hdfs保持一致,以下爲上面思路的具體執行過程記錄。

1. 一開始是查看HBase的60010web頁面,發現有三個region處於RIT狀態,以爲是2.3問題正好碰見region遷移,示意等待5-10mins後再進行查看,但是到時間了甲方也多次重啓HBase,這三個region依舊處於RIT狀態,基本確定是出問題了,永久RIT問題。

2. 使用hbck工具,定位具體的error,但是由於數據庫的表很多,然後也有region可能處於短暫rit狀態,導致hbck中很多region都有問題(空洞、表不一致、region chain有問題等等),讓人無從下手產生恐懼心理。

3. 後續查閱資料確定較爲明確的排查路線,使用hbase hbck 'table_name'精準定位排查一張表的問題,發現是meta上沒有regioninfo,使用相關的修復命令沒用,所以手動去hbase shell中scan .META.表想要查看是否有這個region,如果沒有則使用hbase hbck -fixMeta(刪除HDFS沒有.META.有的,添加HDFS有但是.META.沒有的regioninfo)但是沒用。執行hbck沒用的時候就需要手動去.META.、HDFS查人工對比進行分析修復

4. 後續想刪除zookeeper底下的/hbase/region-in-transition節點然後重啓hbase重新assign region,但是./hbase zkcli好不容易進入zookeeper shell(這裏真的是挺不好意思的,因爲使用的是hbase自帶的zookeeper,一時竟不知道咋進入zookeeper shell),ls /hbase發現沒有這個節點(這個就很迷,網上資料基本都是有這個節點,我的就沒有??),有一個/hbase/unassigned節點,打開發現就是rit狀態的region,手動刪除重啓hbase,結果沒用。

5. 由於對問題排查方法的不夠精確(沒有具體到表)以及對基本操作命令的不熟悉(hdfs、hbase、zookeeper)導致前面浪費了很多時間,最後也是嘗試了hbck常見的修復命令沒用,後面聯想到這個數據本身只是表示某一天的數據,不影響全局,就直接在hbase shell執行disable 'table_name'禁用掉表,問題算是解決了吧。如果後續出現插入數據找不到表的問題(因爲業務中有同步數據到HBase的部分),就直接將這三個表delete掉,程序重新創建表插入數據即可。

此處將用到的知識進行總結:

1. HBase region狀態轉換機制:https://www.cnblogs.com/zackstang/p/9965920.html 正常情況下由於region的assign、unassign、split、merge等操作都需要時間而且隨時都有可能發生,只要發生就意味着此時這個region處於遷移狀態,直觀來講就是這個region在web頁面在region-in-transitiion模塊中。所以遇到RIT不要怕,先等上一會看是否是短暫的rit;如果不是那麼定位問題分析問題解決問題

2. HBase hbck檢查維修工具的常用命令:https://www.zhyea.com/2017/07/29/hbase-hbck-usage.html 一般情況使用hbck最好定位到某一張可以確定有問題的表,節約時間提高效率並且避免遇到短暫RIT的region混淆視聽影響判斷。常用的命令hbck 'table_name'查看分析問題,根據日誌中的ERROR定位問題;hbck -fixAssignments 'table_name' 重新分配region;hbck -fixMeta修復.META.數據表中的regioninfo等信息;hbck -repair多種命令的混合體,一般生產環境少用(未知效果未知操作不要做)

3. HDFS文件的常用命令:https://blog.csdn.net/majianxiong_lzu/article/details/89174176 這裏需要聲明的一個就是運行命令都最好去bin目錄下,使用 ./XXXX來執行(如果有配系統環境,那隨意目錄都可)常用命令./hadoop fs -ls /xxx查看HDFS文件中xxx目錄結構;./hadoop fs -rm /xxx/xxx刪除HDFS文件中的xxx文件 ./hadoop fs 基本等同於 ./hdfs dfs 後面直接加相應的命令即可(1.x開頭的貌似都是hadoop,2.x開始開始使用hdfs dfs替換hadoop fs。使用的時候就試,hdfs dfs不適用了就回去用hadoop fs)【個人習慣使用./hadoop fs】

4. Zookeeper的常用命令:https://www.cnblogs.com/jifengblog/p/9263817.html 若使用HBase自帶的Zookeeper,進入shell使用hbase/bin/hbase zkcli;若使用外置的Zookeeper,進入shell在zookeeper的bin目錄下使用 ./zkCli.sh -server localhost:2181。常用命令 ls /xxx查看xxx下的所有子節點;rmr /xxx刪除xxx目錄;delete /xxx刪除xxx節點

5. 修復hbase的時候注意一般的hbck命令都是在線模式修復的,因此無需重啓hbase。此處參考https://www.liangzl.com/get-article-detail-19242.html

6. linux終端中將運行結果打印到文本中有三種方法,具體可參考https://blog.csdn.net/zhangping1987/article/details/83179837

這裏聯想到Linux集羣配置SSH的時候將集羣中所有節點的密鑰追加到同一個文本文檔,然後分發到所有的節點實現免密登錄。(只要能ping通就算一個小集羣)【很多東西用的時候沒有注意沒有深入思考,等問到的時候還以爲自己沒見過(之前被問到過linux下如何將程序運行結果打印到日誌中,一時卡殼回答不上來簡直菜雞),所以還得多思多想,以問題爲索引多多學習多多總結】

7. 排查過程中由於多次使用hbck工具,這個命令使用會分配一個hbase-hbck.lock鎖,如果hbck命令正常結束那麼鎖會自動釋放掉,其他命令可以直接使用;但是如果hbck命令被手動終止,那麼這個命令無法執行鎖也沒有釋放,其他hbck命令由於無法拿到資源也無法運行,解決方法就是手動刪除釋放掉這個鎖。方法 ./hadoop fs -rm /hbase/.tmp/hbase-hbck.lock

8. 命令有很多,靠腦子記是很容易忘的,所以一個方法是收藏總結比較全面的命令大全博客,另一個方法就是學會使用-help查看支持的相關命令然後根據需要進行選擇

9.  幾個比較好的HBase維護參考網址:

https://www.sohu.com/a/252429305_315839

http://blog.sina.com.cn/s/blog_7b87efa50102wboj.html

https://blog.csdn.net/yongjian_luo/article/details/53375809

https://www.jianshu.com/p/d5697506741e

另外有的經驗教訓總結就是有問題先調研分析,確立一個基本的排查思路和備案;排查過程中對於不確定的常用命令,先百度查清楚確定好以後讓甲方執行,節約交互時間(不確定不熟悉的東西就要去查,如果是自己一個人那可以去試,但是如果有交互那麼要完全確定好後再交互);如果一兩天問題還沒解決,爲了趕緊解決問題不耽誤進程並且這個數據並不影響整體就當是壞數據好了,直接暴力刪除解決問題。

2.5 刪除hbase表問題

運行一個程序,其中一個作用是定期去清理HBase中生命週期大於某些天的表,但是有幾個表刪除的時候會報錯,顯示table disabled。

問題分析:2.4的時候爲了解決RIT問題暴力disable掉了幾張表,於是猜測是這幾張表導致報錯(系統要刪disable狀態的表刪不掉,就手動刪除掉了之前disable的表。

徹底刪除表的過程:(暴力方法主要是刪除HDFS和Zookeeper下的表信息)

但是發現問題還是存在,於是仔細看了下日誌(此處爆錘自己太想當然了)發現是disabled狀態的另有其表。本來這個程序就是drop掉表的,不管他是不是disable狀態只要把它刪除了就成。相比每次根據報錯信息取hbase drop掉表或者去HDFS和Zookeeper中rmr表目錄而言,修改程序來得更容易也更正確。方法很簡單在drop table的相關代碼中先判斷表是否爲disable,是則delete,不是則先disable再delete。

//如果表enabled,則先disable再delete,否則直接delete(已經處於disable狀態了直接delete即可)
if(!getHbaseAdmin().isTableDisabled(tableName)){
    //不是disable則先disable
    getHbaseAdmin().disableTable(tableName);
}
    getHbaseAdmin().deleteTable(tableName);

程序邊界異常處理真的真的很重要!!!編碼的時候多考慮考慮異常處理,讓程序更健壯。

2.6 HBase的master啓動失敗

集羣物理機重啓,重啓啓動hadoop、hbase但是發現hbase啓動失敗。web頁面打不開,集羣各個節點jps查看進程發現主節點的hmaster沒有,重啓hadoop、hbase都不解決問題。查看主節點的日誌發現報錯:

java.io.IOException: error or interrupted while splitting logs in [hdfs://xxxxxxx-splitting] Task = installed = 1 done = 0 error = 1

at org.apache.hadoop.hbase.master.SplitLogManager.splitLogDistributed(SplitLogManager.java:299)

at org.apache.hadoop.hbase.master.MasterFileSystem.splitLog(MasterFileSystem.java:371)

at org.apache.hadoop.hbase.master.MasterFileSystem.splitAllLogs(MasterFileSystem.java:341)

at org.apache.hadoop.hbase.master.MasterFileSystem.splitAllLogs(MasterFileSystem.java:288)

at org.apache.hadoop.hbase.master.HMaster.finishInitialization(HMaster.java:627)

at org.apache.hadoop.hbase.master.HMaster.run(HMaster.java:433)

at java.lang.Thread.run(Thread.java:748)

分析原因:zookeeper沒問題,可能是hdfs塊數據有問題,查看hadoop的web頁面發現warning:有missing blocks證實可能是由於hdfs數據塊丟失導致hbase無法正常啓動(meta表的regioninfo不正常、表的數據塊丟失等問題)

解決方法:參考https://blog.csdn.net/qq_34901049/article/details/101079510

1. ./hadoop fsck -list-corruptfileblocks丟失損壞(corrupt)的塊的路徑,並且查看這個path是否爲CORRUPT,如果是則不正常

2.1 ./hadoop debug recoverLease -path <path> -retries num嘗試手動修復

2.2 若數據塊可以考慮刪除/修復無效,執行./hadoop fsck <path> -move/delete移動corrupt的塊到/lost+found目錄下,然後刪除(如果沒有備份的話會徹底刪除)

2.3 執行./hadoop fsck <path>查看發現path爲HEALTHY,說明corrupt修復/刪除後hdfs數據塊正常。重啓hbase解決問題。

對於HDFS數據塊損壞/丟失,支持手動修復和自動修復,只是自動修復有一定的時間差(據網上資料說是6小時左右開始自動修復),一般生產環境中傾向於手動修復儘快恢復HDFS正常,確保其他業務正常運行(測試環境中一般數據不重要的話也可以直接刪除損壞塊)。

對於查看/操作hdfs文件的命令,老版本Hadoop使用hadoop,新版本使用hdfs。hdfs的fsck工具使用參考:https://www.cnblogs.com/xubiao/p/5757603.html

總結

學習就是這樣吧。看山是山 到 看山不是山 到 看山還是山。路漫漫其修遠兮,吾將上下而求索。

明確知識是不可能短時間內學完的,接受任何對於原知識的衝擊,及時補充,及時修正,及時跟進,及時記錄,相信勤能補拙。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章