輸入DStream和Receiver詳解
輸入DStream代表了來自數(shù)據(jù)源的輸入數(shù)據(jù)流。在之前的wordcount例子中,lines就是一個(gè)輸入DStream(JavaReceiverInputDStream),代表了從netcat(nc)服務(wù)接收到的數(shù)據(jù)流营勤。除了文件數(shù)據(jù)流之外,所有的輸入DStream都會(huì)綁定一個(gè)Receiver對(duì)象壹罚,該對(duì)象是一個(gè)關(guān)鍵的組件葛作,用來從數(shù)據(jù)源接收數(shù)據(jù),并將其存儲(chǔ)在Spark的內(nèi)存中渔嚷,以供后續(xù)處理进鸠。
Spark Streaming提供了兩種內(nèi)置的數(shù)據(jù)源支持
- 基礎(chǔ)數(shù)據(jù)源:StreamingContext API中直接提供了對(duì)這些數(shù)據(jù)源的支持,比如文件形病、socket、Akka Actor等霞幅。
- 高級(jí)數(shù)據(jù)源:諸如Kafka漠吻、Flume、Kinesis司恳、Twitter等數(shù)據(jù)源途乃,通過第三方工具類提供支持。這些數(shù)據(jù)源的使用扔傅,需要引用其依賴耍共。
- 自定義數(shù)據(jù)源:我們可以自己定義數(shù)據(jù)源,來決定如何接受和存儲(chǔ)數(shù)據(jù)猎塞。
要注意的是试读,如果你想要在實(shí)時(shí)計(jì)算應(yīng)用中并行接收多條數(shù)據(jù)流,可以創(chuàng)建多個(gè)輸入DStream荠耽。這樣就會(huì)創(chuàng)建多個(gè)Receiver钩骇,從而并行地接收多個(gè)數(shù)據(jù)流。但是要注意的是,一個(gè)Spark Streaming Application的Executor倘屹,是一個(gè)長時(shí)間運(yùn)行的任務(wù)银亲,因此,它會(huì)獨(dú)占分配給Spark Streaming Application的cpu core纽匙。從而只要Spark Streaming運(yùn)行起來以后务蝠,這個(gè)節(jié)點(diǎn)上的cpu core,就沒法給其他應(yīng)用使用了烛缔。
使用本地模式请梢,運(yùn)行程序時(shí),絕對(duì)不能用local或者local[1]力穗,因?yàn)槟菢拥脑捯慊。粫?huì)給執(zhí)行輸入DStream的executor分配一個(gè)線程。而Spark Streaming底層的原理是当窗,至少要有兩條線程够坐,一條線程用來分配給Receiver接收數(shù)據(jù),一條線程用來處理接收到的數(shù)據(jù)崖面。因此必須使用local[n]元咙,n>=2的模式。
如果不設(shè)置Master巫员,也就是直接將Spark Streaming應(yīng)用提交到集群上運(yùn)行庶香,那么首先,必須要求集群節(jié)點(diǎn)上简识,有>1個(gè)cpu core赶掖,其次,給Spark Streaming的每個(gè)executor分配的core七扰,必須>1奢赂,這樣,才能保證分配到executor上運(yùn)行的輸入DStream颈走,兩條線程并行膳灶,一條運(yùn)行Receiver,接收數(shù)據(jù)立由;一條處理數(shù)據(jù)轧钓。否則的話,只會(huì)接收數(shù)據(jù)锐膜,不會(huì)處理數(shù)據(jù)毕箍。
看下圖片,更能說明問題
所以說枣耀,集群的節(jié)點(diǎn)上霉晕,總共擁有的cpu core庭再,首先,必須是大于Spark Streaming Application的Receiver數(shù)量牺堰,因?yàn)橐粋€(gè)Receiver獨(dú)占一個(gè)CPU core
其次拄轻,在spark-submit腳本中,給Application分配的總的cpu core伟葫,肯定小于等于集群的cpu core的數(shù)量恨搓,大于Receiver的數(shù)量