flume 1.8.0 開發基礎
本文由雲+社群發表
作者:皮皮熊
概述
Apache Flume是一個用於高效地從大量異構資料來源收集、聚合、傳輸到一個集中式資料儲存的分散式、高可靠、高可用的系統。
Apache Flume是Apache基金會的頂級專案。現在有兩個程式碼版本線可以獲取:0.9.x和1.x。本文件對應的是1.x版本。
資料流模型
Event是流經flume agent的最小資料單元。一個Event(由Event介面實現)從source流向channel,再到sink。Event包含了一個payload(byte array)和可選的header(string attributes)。一個flume agent就是一個jvm下的程式:控制著Events從一個外部的源頭到一個外部的目的地。
Source消費著具有特殊格式的Events(這些Event傳遞到Source通過像Web server這樣外在的資料來源)。例如AvroSource可以被用於接收Avro的Events,從本客戶端或者其他執行中的flume客戶端。當一個Source接收到一個Event,它會把它插入到一個或者多個Channel裡。Channel會被動地儲存這些Event直到它們被一個Sink消費到。Flume中一種Channel是FileChannel,其使用檔案系統來作為後端儲存。Sink需要負責任地將一個Event從Channel中移除,並將其放入像hdfs一樣的外部儲存系統(例如HDFSEventSink),或者轉發到傳輸中下一個節點的source中。Source和Sink在agent中非同步地互動Channel中的Event。
可靠性
Event是儲存在Flume agent的Channel裡。Sink的責任就是傳輸Event到下一個agent或者最終的儲存系統(像hdfs)。Sink只有當Event寫入下一個agent的Channel 或者 儲存到最終的系統時才會從channel裡面刪掉Event。這就是Flume如何在單跳訊息傳輸中提供端到端的可靠性。Flume提供了一個事務性的方法來修復可靠傳輸中的Event。Source和Sink包含了Event的儲存和重試(通過由channel提供的事務)。
構建Flume
獲取原始碼
通過git
編譯/測試 Flume
Flume使用maven來build。你可以通過標準的maven命令列來編譯Flume。
- 僅編譯:mvn clean compile
- 編譯且執行單元測試:mvn clean test
- 執行獨立的測試:mvn clean test -Dtest=
, ,... -DfailIfNoTests=false - 打包:mvn clean install
- 打包(忽略單元測試):mvn clean install -DskipTests
注意:Flume build需要在path中有Google Protocol Buffers編譯器。
更新Protocol Buffer版本
File channel依賴Protocol Buffer。當你想更新Protocol Buffer版本時,你需要如下更新使用到Protocol Buffer的data access類:
- 本機安裝你想要的PB版本
- 更新pom.xml中PB的版本
- 生成flume中新的PB data access類:cd flume-ng-channels/flume-file-channel; mvn -P compile-proto clean package -DskipTests
- 在所有生成檔案中加上Apache license(如果缺了的話)
- rebuild及測試Flume:cd ../..; mvn clean install
開發自定義部分
client
Client在Event產生時運轉,並將他們傳遞到Flume的agent。Client通常執行在應用消費資料的程式空間中。Flume目前支援Avro, log4j, syslog, 以及 Http POST (with a JSON body)方式從外部資料來源傳輸資料。同時ExecSource支援將本地程式的輸出作為Flume的輸入。
可能已有的方案是不夠的。本案例中你可以使用自定義的方法來向flume傳送資料。這裡有兩種方法來實現。第一:寫一個自定義的客戶端來和flume已有的source互動,像AvroSource 或者 SyslogTcpSource。此時Client需要將資料轉換成這些Source能理解的message。另外一個方案:寫一個自定義的Flume Source,通過IPC或者RPC,直接地和已有的client應用通訊(需要將client的資料轉換成Flume的Event)。注意這些儲存在flume agent channel中的事件,必須以Flume Event形式存在。
Client SDK
儘管Flume包含了一系列內建的,用於接收資料的方法(即Source),人們常常想直接地通過flume和自定義的程式進行通訊。Flume SDK 就是這樣一個lib,它可以通過RPC直接地連線到Flume,並且傳送到Flume的資料流。
RPC客戶端介面
一個RPC客戶端介面的實現,包含了支援Flume的RPC方法。使用者的程式可以簡單地呼叫Flume SDK客戶端的append(Event)或者appendBatch(List
Transaction(事務)介面
Transaction介面是Flume可靠性的基礎。所有主要元件(即source,sink和channel)必須使用Flume Transaction。
Transaction在channel的實現中實現。每個source和sink連線到channel時必須要得到一個channnel的物件。Source使用channnelprocessor來管理transaction。sink明確地通過他們配置的channel來管理transaction。儲存一個事件(把他們放入channnel中)或者抽取一個事件(從channnel中取出)在一個啟用的transaction中完成。例如:
Channel ch = new MemoryChannel();
Transaction txn = ch.getTransaction();
txn.begin();
try {
// This try clause includes whatever Channel operations you want to do
Event eventToStage = EventBuilder.withBody("Hello Flume!",
Charset.forName("UTF-8"));
ch.put(eventToStage);
// Event takenEvent = ch.take();
// ...
txn.commit();
} catch (Throwable t) {
txn.rollback();
// Log exception, handle individual exceptions as needed
// re-throw all Errors
if (t instanceof Error) {
throw (Error)t;
}
} finally {
txn.close();
}
在這裡,我們從channel獲取transaction。在begin()返回後,Transaction現在處於活動/開啟狀態,然後將Event放入Channel中。如果put成功,則提交併關閉Transaction。
Sink
Sink的目的就是從Channel中提取事件並將其轉發到傳輸中的下一個Flume Agent或將它們儲存在外部儲存庫中。根據Flume屬性檔案中的配置,接收器只與一個通道關聯。每個已配置的Sink都有一個SinkRunner例項,當Flume框架呼叫SinkRunner.start()時,會建立一個新執行緒來驅動Sink(使用SinkRunner.PollingRunner作為執行緒的Runnable),該執行緒管理Sink的生命週期。Sink需要實現start()和stop()方法作為LifecycleAware介面的一部分。
- Sink.start()方法應初始化Sink並將其置於可將事件轉發到其下一個目標的狀態。
- Sink.process()應該執行從Channel提取Event並轉發它的核心處理過程。
- Sink.stop()方法應該進行必要的清理(例如釋放資源)。
Sink實現還需要實現Configurable介面來處理自己的配置設定。例如:
public class MySink extends AbstractSink implements Configurable {
private String myProp;
@Override
public void configure(Context context) {
String myProp = context.getString("myProp", "defaultValue");
// Process the myProp value (e.g. validation)
// Store myProp for later retrieval by process() method
this.myProp = myProp;
}
@Override
public void start() {
// Initialize the connection to the external repository (e.g. HDFS) that
// this Sink will forward Events to ..
}
@Override
public void stop () {
// Disconnect from the external respository and do any
// additional cleanup (e.g. releasing resources or nulling-out
// field values) ..
}
@Override
public Status process() throws EventDeliveryException {
Status status = null;
// Start transaction
Channel ch = getChannel();
Transaction txn = ch.getTransaction();
txn.begin();
try {
// This try clause includes whatever Channel operations you want to do
Event event = ch.take();
// Send the Event to the external repository.
// storeSomeData(e);
txn.commit();
status = Status.READY;
} catch (Throwable t) {
txn.rollback();
// Log exception, handle individual exceptions as needed
status = Status.BACKOFF;
// re-throw all Errors
if (t instanceof Error) {
throw (Error)t;
}
}
return status;
}
}
Source
Source的目的是從外部客戶端接收資料並將其儲存到已配置的Channels中。Source可以獲取其自己的ChannelProcessor的例項來處理在Channel本地事務中提交的序列事件。在exception的情況下,需要Channels傳播異常,則所有Channels將回滾其事務,但先前在其他Channel上處理的事件將保持提交。
與SinkRunner.PollingRunner Runnable類似,有一個PollingRunner Runnable,它在Flume框架呼叫PollableSourceRunner.start()時建立的執行緒上執行。每個配置的PollableSource都與自己執行PollingRunner的執行緒相關聯。該執行緒管理PollableSource的生命週期,例如啟動和停止。
- PollableSource必須實現LifecycleAware介面中宣告的start()和stop()方法。
- PollableSource的執行器呼叫Source的process()方法。 process()方法應檢查新資料並將其作為Flume事件儲存到Channel中。
注意,實際上有兩種型別的Source:已經提到過PollableSource,另一個是EventDrivenSource。與PollableSource不同,EventDrivenSource必須有自己的回撥機制,捕獲新資料並將其儲存到Channel中。EventDrivenSources並不像PollableSources那樣由它們自己的執行緒驅動。下面是一個自定義PollableSource的示例:
public class MySource extends AbstractSource implements Configurable, PollableSource {
private String myProp;
@Override
public void configure(Context context) {
String myProp = context.getString("myProp", "defaultValue");
// Process the myProp value (e.g. validation, convert to another type, ...)
// Store myProp for later retrieval by process() method
this.myProp = myProp;
}
@Override
public void start() {
// Initialize the connection to the external client
}
@Override
public void stop () {
// Disconnect from external client and do any additional cleanup
// (e.g. releasing resources or nulling-out field values) ..
}
@Override
public Status process() throws EventDeliveryException {
Status status = null;
try {
// This try clause includes whatever Channel/Event operations you want to do
// Receive new data
Event e = getSomeData();
// Store the Event into this Source's associated Channel(s)
getChannelProcessor().processEvent(e);
status = Status.READY;
} catch (Throwable t) {
// Log exception, handle individual exceptions as needed
status = Status.BACKOFF;
// re-throw all Errors
if (t instanceof Error) {
throw (Error)t;
}
} finally {
txn.close();
}
return status;
}
}
參考自(Flume 1.8.0 Developer Guide)
flume 1.8.0 文件完整翻譯可見 https://blog.csdn.net/u013128262
此文已由騰訊雲+社群在各渠道釋出
獲取更多新鮮技術乾貨,可以關注我們騰訊雲技術社群-雲加社群官方號及知乎機構號
相關文章
- Flume基礎學習
- PHP 開發基礎PHP
- vxworks開發基礎
- 大資料基礎學習-5.Flume1.6.0大資料
- Solon 1.8.0 釋出,雲原生微服務開發框架微服務框架
- 資料採集元件:Flume基礎用法和Kafka整合元件Kafka
- 機器學習開發流程基礎機器學習
- Go API 開發基礎GoAPI
- 並行開發基礎並行
- 開發基礎知識
- 前端開發基礎-JavaScript前端JavaScript
- Oracle開發基礎-觸發器Oracle觸發器
- 【IOS開發基礎系列】Cocoa基礎專題iOS
- Oracle開發基礎-遊標Oracle
- Vue開發之基礎路由Vue路由
- Javascript模組化開發基礎JavaScript
- 視訊開發基礎篇
- React基礎——更快的開發React
- iOS 基礎開發技巧 (一)iOS
- 微信開發的基礎配置
- plsql開發語言基礎SQL
- Struts2開發基礎
- 蘋果開發基礎知識蘋果
- 小程式開發基礎(一)
- JavaWeb開發基礎Servlet APIJavaWebServletAPI
- .NET 基礎拾遺(5):多執行緒開發基礎執行緒
- iOS開發小記-基礎篇iOS
- 【Java基礎】物件導向開發Java物件
- JavaWEB開發18——基礎加強JavaWeb
- 樹莓派開發—基礎配置樹莓派
- iOS 藍芽開發·基礎篇iOS藍芽
- linux核心模組開發基礎Linux
- iOS 開發之 ReactiveCocoa(基礎)iOSReact
- 嵌入式開發基礎(3)
- PHP 系列:PHP Web 開發基礎PHPWeb
- Mac開發基礎23-NSMenuMac
- Mac開發基礎24-NSToolbarMac
- Mac開發基礎25-NSAlertMac