Spark Streaming Backpressure分析

weixin_33797791發表於2018-01-17

1. 為什麼引入Backpressure

預設情況下,Spark Streaming通過Receiver以生產者生產資料的速率接收資料,計算過程中會出現batch processing time > batch interval的情況,其中batch processing time 為實際計算一個批次花費時間, batch interval為Streaming應用設定的批處理間隔。這意味著Spark Streaming的資料接收速率高於Spark從佇列中移除資料的速率,也就是資料處理能力低,在設定間隔內不能完全處理當前接收速率接收的資料。如果這種情況持續過長的時間,會造成資料在記憶體中堆積,導致Receiver所在Executor記憶體溢位等問題(如果設定StorageLevel包含disk, 則記憶體存放不下的資料會溢寫至disk, 加大延遲)。Spark 1.5以前版本,使用者如果要限制Receiver的資料接收速率,可以通過設定靜態配製引數“spark.streaming.receiver.maxRate”的值來實現,此舉雖然可以通過限制接收速率,來適配當前的處理能力,防止記憶體溢位,但也會引入其它問題。比如:producer資料生產高於maxRate,當前叢集處理能力也高於maxRate,這就會造成資源利用率下降等問題。為了更好的協調資料接收速率與資源處理能力,Spark Streaming 從v1.5開始引入反壓機制(back-pressure),通過動態控制資料接收速率來適配叢集資料處理能力。

2. Backpressure

Spark Streaming Backpressure: 根據JobScheduler反饋作業的執行資訊來動態調整Receiver資料接收率。通過屬性“spark.streaming.backpressure.enabled”來控制是否啟用backpressure機制,預設值false,即不啟用。

3. 流量控制點

當Receiver開始接收資料時,會通過supervisor.pushSingle()方法將接收的資料存入currentBuffer等待BlockGenerator定時將資料取走,包裝成block. 在將資料存放入currentBuffer之時,要獲取許可(令牌)。如果獲取到許可就可以將資料存入buffer, 否則將被阻塞,進而阻塞Receiver從資料來源拉取資料。
其令牌投放採用令牌桶機制進行, 原理如下圖所示:

10139335-ee0120dccb82d374.png
backpressure.png

牌桶機制: 大小固定的令牌桶可自行以恆定的速率源源不斷地產生令牌。如果令牌不被消耗,或者被消耗的速度小於產生的速度,令牌就會不斷地增多,直到把桶填滿。後面再產生的令牌就會從桶中溢位。最後桶中可以儲存的最大令牌數永遠不會超過桶的大小。當進行某操作時需要令牌時會從令牌桶中取出相應的令牌數,如果獲取到則繼續操作,否則阻塞。用完之後不用放回。

Streaming 資料流被Receiver接收後,按行解析後存入iterator中。然後逐個存入Buffer,在存入buffer時會先獲取token,如果沒有token存在,則阻塞;如果獲取到則將資料存入buffer. 然後等價後續生成block操作。

相關文章