1. 背景介紹
許多公司的平台每天會産生大量的日志(一般為流式資料,如,搜尋引擎的pv,查詢等),處理這些日志需要特定的日志系統,一般而言,這些系統需要具有以下特征:
(1) 建構應用系統和分析系統的橋梁,并将它們之間的關聯解耦;
(2) 支援近實時的線上分析系統和類似于Hadoop之類的離線分析系統;
(3) 具有高可擴充性。即:當資料量增加時,可以通過增加節點進行水準擴充。
本文從設計架構,負載均衡,可擴充性和容錯性等方面對比了當今開源的日志系統,包括facebook的scribe,apache的chukwa,linkedin的kafka和cloudera的flume等。
2. FaceBook的Scribe
Scribe是facebook開源的日志收集系統,在facebook内部已經得到大量的應用。它能夠從各種日志源上收集日志,存儲到一個中央存儲系統 (可以是NFS,分布式檔案系統等)上,以便于進行集中統計分析處理。它為日志的“分布式收集,統一處理”提供了一個可擴充的,高容錯的方案。
它最重要的特點是容錯性好。當後端的存儲系統crash時,scribe會将資料寫到本地磁盤上,當存儲系統恢複正常後,scribe将日志重新加載到存儲系統中。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiInBnaugzMzcDN4EzMzMDM2ETNw8CX3ADNxAjMvw1MzUTOxEzLcl2Lc12bj5ycn9Gbi52YuAzcldWYtl2Lc9CX6MHc0RHaiojIsJye.jpg)
架構:
scribe的架構比較簡單,主要包括三部分,分别為scribe agent, scribe和存儲系統。
(1) scribe agent
scribe agent實際上是一個thrift client。 向scribe發送資料的唯一方法是使用thrift client, scribe内部定義了一個thrift接口,使用者使用該接口将資料發送給server。
(2) scribe
scribe接收到thrift client發送過來的資料,根據配置檔案,将不同topic的資料發送給不同的對象。scribe提供了各種各樣的store,如 file, HDFS等,scribe可将資料加載到這些store中。
(3) 存儲系統
存儲系統實際上就是scribe中的store,目前scribe支援非常多的store,包括file(檔案),buffer(雙層存儲,一個主儲存,一個副存儲),network(另一個scribe伺服器),bucket(包含多個 store,通過hash的将資料存到不同store中),null(忽略資料),thriftfile(寫到一個Thrift TFileTransport檔案中)和multi(把資料同時存放到不同store中)。
3. Apache的Chukwa
chukwa是一個非常新的開源項目,由于其屬于hadoop系列産品,因而使用了很多hadoop的元件(用HDFS存儲,用mapreduce處理資料),它提供了很多子產品以支援hadoop叢集日志分析。
需求:
(1) 靈活的,動态可控的資料源
(2) 高性能,高可擴充的存儲系統
(3) 合适的架構,用于對收集到的大規模資料進行分析
Chukwa中主要有3種角色,分别為:adaptor,agent,collector。
(1) Adaptor 資料源
可封裝其他資料源,如file,unix指令行工具等
目前可用的資料源有:hadoop logs,應用程式度量資料,系統參數資料(如linux cpu使用流率)。
(2) HDFS 存儲系統
Chukwa采用了HDFS作為存儲系統。HDFS的設計初衷是支援大檔案存儲和小并發高速寫的應用場景,而日志系統的特點恰好相反,它需支援高并發低速率的寫和大量小檔案的存儲。需要注意的是,直接寫到HDFS上的小檔案是不可見的,直到關閉檔案,另外,HDFS不支援檔案重新打開。
(3) Collector和Agent
為了克服(2)中的問題,增加了agent和collector階段。
Agent的作用:給adaptor提供各種服務,包括:啟動和關閉adaptor,将資料通過HTTP傳遞給Collector;定期記錄adaptor狀态,以便crash後恢複。
Collector的作用:對多個資料源發過來的資料進行合并,然後加載到HDFS中;隐藏HDFS實作的細節,如,HDFS版本更換後,隻需修改collector即可。
(4) Demux和achieving
直接支援利用MapReduce處理資料。它内置了兩個mapreduce作業,分别用于擷取data和将data轉化為結構化的log。存儲到data store(可以是資料庫或者HDFS等)中。
4. LinkedIn的Kafka
Kafka是2010年12月份開源的項目,采用scala語言編寫,使用了多種效率優化機制,整體架構比較新穎(push/pull),更适合異構叢集。
設計目标:
(1) 資料在磁盤上的存取代價為O(1)
(2) 高吞吐率,在普通的伺服器上每秒也能處理幾十萬條消息
(3) 分布式架構,能夠對消息分區
(4) 支援将資料并行的加載到hadoop
Kafka實際上是一個消息釋出訂閱系統。producer向某個topic釋出消息,而consumer訂閱某個topic的消息,進而一旦有新的關于某個topic的消息,broker會傳遞給訂閱它的所有consumer。 在kafka中,消息是按topic組織的,而每個topic又會分為多個partition,這樣便于管理資料和進行負載均衡。同時,它也使用了zookeeper進行負載均衡。
Kafka中主要有三種角色,分别為producer,broker和consumer。
(1) Producer
Producer的任務是向broker發送資料。Kafka提供了兩種producer接口,一種是low_level接口,使用該接口會向特定的broker的某個topic下的某個partition發送資料;另一種那個是high level接口,該接口支援同步/異步發送資料,基于zookeeper的broker自動識别和負載均衡(基于Partitioner)。
其中,基于zookeeper的broker自動識别值得一說。producer可以通過zookeeper擷取可用的broker清單,也可以在zookeeper中注冊listener,該listener在以下情況下會被喚醒:
a.添加一個broker
b.删除一個broker
c.注冊新的topic
d.broker注冊已存在的topic
當producer得知以上時間時,可根據需要采取一定的行動。
(2) Broker
Broker采取了多種政策提高資料處理效率,包括sendfile和zero copy等技術。
(3) Consumer
consumer的作用是将日志資訊加載到中央存儲系統上。kafka提供了兩種consumer接口,一種是low level的,它維護到某一個broker的連接配接,并且這個連接配接是無狀态的,即,每次從broker上pull資料時,都要告訴broker資料的偏移量。另一種是high-level 接口,它隐藏了broker的細節,允許consumer從broker上push資料而不必關心網絡拓撲結構。更重要的是,對于大部分日志系統而言,consumer已經擷取的資料資訊都由broker儲存,而在kafka中,由consumer自己維護所取資料資訊。
5. Cloudera的Flume
Flume是cloudera于2009年7月開源的日志系統。它内置的各種元件非常齊全,使用者幾乎不必進行任何額外開發即可使用。
(1) 可靠性
當節點出現故障時,日志能夠被傳送到其他節點上而不會丢失。Flume提供了三種級别的可靠性保障,從強到弱依次分别為:end-to-end(收到資料agent首先将event寫到磁盤上,當資料傳送成功後,再删除;如果資料發送失敗,可以重新發送。),Store on failure(這也是scribe采用的政策,當資料接收方crash時,将資料寫到本地,待恢複後,繼續發送),Best effort(資料發送到接收方後,不會進行确認)。
(2) 可擴充性
Flume采用了三層架構,分别問agent,collector和storage,每一層均可以水準擴充。其中,所有agent和collector由master統一管理,這使得系統容易監控和維護,且master允許有多個(使用ZooKeeper進行管理和負載均衡),這就避免了單點故障問題。
(3) 可管理性
所有agent和colletor由master統一管理,這使得系統便于維護。使用者可以在master上檢視各個資料源或者資料流執行情況,且可以對各個資料源配置和動态加載。Flume提供了web 和shell script command兩種形式對資料流進行管理。
(4) 功能可擴充性
使用者可以根據需要添加自己的agent,colletor或者storage。此外,Flume自帶了很多元件,包括各種agent(file, syslog等),collector和storage(file,HDFS等)。
正如前面提到的,Flume采用了分層架構,由三層組成,分别為agent,collector和storage。其中,agent和collector均由兩部分組成:source和sink,source是資料來源,sink是資料去向。
(1) agent
agent的作用是将資料源的資料發送給collector,Flume自帶了很多直接可用的資料源(source),如:
text(“filename”):将檔案filename作為資料源,按行發送
tail(“filename”):探測filename新産生的資料,按行發送出去
fsyslogTcp(5140):監聽TCP的5140端口,并且接收到的資料發送出去
同時提供了很多sink,如:
console[("format")] :直接将将資料顯示在桌面上
text(“txtfile”):将資料寫到檔案txtfile中
dfs(“dfsfile”):将資料寫到HDFS上的dfsfile檔案中
syslogTcp(“host”,port):将資料通過TCP傳遞給host節點
(2) collector
collector的作用是将多個agent的資料彙總後,加載到storage中。它的source和sink與agent類似。
下面例子中,agent監聽TCP的5140端口接收到的資料,并發送給collector,由collector将資料加載到HDFS上。
| |
|
| |
一個更複雜的例子如下:
有6個agent,3個collector,所有collector均将資料導入HDFS中。agent A,B将資料發送給collector A,agent C,D将資料發送給collectorB,agent C,D将資料發送給collectorB。同時,為每個agent添加end-to-end可靠性保障(Flume的三種可靠性保障分别由agentE2EChain, agentDFOChain, and agentBEChain實作),如,當collector A出現故障時,agent A和agent B會将資料分别發給collector B和collector C。
下面是簡寫的配置檔案片段:
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
此外,使用autoE2EChain,當某個collector 出現故障時,Flume會自動探測一個可用collector,并将資料定向到這個新的可用collector上。
(3) storage
storage是存儲系統,可以是一個普通file,也可以是HDFS,HIVE,HBase等。
6. 總結
根據這四個系統的架構設計,可以總結出典型的日志系統需具備三個基本元件,分别為agent(封裝資料源,将資料源中的資料發送給collector),collector(接收多個agent的資料,并進行彙總後導入後端的store中),store(中央存儲系統,應該具有可擴充性和可靠性,應該支援目前非常流行的HDFS)。
下面表格對比了這四個系統:
7. 參考資料
scribe首頁:https://github.com/facebook/scribe
chukwa首頁:http://incubator.apache.org/chukwa/
kafka首頁:http://sna-projects.com/kafka/
Flume首頁:https://github.com/cloudera/flume/
來自:http://my.oschina.net/sunzy/blog/183795