錯誤1:
排查問題
通過查看HBase Master運行日志,結合客戶端拋出異常的時刻,發現當時HBase集群內正在進行Region的Split和不同機器之間的Region Balance,那么,為什么會周期性頻繁觸發以上過程呢?而且是發生在壓測期間(數據量與平時相比大幾倍)。下面結合表的設計來分析一下:
1)由於表中rowkey有時間字段,因此每天都需要新創建Region,同時由於寫入數據量大,進一步觸發了HBase的Region Split操作,這一過程一般耗時較長(測試時從線上日志來看,平均為10秒左右,Region大小為4GB),且Region Split操作觸發較為頻繁;
2)同時由於Region Split操作導致Region分布不均勻,進而觸發HBase自動做Region Balance操作,Region遷移過程中也會導致Region下線,這一過程耗時較長(測試時從線上日志來看,平均為20秒左右)。
解決問題
首先,從客戶端考慮,其實就是要保證Region下線不可服務期間,讀寫請求能夠在集群恢復后繼續,具體可以采取如下措施:
1)對於寫端,可以將未寫入成功的記錄,添加到一個客戶端緩存中,隔一段時間后交給一個后台線程統一重新提交一次;也可以通過setAutoFlush(flase, false)保證提交失敗的記錄不被拋棄,留在客戶端writeBuffer中等待下次writeBuffer滿了后再次嘗試提交,直到提交成功為止。
2)對於讀端,捕獲異常后,可以采取休眠一段時間后進行重試等方式。
3)當然,還可以根據實際情況合理調整hbase.client.retries.number和hbase.client.pause配置選項。
然后,從服務端考慮,需要分別針對Region Split和Region Balance進行解決:
1)由於建表時,我們已經考慮到了數據在不同Region Server上的均勻分布,而且預先在不同Region Server上創建並分配了相同數目的Region,那么考慮到為了集群能夠在實際線上環境下提供穩定的服務,可以選擇關掉HBase的Region自動Balance功能,當然關掉后可以選擇在每天讀寫壓力小的時候(如凌晨后)觸發執行一次Balance操作即可。
2)接下來,Region總是被創建,不能被復用的問題該如何解決呢?根本原因是rowkey中包含了timestamp字段,而每時每刻timestamp總是向上增長的。但是,使用方確實需要能夠根據timestamp字段進行順序scan操作,因此,timestamp字段必須保留。據此,這里給出兩種解決思路:
- 一種常用方法是將表按照時間分表,例如按天進行分表,這樣可以通過預先建表創建好Region分區,避免實際讀寫過程中頻繁觸發Region Split等過程,但是這一方法的缺點是每天需要預先建好表,而這一DDL過程可能出現問題進而導致讀寫出現問題,同時跨天時讀寫端也需要做出適應,調整為讀寫新創建的表。
- 其實,我們可以換一種思路,通過修改表的rowkey結構,將timestamp字段改成一個周期循環的timestamp,如取timestamp % TS_MODE后的值,其中TS_MODE須大於等於表的TTL時間周期,這樣才能保證數據不會被覆蓋掉。經過這樣改造后,即可實現Region的復用,避免Region的無限上漲。對於讀寫端的變更也較小,讀寫端操作時只需將timestamp字段取模后作為rowkey進行讀寫,另外,讀端需要考慮能適應scan掃描時處理[startTsMode, endTsMode]和[endTsMode, startTsMode]兩種情況。
錯誤2:
報錯原因:因為服務器處理時間過長,客戶端自動斷開連接,當服務器處理完成返回數據時,發現連接斷開,故拋出異常。
解決方案:1、hbase.rpc.timeout默認值為60000ms,可以適當調大這個值,可以從配置文件里調整,也可以通過conf.set("hbase.rpc.timeout
", "6000000")進行調整。
2、將zookeeper的時間調大:調整zookeeper.session.timeout
在hbase-site.xml中調大如下兩個值(根據實際情況調大)
<property> <name>zookeeper.session.timeout</name> <value>60000</value> </property> <property> <name>hbase.zookeeper.property.tickTime</name> <value>2000</value> </property>
3、加大region數據,讓region均勻分配:調節hbase-site.xml中的hbase.hregion.max.filesize值,默認為256M,可以調整到1G,有人甚至調到4G(更大的Region可以使你集群上的Region的總數量較少。 一般來言,更少的Region可以使你的集群運行更加流暢。)。
