技術實踐-HBase增量數據遷移的方法

      網友投稿 1050 2025-04-01

      概覽


      ● 本文主要是想談一下如何給HBase做增量數據的遷移,也就是遷移實時數據。在之前的博文HBase實用技巧:一種全量+增量數據的遷移方法-云社區-華為云 (huaweicloud.com)中提到HBase增量數據遷移可以使用Replication的方式去做,但是在實際搬遷時,要給原集群設置Replication可能需要重啟,這樣會影響業務,我們需要做到不停機遷移才行。

      WAL原理

      正常情況下,HBase新增的數據都是有日志記錄的,數據在落盤成HFile之前,任何一個Put和Delete操作都是記錄日志并存放在WALs目錄中,日志中包含了所有已經寫入Memstore但還未Flush到HFile的更改(edits)。

      默認情況下每個RegionServer只會寫一個日志文件,該RS管理的所有region都在向這一個日志文件寫入Put和Delete記錄,直到日志文件大小達到128MB(由hbase.regionserver.hlog.blocksize設置)后roll出一個新的日志文件,總共可以roll出32個日志文件(由hbase.regionserver.maxlogs設置)。

      如果日志文件未寫滿128MB,RegionServer間隔1小時也會roll出新一個新日志文件(由hbase.regionserver.logroll.period設置)。

      當日志文件中涉及的所有region的記錄都flush成HFile后,這個日志文件就會轉移至oldWals目錄下歸檔, Master沒間隔10分鐘(hbase.master.cleaner.interval)會檢查oldWALs目錄下的過期日志文件,當文件過期時會被Master清理掉,(日志過期時間由hbase.master.logcleaner.ttl控制)。

      RegionServer默認間隔1小時(由hbase.regionserver.optionalcacheflushinterval設置)會對它管理的region做一次flush動作,所以WALs目錄中一直會有新的日志文件生成,并伴隨著老的日志文件移動到oldWALs目錄中。

      遷移方式

      一、遷移oldWALs目錄中的文件,使用WALPlayer回放

      由于日志文件文件最終移動到oldWALs目錄下,只需要寫個腳本,定時檢查oldWALs目錄下是否有新文件生成,如果有文件,則move至其他目錄,并使用WALPlayer工具對這個目錄進行回放。

      優點:無代碼開發量,僅需腳本實現

      缺點:無法做到實時,因為從數據寫入到最后到達oldWAL目錄會間隔很長時間。

      二、開發獨立工具,解析日志文件,寫入目的集群

      在網上查找遷移方法的時候了解到了阿里開發了一個專門的HBase遷移工具,可以實現不停機。通過閱讀其設計BDS - HBase數據遷移同步方案的設計與實踐了解到阿里開發了應用去讀取HBase的WAL日志文件并回放數據至目的集群。

      優點:可以做到實時;

      缺點:需要一定的代碼開發量;

      要做出這樣一個工具,需要了解上面說的WAL文件歸檔的原理以及日志回放工具WALPlayer,下面簡單說一下可以怎么去實現。

      獨立工具實現

      這里簡單說明下如何去做這樣一個工具,只介紹讀取WAL方面,任務編排就不描述了

      定時掃描WALs目錄獲取所有的日志文件,這里按ServerName去分組獲取,每個分組內根據WAL文件上的時間戳排序;

      ● 獲取所有RS的ServerName

      ClusterStatus clusterStatus = admin.getClusterStatus(); Collection serverNames = clusterStatus.getServers();

      ● 根據ServerName去組成Path獲取日志

      Path rsWalPath = new Path(walPath, serverName.getServerName()); List hlogs = getFiles(fs, rsWalPath, Long.MIN_VALUE, Long.MAX_VALUE);

      ● getFiles()參考HBase源碼中WALInputFormat.java中的實現,可以指定時間范圍去取日志文件

      private List getFiles(FileSystem fs, Path dir, long startTime, long endTime) throws IOException { List result = new ArrayList(); LOG.debug("Scanning " + dir.toString() + " for WAL files"); FileStatus[] files = fs.listStatus(dir); if (files == null) return Collections.emptyList(); for (FileStatus file : files) { if (file.isDirectory()) { // recurse into sub directories result.addAll(getFiles(fs, file.getPath(), startTime, endTime)); } else { String name = file.getPath().toString(); int idx = name.lastIndexOf('.'); if (idx > 0) { try { long fileStartTime = Long.parseLong(name.substring(idx+1)); if (fileStartTime <= endTime) { LOG.info("Found: " + name); result.add(file); } } catch (NumberFormatException x) { idx = 0; } } if (idx == 0) { LOG.warn("File " + name + " does not appear to be an WAL file. Skipping..."); } } } return result; }

      對于取到的每一個WAL文件,當做一個任務Task執行遷移,這個task主要有下面一些步驟

      ● 使用WALFactory為每個日志文件創建一個Reader

      WAL.Reader walReader = WALFactory.createReader(fileSystem, curWalPath, conf);

      ● 通過Reader去讀取key和edit,并記錄下position,為了加快寫入速度,這里可以優化為讀取多個entry

      WAL.Entry entry = walReader.next(); WALKey walKey = entry.getKey(); WALEdit walEdit = entry.getEdit(); long curPos = reader.getPosition();

      ● 記錄position的目的是為了Reader的reset以及seek,因為這個原始WAL文件還正在寫入的時候,我們的Reader速度很可能大于原WAL的寫入速度,當Reader讀到底的時候,需要等待一段時間reset然后再重新讀取entry

      WAL.Entry nextEntry = reader.next(); if (nextEntry == null) { LOG.info("Next entry is null, sleep 10000ms."); Thread.sleep(5000); curPos = reader.getPosition(); reader.reset(); reader.seek(curPos); continue; }

      技術實踐-HBase增量數據遷移的方法

      ● 在讀取WAL的過程中很可能會遇到日志轉移到oldWALs目錄下,這個時候捕獲到FileNotFoundException時,需要重新生成一個oldWALs目錄下Reader,然后設置curPos繼續讀取文件,這個時候如果再次讀取到文件最后的時候,就可以關閉Reader了,因為oldWALs中的日志文件是固定大小的,不會再有追加數據。

      這里需要注意的是這個參數hbase.master.logcleaner.ttl不能設置過小,否則會出現這個在oldWALs目錄下的日志文件還沒讀取完被清理掉了。

      Path oldWALPath = new Path(oldWalPath, walFileName); WAL.Reader reader = WALFactory.createReader(fileSystem, oldWALPath, conf); reader.seek(curPos)

      ● 根據通過WAL.Reader可以讀取到walKey,walEdit進而解析出Cell并寫入目的集群,這個可以參考WALPlay的map()方法

      EI企業智能 HBase 數據遷移 智能數據 表格存儲服務 CloudTable

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:IMLOG2(imlog2函數)
      下一篇:如何制作甘特圖表 - 從零開始學習制作甘特圖表
      相關文章
      亚洲国产一区视频| 亚洲国产精品网站在线播放| 亚洲精品又粗又大又爽A片| 亚洲欧洲自拍拍偷综合| 亚洲日本中文字幕| 亚洲AV无码精品色午夜在线观看| 亚洲日韩精品A∨片无码| 亚洲视频在线一区二区| 亚洲精品乱码久久久久久蜜桃| 国产亚洲人成在线影院| 国产精品亚洲二区在线| 精品无码专区亚洲| 亚洲国产无线乱码在线观看| 亚洲国产成人无码AV在线| 亚洲区日韩精品中文字幕| 亚洲人成无码网站在线观看| 亚洲av无码专区亚洲av不卡| 亚洲AV网一区二区三区| 亚洲av日韩片在线观看| 亚洲AV无码成人精品区日韩| 婷婷亚洲天堂影院| 爱情岛论坛网亚洲品质自拍| 亚洲男人电影天堂| 亚洲乱码卡一卡二卡三| 国产精品亚洲综合五月天| 亚洲乱色伦图片区小说| 亚洲AV网一区二区三区 | 亚洲国产精品综合久久网各| 亚洲成人动漫在线观看| 亚洲一区二区三区久久| 亚洲欧美国产精品专区久久| 老子影院午夜伦不卡亚洲| 亚洲精品色婷婷在线影院| 亚洲桃色AV无码| 亚洲AV无码乱码国产麻豆穿越| 亚洲韩国在线一卡二卡| 亚洲视频一区二区三区四区| 亚洲JIZZJIZZ妇女| 亚洲人成影院在线无码观看| 亚洲国产综合无码一区| 亚洲综合精品一二三区在线|