Apache Storm 官方文档 —— 源码组织结构
原文鏈接? ? 譯者:魏勇
Strom 的代碼有三個(gè)層次:
第一,Storm 在一開(kāi)始就是按照兼容多語(yǔ)言的目的來(lái)設(shè)計(jì)的。Nimbus 是一個(gè) Thrift 服務(wù),拓?fù)湟脖欢x為 Thrift 架構(gòu)。Thrift 的使用使得 Storm 可以用于任何一種語(yǔ)言。
第二,所有的 Storm 接口都設(shè)計(jì)為 Java 接口。所以,盡管 Storm 核心代碼中有大量的 Clojure 實(shí)現(xiàn),所有的訪問(wèn)都必須經(jīng)過(guò) Java API。這就意味著 Storm 的每個(gè)特性都可以通過(guò) Java 來(lái)實(shí)現(xiàn)。
第三,Storm 的實(shí)現(xiàn)中大量使用了 Clojure。可以說(shuō),Storm 的代碼結(jié)構(gòu)大概是一半的 Java 代碼加上一半的 Clojure 代碼。但是由于 Clojure 更具有表現(xiàn)力,所以實(shí)際上 Storm 的核心邏輯大多是采用 Clojure 來(lái)實(shí)現(xiàn)的。
下面詳細(xì)說(shuō)明了每個(gè)層次的細(xì)節(jié)信息。
storm.thrift
要理解 Storm 的代碼架構(gòu),首先需要了解 storm.thrift 文件。
Storm 使用這個(gè) fork 版本的 Thrift(“storm” 分支)來(lái)生成代碼。這個(gè) “fork” 版本實(shí)際上就是 Thrift7,其中所有的 Java package 也都重命名成了 org.apache.thrift7。在其他方面,它與 Thrift7 完全相同。這個(gè) fork 主要是為了解決 Thrift 缺乏向后兼容的機(jī)制的問(wèn)題,同時(shí),也可以讓用戶(hù)在自己的 Storm 拓?fù)渲惺褂闷渌姹镜?Thrift。
拓?fù)渲械拿總€(gè) spout 或者 bolt 都有一個(gè)特定的標(biāo)識(shí),這個(gè)標(biāo)識(shí)稱(chēng)為“組件 id”。組件 id 主要為了從拓?fù)渲?spout 和 bolt 的輸出流中選擇一個(gè)或多個(gè)流作為某個(gè) bolt 訂閱的輸入流。Storm 拓?fù)渲芯桶幸粋€(gè)組件 id 與每種類(lèi)型的組件(spout 與 bolt)相關(guān)聯(lián)的 map。
Spout 和 Bolt 有相同的 Thrift 定義。我們來(lái)看看 Bolt 的 Thrift 定義。它包含一個(gè) ComponentObject 結(jié)構(gòu)和一個(gè)ComponentCommon 結(jié)構(gòu)。
ComponentObject 定義了 bolt 的實(shí)現(xiàn),這個(gè)實(shí)現(xiàn)可以是以下三種類(lèi)型中的一種:
ComponentCommon 定義了組件的其他方面特性,包括:
注意,spout 的結(jié)構(gòu)也有一個(gè) ComponentCommon 域,所以理論上說(shuō) spout 也可以聲明一個(gè)輸入流。然而 Storm 的 Java API 并沒(méi)有為 spout 提供消費(fèi)其他的流的方法,并且如果你為 spout 聲明了輸入流,在提交拓?fù)涞臅r(shí)候也會(huì)報(bào)錯(cuò)。這是因?yàn)?spout 的輸入流聲明不是為了用戶(hù)的使用,而是為了 Storm 內(nèi)部的使用。Storm 會(huì)為拓?fù)涮砑与[含的流與 bolt 來(lái)設(shè)置應(yīng)答框架(acking framework)。這些隱含的流中就有兩個(gè)流用于從 acker bolt 向拓?fù)渲械拿總€(gè) spout 發(fā)送消息。在發(fā)現(xiàn) tuple 樹(shù)完成或者失敗之后,acker 就會(huì)通過(guò)這些隱含的流發(fā)送 “ack” 或者 “fail” 消息。將用戶(hù)的拓?fù)滢D(zhuǎn)化為運(yùn)行時(shí)拓?fù)涞拇a在這里。
Java 接口
Storm 的對(duì)外接口基本上為 Java 接口,主要的幾個(gè)接口有:
大部分接口的策略為:
你可以從 BaseRichSpout 類(lèi)中觀察到這種策略的工作機(jī)制。
如上所述,Spout 和 Bolt 都已經(jīng)根據(jù)拓?fù)涞?Thrift 定義進(jìn)行了序列化。
在這些接口中,IBolt、ISpout 與 IRichBolt、IRichSpout 之間存在著一些細(xì)微的差別。其中最主要的區(qū)別是帶有 “Rich” 的接口中增加了 declareOutputFields 方法。這種區(qū)別的原因主要在于每個(gè)輸出流的輸出域聲明必須是 Thrift 結(jié)構(gòu)的一部分(這樣才能實(shí)現(xiàn)跨語(yǔ)言操作),而用戶(hù)本身只需要將流聲明為自己的類(lèi)的一部分即可。TopologyBuilder 在構(gòu)造 Thrift 結(jié)構(gòu)時(shí)所做的就是調(diào)用 declareOutputFields 方法來(lái)獲取聲明并將其轉(zhuǎn)化為 Thrift 結(jié)構(gòu)。這種轉(zhuǎn)化過(guò)程可以在TopologyBuilder 的源碼中看到。
實(shí)現(xiàn)
通過(guò) Java 接口來(lái)詳細(xì)說(shuō)明所有的功能可以確保 Storm 的每個(gè)特征都是有效的。更重要的是,關(guān)注 Java 接口可以讓有 Java 使用經(jīng)驗(yàn)的用戶(hù)更易上手。
另一方面,Storm 的核心架構(gòu)主要是通過(guò) Clojure 實(shí)現(xiàn)的。盡管按照一般的計(jì)數(shù)規(guī)則來(lái)說(shuō)代碼庫(kù)中 Java 與 Clojure 各占 50%,但是大部分邏輯實(shí)現(xiàn)還是基于 Clojure 的。不過(guò)也有兩個(gè)例外,分別是 DRPC 和事務(wù)型拓?fù)涞膶?shí)現(xiàn)。這兩個(gè)部分是完全使用 Java 實(shí)現(xiàn)的。這是為了說(shuō)明在 Storm 中如何實(shí)現(xiàn)高級(jí)抽象。DRPC 和事務(wù)型拓?fù)涞膶?shí)現(xiàn)分別位于backtype.storm.coordination、backtype.storm.drpc 和 backtype.storm.transactional 包中。
以下是主要的 Java 包和 Clojure 命名空間的總結(jié)。
Java packages
backtype.storm.coordination: 實(shí)現(xiàn)了用于將批處理整合到 Storm 上層的功能,DRPC 和事務(wù)型拓?fù)涠夹枰@個(gè)功能。CoordinatedBolt 是其中最重要的類(lèi)。
backtype.storm.drpc: DRPC 高級(jí)抽象的實(shí)現(xiàn)。
backtype.storm.generated: 為 Storm 生成的 Thrift 代碼(使用了這個(gè) fork 版本的 Thrift,其中僅僅將包名重命名為 org.apache.thrift7 來(lái)避免與其他 Thrift 版本的沖突)。
backtype.storm.grouping: 包含自定義流分組的接口。
backtype.storm.hooks: 用于在 Storm 中添加事件鉤子的接口,這些事件包括任務(wù)發(fā)送 tuple、tuple 被 ack 等等。
backtype.storm.serialization: Storm 序列化/反序列化 tuple 的接口。這是在 Kryo 的基礎(chǔ)上構(gòu)建的。
backtype.storm.spout: Spout 與一些關(guān)聯(lián)接口的定義(例如 SpoutOutputCollector)。其中也包含有用于實(shí)現(xiàn)非 JVM 語(yǔ)言 spout 的協(xié)議的 ShellSpout。
backtype.storm.task: Bolt 與關(guān)聯(lián)接口的定義(例如 OutputCollector)。其中也包含有用于實(shí)現(xiàn)非 JVM 語(yǔ)言 bolt 的協(xié)議的 ShellBolt。最后,TopologyContext 也是在這里定義的,該類(lèi)可以用于在拓?fù)溥\(yùn)行時(shí)為 spout 和 bolt 提供拓?fù)湟约八麄冏陨韴?zhí)行的相關(guān)信息。
backtype.storm.testing: 包含很多 bolt 測(cè)試類(lèi)以及用于 Storm 單元測(cè)試的工具類(lèi)。
backtype.storm.topology: 在 Thrift 結(jié)構(gòu)上層的 Java 層,用于為 Storm 提供完全的 Java API(用戶(hù)不必了解 Thrift)。TopologyBuilder 和一些為不同的 spout 和 bolt 提供幫助的基礎(chǔ)類(lèi)都在這里。稍微高級(jí)一點(diǎn)的 IBasicBolt 接口也在這里,該接口是一種實(shí)現(xiàn)基本的 bolt 的簡(jiǎn)單方式。
backtype.storm.transactional: 事務(wù)型拓?fù)涞膶?shí)現(xiàn)。
backtype.storm.tuple: Storm tuple 數(shù)據(jù)模型的實(shí)現(xiàn)。
backtype.storm.utils: 整個(gè)代碼庫(kù)中通用的數(shù)據(jù)結(jié)構(gòu)和各種工具類(lèi)。
Clojure namespaces
譯者注:Clojure 部分內(nèi)容暫不提供翻譯。
總結(jié)
以上是生活随笔為你收集整理的Apache Storm 官方文档 —— 源码组织结构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: android: 播放音频
- 下一篇: 一个word文档中,多个表格的批量调整(