1.1 簡(jiǎn)單介紹
實(shí)時(shí)處理Stream流的能力,有容錯(cuò)性,保證性處理機(jī)制镀岛。對(duì)于輸入數(shù)據(jù),支持消息隊(duì)列友驮,像RabbitMQ, JMS, Kafka等或者傳統(tǒng)的數(shù)據(jù)庫(kù)和Hbase漂羊。
1.2 基本概念
- Stream
Stream 是最基礎(chǔ)的抽象和核心概念,一個(gè)沒(méi)有開(kāi)始和結(jié)束的一連串?dāng)?shù)據(jù)喊儡,可以并行創(chuàng)建拨与,被分布式組件并行消費(fèi)。 - Tuple
在Storm上下文中艾猜,stream是一連串沒(méi)有結(jié)束tuple(元組)买喧;
A tuple is a named list of values, where each value can be any type
tuple就是一個(gè)值(有名稱(chēng))列表,tuple中的值可以是任何類(lèi)型的匆赃,Storm需要知道怎么序列化Tuple的類(lèi)型淤毛,storm中的tuple支持私有類(lèi)型、字符串算柳、字節(jié)數(shù)組等作為它的字段值低淡,如果使用其他類(lèi)型,就需要序列化該類(lèi)型瞬项。
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
//定義輸出字段描述
declarer.declareStream("source", new Fields("sentence", "sentence.length"));
}
@Override
public void nextTuple() {
if(index >= sentences.length){
return;
}
//發(fā)送字符串
this.collector.emit("source", new Values(sentences[index], sentences[index].length()), "messageID_"+index);
index++;
Utils.sleep(100);
}
1.3 其它簡(jiǎn)單概念
- 拓?fù)?Topology):打包好的實(shí)時(shí)應(yīng)用計(jì)算任務(wù)蔗蹋,同Hadoop的MapReduce任務(wù)相似。
- 元組(Tuple):是Storm提供的一個(gè)輕量級(jí)的數(shù)據(jù)格式囱淋,可以用來(lái)包裝你需要實(shí)際處理的數(shù)據(jù)猪杭。
- 流(Streams):數(shù)據(jù)流(Stream)是Storm中對(duì)數(shù)據(jù)進(jìn)行的抽象,它是時(shí)間上無(wú)界的tuple元組序列(無(wú)限的元組序列)?
- Spout(噴嘴):Storm中流的來(lái)源妥衣。Spout從外部數(shù)據(jù)源皂吮,如消息隊(duì)列中讀取元組數(shù)據(jù)并吐到拓?fù)淅铩?/li>
- Bolts:在拓?fù)渲兴械挠?jì)算邏輯都是在Bolt中實(shí)現(xiàn)的。
- 任務(wù)(Tasks):每個(gè)Spout和Bolt會(huì)以多個(gè)任務(wù)(Task)的形式在集群上運(yùn)行税手。
- 組件(Component):是對(duì)Bolt和Spout的統(tǒng)稱(chēng)蜂筹。
1.4 Storm集群架構(gòu)
Storm集群采用主從架構(gòu)方式,主節(jié)點(diǎn)是Nimbus芦倒,從節(jié)點(diǎn)是Supervisor艺挪,有關(guān)調(diào)度相關(guān)的信息存儲(chǔ)到ZooKeeper集群中。
- Nimbus
Storm集群的Master節(jié)點(diǎn)兵扬,負(fù)責(zé)分發(fā)用戶(hù)代碼麻裳,指派給具體的Supervisor節(jié)點(diǎn)上的Worker節(jié)點(diǎn),去運(yùn)行Topology對(duì)應(yīng)的組件(Spout/Bolt)的Task周霉。 - Supervisor
Storm集群的從節(jié)點(diǎn)掂器,負(fù)責(zé)管理運(yùn)行在Supervisor節(jié)點(diǎn)上的每一個(gè)Worker進(jìn)程的啟動(dòng)和終止。通過(guò)Storm的配置文件中的supervisor.slots.ports配置項(xiàng)俱箱,可以指定在一個(gè)Supervisor上最大允許多少個(gè)Slot国瓮,每個(gè)Slot通過(guò)端口號(hào)來(lái)唯一標(biāo)識(shí),一個(gè)端口號(hào)對(duì)應(yīng)一個(gè)Worker進(jìn)程(如果該Worker進(jìn)程被啟動(dòng))狞谱。 - Worker
運(yùn)行具體處理組件邏輯的進(jìn)程乃摹。Worker運(yùn)行的任務(wù)類(lèi)型只有兩種,一種是Spout任務(wù)跟衅,一種是Bolt任務(wù)孵睬。 - Task
worker中每一個(gè)spout/bolt的線程稱(chēng)為一個(gè)task. 在storm0.8之后,task不再與物理線程對(duì)應(yīng)伶跷,不同spout/bolt的task可能會(huì)共享一個(gè)物理線程掰读,該線程稱(chēng)為executor秘狞。 - ZooKeeper
用來(lái)協(xié)調(diào)Nimbus和Supervisor,如果Supervisor因故障出現(xiàn)問(wèn)題而無(wú)法運(yùn)行Topology蹈集,Nimbus會(huì)第一時(shí)間感知到烁试,并重新分配Topology到其它可用的Supervisor上運(yùn)行
1.5 Topology運(yùn)行
在Storm中,一個(gè)實(shí)時(shí)應(yīng)用的計(jì)算任務(wù)被打包作為T(mén)opology發(fā)布,這同Hadoop的MapReduce任務(wù)相似拢肆。但是有一點(diǎn)不同的是:在Hadoop中减响,MapReduce任務(wù)最終會(huì)執(zhí)行完成后結(jié)束;而在Storm中郭怪,Topology任務(wù)一旦提交后永遠(yuǎn)不會(huì)結(jié)束支示,除非你顯示去停止任務(wù)。計(jì)算任務(wù)Topology是由不同的Spouts和Bolts鄙才,通過(guò)數(shù)據(jù)流(Stream)連接起來(lái)的圖?一個(gè)Storm在集群上運(yùn)行一個(gè)Topology時(shí)颂鸿,主要通過(guò)以下3個(gè)實(shí)體來(lái)完成Topology的執(zhí)行工作:
(1). Worker(進(jìn)程)
(2). Executor(線程)
(3). Task
worker進(jìn)程(不同的jvm)執(zhí)行的是1個(gè)topology的子集。1個(gè)worker進(jìn)程會(huì)啟動(dòng)1個(gè)或多個(gè)executor線程來(lái)執(zhí)行topology的component(spout或bolt)咒循。因此据途,1個(gè)運(yùn)行中的topology就是由集群中多臺(tái)物理機(jī)上的多個(gè)worker進(jìn)程組成的。
executor是1個(gè)被worker進(jìn)程啟動(dòng)的單獨(dú)線程叙甸。每個(gè)executor只會(huì)運(yùn)行topology的1個(gè)component(spout或bolt)的task(注:task可以是1個(gè)或多個(gè)颖医,storm默認(rèn)是1個(gè)component只生成1個(gè)task,executor線程里會(huì)在每次循環(huán)里順序調(diào)用所有task實(shí)例)裆蒸。
task是最終運(yùn)行spout或bolt中代碼的單元(注:1個(gè)task即為spout或bolt的1個(gè)實(shí)例熔萧,executor線程在執(zhí)行期間會(huì)調(diào)用該task的nextTuple或execute方法)。topology啟動(dòng)后僚祷,1個(gè)component(spout或bolt)的task數(shù)目是固定不變的佛致,但該component使用的executor線程數(shù)可以動(dòng)態(tài)調(diào)整(例如:1個(gè)executor線程可以執(zhí)行該component的1個(gè)或多個(gè)task實(shí)例)。默認(rèn)情況下task的數(shù)目等于executor線程數(shù)目辙谜,即1個(gè)executor線程只運(yùn)行1個(gè)task俺榆。
1.6 Storm Streaming Grouping
在Storm中, 開(kāi)發(fā)者可以為上游spout/bolt發(fā)射出的tuples指定下游bolt的哪個(gè)/哪些task(s)來(lái)處理該tuples装哆。這種指定在storm中叫做對(duì)stream的分組罐脊,即stream grouping
- Shuffle Grouping :隨機(jī)分組,上游spout/bolt發(fā)射的tuples被隨機(jī)地在下游bolt的tasks中選擇一個(gè)來(lái)處理蜕琴。bolt的tasks之間的負(fù)載比較均衡萍桌。
- Fields Grouping :根據(jù)指定的字段的值進(jìn)行分組,舉個(gè)栗子凌简,流按照“user-id”進(jìn)行分組上炎,那么具有相同的“user-id”的tuple會(huì)發(fā)到同一個(gè)task,而具有不同“user-id”值的tuple可能會(huì)發(fā)到不同的task上雏搂。這種情況常常用在單詞計(jì)數(shù)藕施,而實(shí)際情況是很少用到寇损,因?yàn)槿绻硞€(gè)字段的某個(gè)值太多,就會(huì)導(dǎo)致task不均衡的問(wèn)題。task不共享同一個(gè)對(duì)象,不是單實(shí)例的塑径。
- All grouping :廣播分組:將所有的tuple都復(fù)制之后再分發(fā)給Bolt所有的task纽窟,每一個(gè)訂閱數(shù)據(jù)流的task都會(huì)接收到一份相同的完全的tuple的拷貝。
- Global grouping :全局分組憨愉,這種分組會(huì)將所有的tuple都發(fā)到一個(gè)taskid最小的task上烦绳。由于所有的tuple都發(fā)到唯一一個(gè)task上,勢(shì)必在數(shù)據(jù)量大的時(shí)候會(huì)造成資源不夠用的情況配紫。所有上游消息全部匯總径密,便于合并、統(tǒng)計(jì)等躺孝。
- None grouping :不分組 目前等同于shuffle grouping享扔。
- LocalOrShuffle Grouping : 如果下游bolt的某些task與上游spout/bolt的某些task運(yùn)行在同一個(gè)worker進(jìn)程中,那么上游spout/bolt的這些task所發(fā)射的所有tuples均由下游bolt的同進(jìn)程的tasks來(lái)處理植袍;否則惧眠,這種分組方式等同于shuffle grouping。因優(yōu)先選擇同進(jìn)程task間傳輸而降低tuple網(wǎng)絡(luò)傳輸代價(jià)于个,但因?qū)ふ彝M(jìn)程的task而消耗CPU和內(nèi)存資源
- Direct grouping :直接分組氛魁,允許上游spout/bolt決定其發(fā)射出的任一tuple由下游bolt的哪個(gè)task接收并處理