val socketLineDStream: ReceiverInputDStream[String] = streamingContext.socketTextStream('linux1', 8888)
// TODO Driver中執行一次
// 例如val a = 1 在Driver中只執行一次
// 首先看一下DStream的其他Transformations(轉換)操作
socketLineDStream.map({
case x => {
// TODO Executor中執行n次(n是Executor數)
}
}
)
// 重點來了,看一下DStream的transform轉換操作
socketLineDStream.transform({
case rdd => {
// TODO Driver中執行m次(m是採集週期數)
rdd.map({
case x => {
//TODO Executor中執行n次(n是Executor數)
}
})
}
}
)
注意:
- transform中的註釋處的m就是細節之處,它可以保證此處運行在Driver中的代碼可以週期(SparkStreaming的數據採集週期)間變化,即每個數據週期transform走一遍。用處之一是黑名單的更新(比如惡意發帖的用戶的更新)
- 爲什麼DStream.map裏面的代碼執行是在Executor?個人理解因爲DStream在每個週期(批次)相當於就是一個RDD的封裝,所以可以類比RDD.map()裏面的代碼是運行在Executor端