Docker化HBase排錯實錄:從Master hflush啟動失敗到Snappy算法未支持解決

前言

在容器化時代,使用 Docker 部署像 HBase 這樣復雜的分布式系統也比較方便。社區也提供了許多方便的 HBase Docker 鏡像,沒有找到官方的 apache的,但有包含許多大數據工具的 harisekhon/hbase 或用于學習目的的 bigdatauniversity/hbase 等,下載量多的一般都比較老了,也可以找最新的。選擇一個合適的鏡像可以快速啟動 HBase 實例。小子是在老鏡像上基礎上創建的。

問題及結論

然而,即使使用了預構建的鏡像,仍然可能遇到挑戰。先總結一下小子在 Docker 環境中使用 HBase 2.5.11 時,遇到的問題及解決方案,后面是詳細介紹:

  1. HMaster 啟動失敗: 由于本地文件系統缺少 hflush 能力,通過設置 hbase.unsafe.stream.capability.enforce=false 繞過強制檢查得以解決。
  2. Zookeeper 啟動失敗:/tmp 目錄數據不一致,通過清理 Zookeeper 數據目錄并強調持久化存儲的重要性得以解決。
  3. Snappy 壓縮失敗: 由于默認 Codec 依賴 Native 庫在 Docker 環境中出現問題,通過在 hbase-site.xml 中配置使用純 Java 的 Snappy Codec (hbase.io.compress.snappy.codec) 解決。

環境

  • HBase 版本: 2.5.11
  • 部署環境: Docker (未使用 HDFS,hbase.rootdir(/hbase-data) 指向本地文件系統路徑)
  • 1-master+1-regionserver+1-zookeeper

問題一:HMaster 啟動失敗 - “StreamLacksCapabilityException: hflush”

在嘗試啟動 HBase 集群時,遇到的第一個攔路虎是 HMaster 進程無法成功啟動。檢查 Master 日志 (logs/hbase--master-....log),定位到以下關鍵錯誤信息:

2025-04-26T09:04:32,270 WARN  [main] wal.AbstractProtobufLogWriter: Init output failed, path=file:/hbase-data/MasterData/WALs/...
org.apache.hadoop.hbase.util.CommonFSUtils$StreamLacksCapabilityException: hflush# ... (堆棧跟蹤)2025-04-26T09:04:32,277 ERROR [main] wal.AsyncFSWALProvider: The RegionServer async write ahead log provider relies on the ability to call hflush for proper operation... but the current FileSystem does not support doing so. Please check the config value of 'hbase.wal.dir' and ensure it points to a FileSystem mount that has suitable capabilities...2025-04-26T09:04:32,281 ERROR [main] master.HMaster: Failed to become active master
java.io.IOException: cannot get log writer# ... (Caused by: StreamLacksCapabilityException: hflush)2025-04-26T09:04:32,282 ERROR [main] master.HMaster: ***** ABORTING master ...: Unhandled exception. Starting shutdown. *****

原因分析:

日志非常清晰地指出了問題所在:

  1. HBase 的 hbase.rootdir 被配置為 file:/hbase-data,使用的是本地文件系統。
  2. HBase 默認(或當前配置)的 Write-Ahead Log (WAL) 提供者是 AsyncFSWALProvider
  3. AsyncFSWALProvider 設計上依賴底層文件系統提供 hflush 功能,這是 HDFS 文件系統的一個重要能力,用于確保數據被強制刷寫到存儲介質,保證數據持久性。
  4. 然而,標準的本地文件系統 (file:/) 實現通常不保證或不報告支持 hflush 這個 HDFS 特有的能力。
  5. 因此,在初始化 WAL 時,由于底層文件系統缺少所需的能力,導致 AsyncFSWALProvider 初始化失敗,進而 HMaster 啟動中止。

解決方案探索與最終方案:

小子查資料(包括從gemini和chatgpt上問)首先嘗試修改 hbase-site.xml(在$HBASE_HOME/conf下),將 WAL 提供者更改為舊版的、理論上更適合本地文件系統的 filesystem

<property><name>hbase.wal.provider</name><value>filesystem</value>
</property>

遺憾的是,僅僅這樣修改并重啟后,問題依舊存在。推測可能是 HBase 或 Hadoop 的底層庫在實際使用 WAL 提供者之前,仍然會進行一個文件系統能力的預檢查,這個檢查仍然失敗了。

最終找到并確認有效的解決方案是在 hbase-site.xml 中添加以下配置,顯式地禁用強制的文件流能力檢查(是聯網的chatgpt給出的答案):

<property><name>hbase.unsafe.stream.capability.enforce</name><value>false</value>
</property>

解釋: 將此參數設置為 false,相當于告訴 HBase:“我知道我使用的文件系統可能沒有報告支持 hflush 這些高級能力,但請不要因為這個檢查就失敗,繼續嘗試運行。” 這樣就繞過了啟動時的強制檢查。

關于 “unsafe”: 這個名字提醒我們,禁用檢查意味著 HBase 失去了對底層存儲 hflush 能力的強保證。對于本地文件系統,操作系統通常有緩存機制,雖然 filesystem WAL 提供者會盡力(如使用 fsync)保證數據落盤,但在極端情況(如 OS 崩潰且 fsync 未完成)下,理論上存在丟失極少量已確認寫入的數據的風險。不過,在 Docker 中使用可靠的本地卷進行開發或測試,這種風險通常是可接受的。生產環境中使用非 HDFS 存儲時,務必謹慎評估此配置的安全性影響。

應用此配置并重啟后,HMaster 終于成功啟動了!

問題二:Zookeeper 啟動失敗 - “No snapshot found, but there are log entries”

在多次重啟(尤其在容器內直接重啟hbase時)的 Zookeeper 進程也可能啟動失敗。查看 Zookeeper 的日志 ($HBASE_HOME/logs/zookeeper.log),發現了這個錯誤:

2025-04-26T08:46:06,621 INFO  [main] persistence.SnapStream: zookeeper.snapshot.compression.method = CHECKED
java.io.IOException: No snapshot found, but there are log entries. Something is broken!at org.apache.zookeeper.server.persistence.FileTxnSnapLog.restore(FileTxnSnapLog.java:290)at org.apache.zookeeper.server.ZKDatabase.loadDataBase(ZKDatabase.java:285)# ... (堆棧跟蹤省略)

日志同時顯示 Zookeeper 的數據和快照目錄位于 /tmp/hbase-root/zookeeper/version-2

原因分析:

這個錯誤表明 Zookeeper 的數據目錄處于一個不一致的狀態:存在事務日志文件,卻沒有對應的快照文件作為恢復的起點。在 Docker 環境下,尤其當數據目錄指向 /tmp 時,常見原因有:

  1. /tmp 的易失性: 容器重啟可能導致 /tmp 目錄下的內容被部分或全部清除。
  2. 不正常關閉: 上次容器非正常退出,可能導致 Zookeeper 數據文件寫入中斷或損壞。
  3. 缺少持久化: Zookeeper 的數據目錄沒有配置 Docker Volume 或綁定掛載到宿主機的持久化存儲上。

小子的容器原因,是因為沒有重啟pod,老版本hbase啟用成功過,zk有數據持久化到目錄,升級到高版本不兼容,就啟動不起來了。

解決方案:

最直接有效的辦法是清理掉這個損壞的 Zookeeper 數據目錄。

  1. 停止 HBase 相關容器。
  2. 進入 Master 容器(如果 ZK 在此容器內)或操作對應的 Docker Volume。
  3. 刪除 Zookeeper 數據目錄
    # 示例:在容器內執行
    rm -rf /tmp/hbase-root/zookeeper
    

或直接重新啟動容器。

執行清理操作后,Zookeeper 成功啟動。

配置優化:調整 JVM 堆內存

為了讓 HBase 更穩定、性能更好,可以根據容器或服務器的資源情況,為 HBase 的核心組件(Master, RegionServer, Zookeeper)分配合適的 JVM 堆內存。們通過修改 hbase-env.sh 文件來設置(也可以通過 Docker 環境變量如 HBASE_MASTER_OPTS 等方式傳入)。

conf/hbase-env.sh 文件中添加或修改以下行:

# ==============================================================================
# JVM Heap Settings for HBase Components
# ==============================================================================# 設置 HBase Master 最大堆內存為 3GB
export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS -Xmx3g"# 設置 HBase RegionServer 最大堆內存為 6GB
export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS -Xmx6g"# 設置 HBase 管理的 Zookeeper 最大堆內存為 1GB (僅對內嵌 ZK 有效)
export HBASE_ZOOKEEPER_OPTS="$HBASE_ZOOKEEPER_OPTS -Xmx1g"# ==============================================================================
# 可選: 設置初始堆大小 (-Xms) 與最大堆大小一致以提高性能
# ==============================================================================
# export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS -Xms3g"
# export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS -Xms6g"
# export HBASE_ZOOKEEPER_OPTS="$HBASE_ZOOKEEPER_OPTS -Xms1g"

應用方式:

  • 將修改后的 hbase-env.sh 文件通過 Docker Volume 掛載到容器的 /path/to/hbase/conf/hbase-env.sh 位置。
  • 或者,基于 HBase 鏡像構建一個新鏡像,在 Dockerfile 中將修改后的文件 COPY 進去。

重要: 修改配置后,需要重啟對應的 HBase 容器才能生效。同時,確保為 Docker 容器本身分配了足夠的內存(例如,使用 docker run --memorydocker-compose.yml 中的 deploy.resources.limits.memory)來容納設置的 JVM 堆以及其他開銷。

問題三:Snappy 壓縮表創建失敗 - “previously failed test”

HBase服務啟動成功后。嘗試創建一個使用 Snappy 壓縮的表:

create 'test_snappy_1', {NAME => 'cf1', COMPRESSION => 'SNAPPY'}

沒想到,RegionServer 日志中又出現了錯誤:

2025-04-26T05:19:20.671847592Z 2025-04-26 05:19:20,490 ERROR [RS_OPEN_REGION-...] handler.OpenRegionHandler: Failed open of region=test_snappy_1...
2025-04-26T05:19:20.671852492Z org.apache.hadoop.hbase.DoNotRetryIOException: Compression algorithm 'snappy' previously failed test.
2025-04-26T05:19:20.671857792Z 	at org.apache.hadoop.hbase.util.CompressionTest.testCompression(CompressionTest.java:93)# ... (堆棧跟蹤)

錯誤信息 Compression algorithm 'snappy' previously failed test 指示 HBase 在嘗試使用 Snappy 壓縮時,其內部的壓縮算法測試失敗了。

原因分析與純 Java Codec:

根據 HBase 官方文檔,HBase 支持多種壓縮算法,包括 Snappy。默認情況下,SNAPPY 算法通常映射到 org.apache.hadoop.io.compress.SnappyCodec 這個實現。這個實現依賴于 Hadoop Native Library。在 Docker 環境中,如果:

  • 基礎鏡像沒有包含 Hadoop Native Library;
  • 包含的 Native Library 版本與操作系統或 JVM 不兼容;
  • Native Library 因為某些原因加載失敗;

那么,依賴 Native Library 的 Snappy Codec 就會在 HBase 的 CompressionTest 中失敗。

幸運的是,新版的HBase支持純 Java 實現的壓縮 Codec,它們不依賴于操作系統級別的 Native 庫,從而可以避免這類環境兼容性問題:

  • 官方介紹的Java 實現
  • 2.5.x才支持的jira說明

由于小子使用的是 HBase 2.5.11,這些純 Java 實現都是可用的。不想再引入HDFS,所以使用純 Java 實現是理想的選擇。

解決方案:配置使用 Aircompressor Snappy Codec

hbase-site.xml 中添加以下配置,明確指定 SNAPPY 壓縮算法使用 Aircompressor 提供的純Java 實現:

<property><name>hbase.io.compress.snappy.codec</name><value>org.apache.hadoop.hbase.io.compress.aircompressor.SnappyCodec</value>
</property>

然后務必重啟 HBase Master 和所有 RegionServer 進程

重啟完成后,再次嘗試創建 Snappy 壓縮表:

create 'test_snappy_1', {NAME => 'cf1', COMPRESSION => 'SNAPPY'}

這一次,命令成功執行,表成功創建!

也可以使用以下命令驗證:

$HBASE_HOME/bin/hbase org.apache.hadoop.hbase.util.CompressionTest file:///tmp/test.txt snappy

結語

在 Docker 中部署和運行 HBase 2.5.11 的過程充滿了挑戰,但也收獲頗豐。小子也順手記錄,以饗各位看官,歡迎留言交流!


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/81129.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/81129.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/81129.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

windows遠程服務器數據庫的搭建和遠程訪問(Mysql忘記密碼通過Navicat連接記錄解密密碼)

服務器數據庫的搭建和遠程訪問 mysql數據庫安裝&#xff08;詳細&#xff09; window安裝mysql詳細流程 路程&#xff1a;重設MySQL5密碼&#xff0c;發現遠程服務器原本有一個MySQL5&#xff0c;嘗試在服務器本地建立連接被拒絕&#xff0c;因為不知道密碼。 &#xff08;1…

每日c/c++題 備戰藍橋杯(P1093 [NOIP 2007 普及組] 獎學金)

洛谷P1093 [NOIP 2007 普及組] 獎學金 詳解題解 題目背景與要求 題目鏈接&#xff1a;P1093 獎學金 核心任務&#xff1a;根據學生三科總分評選前5名獎學金獲得者&#xff0c;需按特定規則排序輸出。 排序規則&#xff08;按優先級從高到低&#xff09;&#xff1a; 總分降…

openEuler 22.03 安裝 Nginx,支持離線安裝

目錄 一、環境檢查1.1 必要環境檢查1.2 在線安裝&#xff08;有網絡&#xff09;1.3 離線安裝&#xff08;無網絡&#xff09; 二、下載Nginx2.1 在線下載2.2 離線下載 三、安裝Nginx四、開機自啟服務五、開放防火墻端口六、常用命令 一、環境檢查 1.1 必要環境檢查 # 查看 g…

基于深度學習的圖像壓縮技術(二)

接上篇&#xff1a;基于深度學習的圖像壓縮技術&#xff08;一&#xff09;-CSDN博客 3 基于生成對抗神經網絡的圖像壓縮技術 生成對抗網絡是一種先進的無監督學習算法&#xff0c;由Goodfellow等人在2014 年首次提出&#xff0c;其核心思想源于博弈論。 生成對抗網絡在圖像壓…

TCP和UDP的數據傳輸+區別

目錄 一、數據傳輸過程 1.1 TCP字節流服務圖 1.2 UDP數據報服務圖 二、tcp與udp的區別 1.連接方式 2.可靠性 3.傳輸效率 4.有序性 5.流量控制和擁塞控制 6.應用場景 7.首部長度 三、tcp與udp能不能使用同一個端口號&#xff1f; 四、同一個協議&#xf…

基于ssm的校園舊書交易交換平臺(源碼+文檔)

項目簡介 校園舊書交易交換平臺的主要使用者分為&#xff1a; 前臺功能&#xff1a;用戶進入系統可以對首頁、書籍信息、校園公告、個人中心、后臺管理等功能進行操作&#xff1b; 后臺主要是管理員&#xff0c;管理員功能包括主頁、個人中心、學生管理、發布人管理、書籍分類…

虛假安全補丁攻擊WooCommerce管理員以劫持網站

一場大規模釣魚攻擊正針對WooCommerce用戶&#xff0c;通過偽造安全警報誘使他們下載所謂的"關鍵補丁"&#xff0c;實則為植入WordPress后門的惡意程序。 惡意插件植入 根據Patchstack研究人員發現&#xff0c;上當受騙的用戶在下載更新時&#xff0c;實際上安裝的…

《冰雪傳奇點卡版》:第二大陸介紹!

一、第二大陸&#xff1a;高階資源與實力驗證的核心戰場 1. 準入條件與地圖分布 進入門檻&#xff1a; 基礎要求&#xff1a;角色需達到四轉&#xff08;需消耗50萬元寶完成轉生任務&#xff09;&#xff0c;部分地圖需額外滿足神魔點數&#xff08;如黑暗之森需神魔全2&#…

信創系統圖形界面開發指南:技術選擇與實踐詳解

信創系統圖形界面開發指南&#xff1a;技術選擇與實踐詳解 &#x1f9d1; 博主簡介&#xff1a;CSDN博客專家、CSDN平臺優質創作者&#xff0c;高級開發工程師&#xff0c;數學專業&#xff0c;10年以上C/C, C#, Java等多種編程語言開發經驗&#xff0c;擁有高級工程師證書&…

【人臉去遮擋前沿】三階段級聯引導學習如何突破真實場景遮擋難題?

一、現實痛點:當人臉被遮擋,AI “認臉” 有多難? 你是否遇到過這樣的場景? 中考體育測試:2025 年天津泰達街中考考場要求考生 “臉部無遮擋” 才能通過人臉識別入場,戴口罩、帽子的學生需現場調整發型。智能門鎖:奇景光電在 CES 2025 推出的 WiseEye 掌靜脈模塊,通過掌…

c++線程的創建

c 11 線程編程實戰 目錄 c 11 線程編程實戰1&#xff0c;線程的創建1.1 傳入無參函數1.2 傳入有參函數1.3 傳入類內部函數1.4 lambda表達式 1&#xff0c;線程的創建 1.1 傳入無參函數 //傳入函數&#xff0c;創建線程 void ThreadMain() {//獲取線程IDstd::thread::id thi…

人工智能數學基礎(六):數理統計

數理統計是人工智能中數據處理和分析的核心工具&#xff0c;它通過收集、分析數據來推斷總體特征和規律。本文將系統介紹數理統計的基本概念和方法&#xff0c;并結合 Python 實例&#xff0c;幫助讀者更好地理解和應用這些知識。資源綁定附上完整資源供讀者參考學習&#xff0…

解決STM32待機模式無法下載程序問題的深度探討

在現代嵌入式系統開發中&#xff0c;STM32系列微控制器因其高性能、低功耗和豐富的外設資源而廣受歡迎。然而&#xff0c;開發者在使用STM32時可能會遇到一個問題&#xff1a;當微控制器進入待機模式后&#xff0c;無法通過調試接口&#xff08;如SWD或JTAG&#xff09;下載程序…

C#擴展方法與Lambda表達式基本用法

C# 擴展方法與 Lambda 表達式詳解 一、擴展方法詳解 1. 基本概念 ??擴展方法??允許為現有類型"添加"方法&#xff0c;而無需修改原始類型或創建派生類型。 ??定義條件??&#xff1a; 必須在靜態類中定義方法本身必須是靜態的第一個參數使用this修飾符指…

C#規避內存泄漏的編碼方法

C#規避內存泄漏的編碼方法 內存泄漏是C#開發中常見的問題&#xff0c;盡管.NET有垃圾回收機制(GC)&#xff0c;但不當的編碼實踐仍可能導致內存無法被及時回收。以下是系統性的規避內存泄漏的方法&#xff1a; 一、理解內存泄漏的常見原因 ??未釋放的事件訂閱????靜態…

React 后臺管理系統

這是一個基于 React TypeScript Ant Design 開發的向明天系統前端項目。 git倉庫地址 技術棧 React 19TypeScriptAnt Design 5.xRedux ToolkitReact RouterAxiosLess 環境要求 Node.js (推薦使用最新LTS版本)npm 或 yarn 安裝步驟 克隆項目到本地 git clone [https://…

第九節:文件操作

理論知識 文件的基本概念&#xff1a;文件是存儲數據的基本單位&#xff0c;在 Linux 系統中&#xff0c;一切皆文件。文件可以是文本文件、二進制文件、設備文件等。文件的創建&#xff1a;使用 touch 命令可以創建一個新的空文件。如果文件已經存在&#xff0c;則更新文件的…

2025-03 機器人等級考試四級理論真題 4級

1 2025年蛇年春晚&#xff0c;節目《秧BOT》機器人舞蹈表演節目點燃了全國觀眾的熱情&#xff0c;請問參加節目表演的機器人是由哪家公司研發&#xff1f;&#xff08; &#xff09; A.大疆 B.華為 C.優必選 D.宇樹科技 【參考答…

k8s平臺:手動部署Grafana

以下是一個可用于生產環境的 Kubernetes 部署 Grafana 的 YAML 文件。該配置包括 Deployment、Service、ConfigMap 和 PersistentVolumeClaim&#xff0c;確保 Grafana 的高可用性和數據持久化。 Grafana 生產部署 YAML 文件 ☆實操示例 cat grafana-deployment.yaml --- # …

農產品園區展示系統——仙盟創夢IDE開發

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>農業大數據平臺</title><style>* {margi…