第三階段:數據存儲與計算(離線場景):3.4 數據採集flume

概要

Apache Flume 是一個分佈式,可靠且可用的系統,用於有效地從許多不同的源收集、聚合和移動大量日誌數據到一個集中式的數據存儲區。

 

Flume 的使用不只限於日誌數據。因爲數據源可以定製,flume 可以被用來傳輸大量事件數據,這些數據不僅僅包括網絡通訊數據、社交媒體產生的數據、電子郵件信息等等。

 

Apache Flume 是 Apache 基金會的頂級項目,在加入 Apache 之前由 cloudera 公司開發以及維護。Apache Flume 目前有兩種主版本: 0.9.x 和 1.x。 其中 0.9.x 是歷史版本,我們稱之爲 Flume OG(original generation)。2011 年 10 月 22 號,cloudera 完成了 Flume-728,對 Flume 進行了里程碑式的改動:重構核心組件、核心配置以及代碼架構,重構後的版本統稱爲 Flume NG(next generation),也就是這裏說的 1.x 版本。

 

本文主要對 Flume 的作用以及核心概念進行介紹,通過本文讀者可以大致瞭解 flume 的使用場景、核心組件以及各組件的運行機制。關於如何配置 flume 以適應不同場景,我們會在另一篇文章中詳細解讀。

 

架構

 

數據流模型

一個 Flume 事件被定義爲一個數據流單元。Flume agent 其實是一個 JVM 進程,該進程中包含完成任務所需要的各個組件,其中最核心的三個組件是 Source、Chanel 以及 Slink。

 

 

Source 消費由外部源(如Web服務器)傳遞給它的事件。外部源以一定的格式發送數據給 Flume,這個格式的定義由目標 Flume Source 來確定。例如,一個 Avro Flume source 可以從 Avro(Avro是一個基於二進制數據傳輸的高性能中間件,是 hadoop 的一個子項目) 客戶端接收 Avro 事件,也可以從其他 Flume agents (該 Flume agents 有 Avro sink)接收 Avro 事件。 同樣,我們可以定義一個 Thrift Flume Source 接收來自 Thrift Sink、Flume Thrift RPC 客戶端或者其他任意客戶端(該客戶端可以使用任何語言編寫,只要滿足 Flume thrift 協議)的事件。

 

channel 可以理解爲緩存區,用來保存從 Source 那拿到的數據,直到 Flume slink 將數據消費。file chanel 是一個例子,它將數據保存在文件系統中(當然你可以將數據放在內存中)。

 

slink 從 channel 消費完數據就會將數據從 channel 中清除,隨後將數據放到外部存儲系統例如 HDFS (使用 Flume HDFS sink)或發送到其他 Flume agent 的 source 中。不管是 Source 還是 Slink 都是異步發送和消費數據。

 

複雜的流

 

Flume 允許用戶構建一個複雜的數據流,比如數據流經多個 agent 最終落地。It also allows fan-in and fan-out flows, contextual routing and backup routes (fail-over) for failed hops.

 

可靠性

 

事件被存儲在每個 agent 的 channel 中。隨後這些事件會發送到流中的下一個 agent 或者設備存儲中(例如 HDFS)。只有事件已經被存儲在下一個 agent 的 channel 中 或設備存儲中時,當前 channel 纔會清除該事件。這種機制保證了流在端到端的傳輸中具有可靠性。

 

Flume使用事務方法(transactional approach)來保證事件的可靠傳輸。在 source 和 slink 中,事件的存儲以及恢復作爲事務進行封裝,存放事件到 channel 中以及從 channel 中拉取事件均是事務性的。這保證了流中的事件在節點之間傳輸是可靠的。

 

可恢復

 

事件在 channel 中進行,該 channel 負責保障事件從故障中恢復。Flume 支持一個由本地文件系統支持的持久化文件(文件模式:channel.type = "file") channel。同樣也支持內存模式(channel.type = "memmory"),即將事件保存在內存隊列中。顯然,內存模式相對與文件模型性能會更好,但是當 agent 進程不幸掛掉時,內存模式下存儲在 channel 中的事件將丟失,無法進行恢復。

 

構建

構建一個 agent

 

Flume agent 的配置保存在一個本地配置文件中。它是一個 text 文本,java 程序可以直接方便地讀取其屬性。可以在同一配置文件中指定一個或多個 agent 的配置。配置文件指定了 agnet 中每個 source、channel、slink 的屬性,以及三者如何組合形成數據流。

 

配置單個組件

 

流中的每一個組件(source、channel、slink)都有自己的名稱、類型以及一系列配置屬性。例如,一個 Avro source 需要配置 hostname (或者 IP 地址)以及端口號來接收數據。一個內存模式 channel 可以有最大隊列長度的屬性("capacity": channel 中最大容納多少事件)。一個 HDFS slink 則需要知道文件系統的 URL(hdfs://****)、文件落地的路徑、文件回滾的評率("hdfs.rollInterval": 每隔多少秒將零時文件回滾成最終文件保存到 HDFS 中)。所有這些關於各個組件的屬性需要在配置文件中進行指定。

 

將各個部分組合起來

 

Agent 需要知道加載哪些組件以及如何將這些組件組合起來形成數據流。Flume 指定每個組件的名稱(source、channel、slink),同時明確地告訴我們 channel 與 哪些 source 和 slink 連接,這樣各個組件就能組合起來。例如,一個叫 "avroWeb" 的 source 通過一個叫 "file-channel" 的channel 將事件傳遞到 HDFS sink 中。配置文件需包含這些組件的名稱以及組合關係。

 

開始一個 agent

 

我們可以通過 Flume bin 目錄下的腳本文件(flume-ng)來啓動 agent。在命令後面,你需要指定 agent 的名稱、配置文件:

$ bin/flume-ng agent -n $agent_name -c conf -f conf/flume-conf.properties.template

運行以上命令,agent 將會按照配置文件裏描述的方式來運行組件。

 

一個簡單的示例

 

這裏,我們給出一個配置文件的示例,該示例爲 flume 單節點部署的配置方式。

# example.conf: A single-node Flume configuration

 

# Name the components on this agent

a1.sources = r1

a1.sinks = k1

a1.channels = c1

 

# Describe/configure the source

a1.sources.r1.type = netcat

a1.sources.r1.bind = localhost

a1.sources.r1.port = 44444

 

# Describe the sink

a1.sinks.k1.type = logger

 

# Use a channel which buffers events in memory

a1.channels.c1.type = memory

a1.channels.c1.capacity = 1000

a1.channels.c1.transactionCapacity = 100

 

# Bind the source and sink to the channel

a1.sources.r1.channels = c1

a1.sinks.k1.channel = c1

 

看看這個配置文件,我們可以發現這個 agent 的名稱是 a1。其中該 agent 的 source 監聽 44444 端口。channel 採用內存模式,而 slink 直接輸出數據到 控制檯上(logger)。配置文件指定了各個組件的名稱,並描述了它們的類型以及其他屬性。當然,一個配置文件可以配置多個 agent 屬性,當希望運行指定 agent 進程時,我們需要在命令行中顯示的給出該 agent 的名稱:

$ bin/flume-ng agent --conf conf --conf-file example.conf --name a1 -Dflume.root.logger=INFO,console

 

注意,在實際部署中,我們通常會包含一個選項: --conf-file = 。 目錄將包含一個 shell 腳本 flume-env.sh 以及一個 log4j 屬性文件。 在這個例子中,我們傳遞一個 Java 選項來強制 Flume 將日誌輸出到控制檯。

 

下面的例子中,我們可以遠程 telnet 訪問 44444 端口來向 agent 發送數據:

$ telnet localhost 44444

Trying 127.0.0.1...

Connected to localhost.localdomain (127.0.0.1).

Escape character is '^]'.

Hello world! <ENTER>

OK

 

agent 進程的控制檯將會打印通過 telnet 發送的數據:

12/06/19 15:32:19 INFO source.NetcatSource: Source starting

12/06/19 15:32:19 INFO source.NetcatSource: Created serverSocket:sun.nio.ch.ServerSocketChannelImpl[/127.0.0.1:44444]

12/06/19 15:32:34 INFO sink.LoggerSink: Event: { headers:{} body: 48 65 6C 6C 6F 20 77 6F 72 6C 64 21 0D Hello world!. }

 

完成這一步,恭喜你已經成功地配置以及部署一個 flume agent。

 

數據獲取(Data ingestion)

 

Flume 支持許多從外部源獲取數據的機制。

 

RPC

 

一個 Avro client 可以使用 rpc 機制發送指定的文件到 source 中:

$ bin/flume-ng avro-client -H localhost -p 41414 -F /usr/logs/log.10

 

上面的命令會將 /usr/logs/log.10 發送到監聽 41414 端口的 source 上。

 

網絡流(Network streams)

 

Flume 支持從一些流行的日誌流中讀取數據,例如:

  • Avro
  • Thrift
  • Syslog
  • Netcat

設置多 agent 流(Setting multi-agent flow)

 

Flume 支持將多個 agent 串聯起來,完成這項操作。

合併(Consolidation)

 

當需要從衆多主機上收集日誌信息時,我們可以在每臺主機上部署 agent,這些主機的 slink 均連接到最終日誌落地主機的 source 上。落地主機將所有數據進行組合,落地到 HDFS 上。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章