目錄結構
1. 前言java
2. BulkLoad 致使數據無限膨脹node
3. 刪表超時致使 RITweb
4. 從新規劃 Import 的流程apache
5. 總結centos
1. 前言
Hadoop 集羣的 DataNode 節點嚴重不均衡,某些節點的磁盤空間佔用逼近百分之百,眼看着立刻就要爆掉了。bash
雖然這些 DataNode 節點同時也是 HBase 集羣的 RegionServer,但一開始還真沒把磁盤的這種異常現象與 HBase 的活動聯繫起來。隨後經過查看 HDFS 的日誌,咱們才進一步肯定了 HBase 的某一個 RegionServer 此時正發生着大量的寫入操做。DataNode 日誌信息大體以下:微信
![](http://static.javashuo.com/static/loading.gif)
從日誌中能夠看到,HDFS_WRITE 操做的一個 client id 正指向發生異常的那個 DataNode 節點(也即 RegionServer)。其實,在這段時間內,Hadoop 集羣上的大 HBase 集羣一直在進行着數據同步操做,線上 HBase 集羣的表經過 Export/Import 的方式同步進大 HBase 集羣,以後,這個大 HBase 集羣將做爲災備集羣服務於線上的業務。編輯器
爲了提升 Import 階段 MR 任務的運行效率,咱們改變 Import 時以 HBaseClient 的方式寫入集羣,而是先用 Import 工具在臨時目錄中生成每一個表的 HFile,最後再使用 BulkLoad 的方式實現快速的數據導入。然而,一系列異常的情況正是發生在 HFIle BulkLoad 的階段。函數
2. BulkLoad 致使數據無限膨脹
在肯定是 HBase 的問題以後,咱們重點排查了正在進行的數據同步流程。Import 的 MR 任務完成以後,HFIle 在臨時目錄中生成。目錄中 HFIle 的文件結構以下圖所示:工具
![](http://static.javashuo.com/static/loading.gif)
接着使用 BulkLoad 的命令快速導入數據,對於數據量比較小的表,命令很快就執行成功了,數據也很快加載完畢,並且數據是完整的,只是讓咱們感到奇怪的一點是,BulkLoad 的命令運行結束後,臨時目錄中生成的 HFIle 一點也沒有減小。
在以前 hive to hbase 的數據同步流程中,咱們一樣是用 Spark 程序先把 hive 錶轉換成 HFile,而後用 BulkLoad 的方式導入 HFile,整個流程結束後,臨時目錄爲空,看起來好像是 BulkLoad 的命令作了 Move 操做,把生成的 HFile 直接移動進了 HBase 的數據目錄/hbase/data/table
中,整個過程對 HBase 的影響微乎其微。
這兩種方式生成的 HFile 究竟有何異同,目前咱們尚未深刻研究,而是放在了以後的計劃之中。隨後,在繼續同步幾張數據量比較大的表的時候,BulkLoad 命令執行過程當中打印了以下警告信息:
![](http://static.javashuo.com/static/loading.gif)
[2020-07-09 05:23:23,452] {bash_operator.py:120} INFO - 20/07/09 05:23:23 INFO client.RpcRetryingCaller: Call exception, tries=16, retries=35, started=1190177 ms ago, cancelled=false, msg=row 'TMofTtwC4hkHMY6Lq0QKew==' on table 'PERSON_INFO:CELL_PERSON_INFO' at region=PERSON_INFO:CELL_PERSON_INFO,TMofTtwC4hkHMY6Lq0QKew==,1594205285703.24c827308174f7ec321180ff59038072., hostname=rs-host,60020,1594199016949, seqNum=2
[2020-07-09 05:23:23,452] {bash_operator.py:120} INFO - 20/07/09 05:23:23 WARN ipc.CoprocessorRpcChannel: Call failed on IOException
[2020-07-09 05:23:23,453] {bash_operator.py:120} INFO - java.net.SocketTimeoutException: callTimeout=1200000, callDuration=1210221: row 'TMofTtwC4hkHMY6Lq0QKew==' on table 'PERSON_INFO:CELL_PERSON_INFO' at region=PERSON_INFO:CELL_PERSON_INFO,TMofTtwC4hkHMY6Lq0QKew==,1594205285703.24c827308174f7ec321180ff59038072., hostname=rs-host,60020,1594199016949, seqNum=2
[2020-07-09 05:23:23,453] {bash_operator.py:120} INFO - at org.apache.hadoop.hbase.client.RpcRetryingCaller.callWithRetries(RpcRetryingCaller.java:169)
看起來像是 bulkload 超時,而程序依舊在執行,不會被中斷,並且這張表的數據目錄持續膨脹,原本 100 多 G 的數據,bulkload 命令運行半小時以後,居然膨脹到好幾個 T,有些表運行了一夜膨脹到了幾十個 T。查看 HBase 的底層數據目錄,發現這些表底層 HFile 的存儲格式貌似也有些不太正常。
![](http://static.javashuo.com/static/loading.gif)
數據表的 hfile 多了好多_Seq 之類的後綴,且這些文件愈來愈多,不知道什麼時候纔會中止。到了這裏,上文描述的某一個 DataNode 磁盤空間佔用異常就是這樣的文件引發的。對一個 RS 節點產生了這麼大影響,當時還覺得是預分區過少或沒有給表預分區的緣故,繼而致使出現了大量的寫入熱點。後來又根據表的實際數據量,對錶作了從新的預分區操做,可 Import 的過程當中依舊會出現這樣的狀況。
目前爲止,尚未找到一個合理的解釋來完美說明爲何會出現這樣的狀況。
3 刪表超時致使 RIT
針對那些數據量異常的表,在沒找到最合適的解決辦法以前,只能優先刪除,避免撐爆磁盤。Import 成 HFIle 再 Bulkload 數據的方式,貌似也不太靠譜,只能從新以默認方式進行 Import 操做。
就在刪除數據同步過程當中數據量異常的表時,disable 的命令卡在了客戶端遲遲沒法返回響應結果,最後拋出相似操做超時的異常。在集羣監控頁面上能夠看到 disable 的 Procedures 一直在運行。
disable 的命令卡住:
監控界面上的 disable Procedures 持續在運行:
因爲數據量異常的大,disable 的耗時過長,觸發了客戶端的操做超時,命令自動中斷。此時,黔驢技窮了。看起來只能重啓集羣了,咱們也正是這樣作的。而 RIT 正是在此過程當中發生,重啓集羣的過程當中 CDH 界面上 Master 進程飆紅。CDH 的 Master 進程因爲 RIT 的存在而沒法正常啓動。
在 HBase 自帶的監控界面上能夠看到發生 RIT 的表的信息。
發生 RIT 的表也是上一個刪除操做中超時的數據量異常的表,至於 RIT 發生的根本緣由,直至如今也不明其理,只知道上述的種種不正常的操做和表現出來的現象,致使了這個異常。
咱們嘗試用hbase hbck
命令來試圖修復損壞的 Region。首先運行hbase hbck 待操做表名
的命令來查看當前表的總體狀態。並摘取 ERROR 的日誌信息。
ERROR: Region { meta => ENTCARD:表名,,1591256713254.77eb283b4525e8ce2f0bcf5d27803927., hdfs => hdfs://hdfs-service/hbase/data/ENTCARD/表名/77eb283b4525e8ce2f0bcf5d27803927, deployed => , replicaId => 0 } not deployed on any region server.
20/07/07 21:57:49 INFO util.HBaseFsck: Handling overlap merges in parallel. set hbasefsck.overlap.merge.parallel to false to run serially.
ERROR: There is a hole in the region chain between and . You need to create a new .regioninfo and region dir in hdfs to plug the hole.
ERROR: Found inconsistency in table ENTCARD:表名
從中進一步獲得具體的 ERROR: There is a hole in the region chain between and . You need to create a new .regioninfo and region dir in hdfs to plug the hole 的提示信息,該表出現了 Region 空洞,也就是出現了 start key 和 end key 不連續的 region。
關於 region 空洞的修復,hbase hbck
的使用文檔中描述的很詳細,運行下 hbase hbck -repairHoles 表名
。
大體說明下該命令的具體做用,也即修復範圍。hbase hbck -repairHoles 至關於-fixAssignments -fixMeta -fixHdfsHoles -fixHdfsOrphans 這四個參數同時生效。
-
-fixAssignments 用於修復 Region 分配錯誤 -
-fixMeta 用於修復.META.表的問題(前提是 HDFS 上的 region 信息是正確的) -
-fixHdfsHoles 修復 RegionHoles 的問題 -
-fixHdfsOrphans 修復 Orphan Region(HDFS 上沒有.regioninfo 的 Region
等待命令運行結束後,再一次使用 hbase hbck 待修復的表名
命令來查看集羣的狀態。在輸出信息的末尾,若是你看到一個大大的 OK,那就證實這次修復是成功的,觀察 HBase 的集羣監控界面,原有 RIT 的錯誤提示消失不見,集羣恢復健康,此時運行重啓命令,集羣順利重啓,以前超時的 disable 操做的 Procedures 也消失了,而後就能夠成功刪除那個異常的表了。
異常的表其實有好幾張,以後的刪除操做中一樣遇到了超時卡住的問題和 RIT,針對後續的 RIT,使用hbase hbck 表名
獲得的異常信息並不都是 RegionHoles。不同的狀態異常以下:
ERROR: Region { meta => person_info:person_info_encrypt,,1591256723291.80e182837f515bfd18c68bd845320875.,
hdfs => hdfs://hdfs-service/hbase/data/person_info/person_info_encrypt/80e182837f515bfd18c68bd845320875,
deployed => centos-bigdata-datanode-ip-.internal,60020,1594127519656;person_info:person_info_encrypt,,1591256723291.80e182837f515bfd18c68bd845320875., replicaId => 0 }
should not be deployed according to META, but is deployed on bigdata-datanode-ip,60020,1594127519656
should not be deployed according to META, but is deployed on 再運行 hbase hbck 的修復命令,提示信息以下:
意思是一個 region close 的關閉任務已經在運行,不能重複提交。
那就只能先重啓了,disable 的 Procedures 終止,把這張 RIT 的表直接刪掉。
4. 從新規劃 Import 的流程
刪除掉那些數據量異常的表後,DN 節點的磁盤空間被釋放,磁盤的壓力也隨之消失。原有 Import 成 HFile 再 Bulkload 的方案不能繼續用了,只能使用 Import 的默認方式,走 hbase-client API 來寫入數據。這種方式寫入數據的速度雖然慢,但總不至於引發這樣的匪夷所思的異常。
使用 Import 默認的數據導入方式時,還須要注意一個點。對於數據量大的表,建立表時要進行合理的預分區。若是不進行表的預分區操做,數據導入時極大可能會引發寫入熱點,嚴重影響數據的讀寫效率,在極端狀況下甚至致使集羣的服務掛掉。上述全部操做準備穩當以後,從新調度 Export、Import 的遷移腳本,數據開始穩定導出並寫入災備集羣,並且效率也不是很慢。
5. 總結
以上內容林林總總記錄了咱們這次跨大版本數據遷移過程當中遇到的種種問題,文字的力量或許還不足以讓咱們百分之百重現當時的細枝末節。這裏也只是記錄了一個大概的過程,中間也遺留了不少亟待解決的問題。
在以往 HBase 的使用經歷中,各個場景下的 HBase 的數據遷移,咱們幾乎都有碰見過。升級 2.1 時候老 HBase 集羣同步數據到新集羣,主備新集羣之間的數據同步,新集羣到大 Hadoop 災備 HBase 集羣間同步數據,HIve 大批量離線數據同步到 HBase 集羣等等,所依賴的大部分命令其實都源自 HBase 內置的工具命令。但在具體的實施過程當中,又會遇到各類各樣的問題,版本兼容問題,同步效率、穩定性、流程標準化、自動化調度等等。
其實瞭解一個工具的使用,最簡單有效的方式就是深刻源碼,在入口函數裏你能夠找到命令使用的傳參細節,在流程代碼裏你能夠剖析工具實現的底層原理,而後是全面而深刻的測試,不要忽略細枝末節,甚至在必要時把源碼貼出來進行簡單的擴展和包裝,最後造成一個標準化的解決流程。
聽說,關注個人人都找到了對象👇
![](http://static.javashuo.com/static/loading.gif)
本文分享自微信公衆號 - HBase工做筆記(HBase-Notes)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。