Spark拉取HBase數據時遇到的問題

問題1:

org.apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle 5

    從堆棧日誌中可以看出,是BlockStoreShuffleReader在讀取Shuffle到磁盤上的數據的時候發生的錯誤。從源碼中可以看出,MapStauts==null纔會跑出這個異常,而MapStatus爲什麼是null是因爲Executor掛了:

    Executor掛了的原因可能是因爲某些個Partition的太大,導致Task處理需要很長時間,從而引起長時間的GC或者JVM崩潰了。Executor lost會爆出Failed to connect host錯誤。

解決方法有如下幾個:

  1. 增加Partition數量,本人就是通過這種方式解決了
  2. 判斷下是否是數據傾斜,有條件的話,增加Executor的內存
  3. 使用一些減少Shuffle的算子

 

 

問題2:

Spark 拉取HBase數據時,Executor端報錯java.net.socketTimeoutExection:

同時HBase的RegionServer也報錯:lease *** does not exist

 

這兩個問題都是超時問題,解決方法如下:

    連接HBase的Configuration設置下面兩個參數:

        conf.setInt("hbase.rpc.timeout",7200000)

        conf.setInt("hbase.client.scanner.timeout.period",7200000)//HBase1.1之前爲“hbase.regionserver.lease.period”

 

下面來解釋下這兩個參數的含義:

hbase.rpc.timeout:

    表示一次RPC請求的超時時間,如果超過這個時間,客戶端就會關閉socke,服務端就會拋出一個異常:java.io.IOException:Connection reset by peer。由於個人程序中給Spark配置了很多Core,高併發的讀給HBase服務端造成了很大的壓力,導致請求無法處理髮生超時,默認是60000ms

 

hbase.client.scanner.timeout.period:

    專門給Scan設置的一個超時參數。一個Scan根據setCache(***)會分成多個RPC請求去服務端獲取數據,而不像Put等其他請求一樣是一次性處理完的,所以HBase服務端會引入一個lease機制(租約機制)

    引入這個機制的原因是RegionServer在收到Scan請求的時候,會生成一個全局唯一的scanId,然後構建整個scan體系(這個可以看之前分析Get請求的那篇文章)。後續同一個Scan的RPC請求只要使用相同的scanId就可以繼續獲取資源。也就是說在整個Scan的過程中,客戶端其實都在佔用着服務端的資源。如果客戶端崩潰了,那麼服務端檢測到超過了設置的配置時間之後,就會銷燬lease並釋放Scan所持有的全部資源,客戶端再發送RPC請求來之後,相應的lease已經不存在了,就會拋出leaseExecption。

 

還有一個hbase.client.operation.timeout:

    表示除了Scan以外,其他一次數據操作的總的超時時間,數據操作可以是Get、Put、Delete等等,一次操作也可以包含多個RPC請求。

 

 

參考:

https://blog.csdn.net/shenxiaoming77/article/details/17914941(HBase客戶端超時分析)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章