之前搭建了單機的hbase,使用偽分散式的hdfs作為資料儲存,具體搭建要點和問題有所記錄:
https://blog.csdn.net/tuzongxun/article/details/107915720
後來,偽分散式的hdfs升級為ha模式,hbase自然也是要同步升級成ha的,本以為應該會很順利,但實際上花的時間還是比預想中的多,因此還是做一個簡單的記錄,尤其是其中卡住的問題。
本次hbase-ha模式搭建規劃使用三臺機,主機名分別是node001
、node002
、node003
,其中node001為master,node003為back master,而三臺都作為regionserver。
hbase-ha模式搭建,按官網說明,以及目前驗證來看,似乎必須要用hdfs,因此主要的依賴條件如下:
jdk
hdfs-ha叢集
zookeeper叢集
ssh免密
之前單機的時候,zookeeper也是使用的hbase自帶的,因此在hbase-env.sh
檔案中有這樣一行:
export HBASE_MANAGES_ZK=true
在搭建ha模式的hdfs時已經搭建好了獨立的zookeeper叢集,所以hbase的ha自然也可以直接使用這個zookeeper叢集,而不再使用自帶的,因此這裡需要修改成不使用自帶的:
export HBASE_MANAGES_ZK=false
hbase主要的一些設定都在這個檔案裡,先列一下最終的檔案主要內容:
<property>
<name>hbase.rootdir</name>
<value>hdfs://mycluster/hbase3</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.tmp.dir</name>
<value>/var/bigdata/hbase/data-local3</value>
</property>
<property>
<name>hbase.unsafe.stream.capability.enforce</name>
<value>false</value>
</property>
<property>
<name>hbase.master</name>
<value>node001:60000</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>node002,node003,node004</value>
</property>
上述第一個設定hbase.rootdir
指向hbase的儲存路徑,這裡還是使用hdfs儲存,但是不同的是,把之前固定的ip和埠改成了hdfs叢集的名稱。
之後的hbase.cluster.distributed
為true
開啟分散式,hbase.tmp.dir
設定臨時儲存目錄,hbase.unsafe.stream.capability.enforce
這個設定保持不變,為了保證啟動不報錯(具體原因待深究),hbase.master
指定一個主節點(網上說這個可以不設定,交給zookeeper來選擇,時間問題暫時未驗證),hbase.zookeeper.quorum
設定外部zookeeper的節點。
根據官網說明,需要把叢集中的region節點主機寫入到這個檔案中,這個檔案也在conf
目錄下,只不過原本里邊只有一個localhost
,修改之後如下:
node001
node002
node003
這個檔案原本是沒有的,是一個master備份節點的設定,可以不要。但是正常的ha模式一般來說是需要有備份master節點的,所以還是需要這個檔案。由於原本沒有,就需要手動在conf
目錄下建立並制定備份master節點,例如:
node003
原以為有了上邊的設定就可以了,但是使用start-hbase.sh
啟動時,發現hbase-root-regionserver-node001.log
紀錄檔出現如下的error資訊:
Caused by: java.lang.IllegalArgumentException: java.net.UnknownHostException: mycluster
at org.apache.hadoop.security.SecurityUtil.buildTokenService(SecurityUtil.java:417)
at org.apache.hadoop.hdfs.NameNodeProxiesClient.createProxyWithClientProtocol(NameNodeProxiesClient.java:132)
at org.apache.hadoop.hdfs.DFSClient.<init>(DFSClient.java:351)
at org.apache.hadoop.hdfs.DFSClient.<init>(DFSClient.java:285)
at org.apache.hadoop.hdfs.DistributedFileSystem.initialize(DistributedFileSystem.java:160)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2812)
上邊的mycluster
並非主機名,而是hdfs的叢集名稱,看起來是這裡不能識別。經過查詢,解決方案是複製hadoop裡邊的core-site.xml
和hdfs-site.xml
到hbase的conf
目錄下,然後重新啟動。
上邊操作之後重新啟動hbase不在拋error異常,原以為這次成功了,但是使用hbase shell
操作時卻不能正常的操作,而是在命令列介面跑出如下異常:
ERROR: org.apache.hadoop.hbase.PleaseHoldException: Master is initializing
at org.apache.hadoop.hbase.master.HMaster.checkInitialized(HMaster.java:2811)
at org.apache.hadoop.hbase.master.HMaster.createTable(HMaster.java:2018)
at org.apache.hadoop.hbase.master.MasterRpcServices.createTable(MasterRpcServices.java:659)
at org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos$MasterService$2.callBlockingMethod(MasterProtos.java)
at org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:418)
at org.apache.hadoop.hbase.ipc.CallRunner.run(CallRunner.java:133)
at org.apache.hadoop.hbase.ipc.RpcExecutor$Handler.run(RpcExecutor.java:338)
at org.apache.hadoop.hbase.ipc.RpcExecutor$Handler.run(RpcExecutor.java:318)
這個異常在搭建單機hbase的時候實際已經出現過,但是當時等了一會兒就好了,而這次這個異常卻沒有隨時間變化而解決,在網上找了很多解決方案均是失敗的情況下,我重新一行行的看了下紀錄檔,結果發現在hbase-root-master-node001.log
檔案中有如下幾行:
2020-09-23 09:17:17,383 WARN [master/node001:16000:becomeActiveMaster] master.HMaster: hbase:meta,,1.1588230740 is NOT online; state={1588230740 state=OPEN, ts=1600823703586, server=node001,16020,1599788244145}; ServerCrashProcedures=true. Master startup cannot progress, in holding-pattern until region onlined.
這個紀錄檔只是WARN,所以一開始沒有注意到,仔細讀了之後猜測可能就是我shell無法操作的原因,於是通過搜尋這個問題找到了解決方案,目前不完全確定根本原因,但猜測應該是zookeeper中對於hbase的狀態管理出現了異常資料。
因為我的hbase不是直接搭建成ha模式,而是從單機使用本地檔案改成hdfs,又改成ha模式,這期間為了處理和驗證各種異常還手動刪除過/tmp
等目錄下的內容,不確定是否這些操作導致zookeeper裡出現了不一致的資料。
最終解決辦法就是刪除zookeeper裡meta-region-server
,具體操作是:
zkCli.sh
deleteall /hbase/meta-region-server
實際上網上的答案几乎千篇一律是rmr /hbase-unsecure/meta-region-server
,但是我發現我的zookeeper進去之後並沒有rmr
命令,也沒有hbase-unsecure
目錄,後來看到有地方說rmr
是過期指令,多半是我的zookeeper-3.6.1比較新,已經完全刪除了這個操作,取而代之的是deleteall
。
而hbase-unsecure
應該是和mycluster
一樣只是一個叢集名字,而我這裡就叫hbase
。
裡邊諸多細節還有待深究和驗證,好在最終再重新啟動hbase之後,不論是hbase shell
還是phoenix
都能正常操作了。
注:除了細節上,hbase本身ha搭建還是較簡單,需要注意的是需要保證各叢集節點內的組態檔一致,包括從hadoop複製來的檔案。