基於Flume的美團日誌收集系統 二 改進和優化

2021-07-11 19:07:53 字數 4436 閱讀 8644

來自:美團技術部落格

在《基於flume的美團日誌收集系統(一)架構和設計》中,我們詳述了基於flume的美團日誌收集系統的架構設計,以及為什麼做這樣的設計。在本節中,我們將會講述在實際部署和使用過程中遇到的問題,對flume的功能改進和對系統做的優化。

在flume的使用過程中,遇到的主要問題如下:

a. channel「水土不服」:使用固定大小的memorychannel在日誌高峰時常報佇列大小不夠的異常;使用filechannel又導致io繁忙的問題;

b. hdfssink的效能問題:使用hdfssink向hdfs寫日誌,在高峰時間速度較慢;

c. 系統的管理問題:配置公升級,模組重啟等;

從上面的問題中可以看到,有一些需求是原生flume無法滿足的,因此,基於開源的flume我們增加了許多功能,修改了一些bug,並且進行一些調優。下面將對一些主要的方面做一些說明。

一方面,flume本身提供了http, ganglia的監控服務,而我們目前主要使用zabbix做監控。因此,我們為flume新增了zabbix監控模組,和sa的監控服務無縫融合。

另一方面,淨化flume的metrics。只將我們需要的metrics傳送給zabbix,避免 zabbix server造成壓力。目前我們最為關心的是flume能否及時把應用端傳送過來的日誌寫到hdfs上, 對應關注的metrics為:

首先,我們的hdfssink寫到hadoop的檔案採用lzo壓縮儲存。 hdfssink可以讀取hadoop配置檔案中提供的編碼類列表,然後通過配置的方式獲取使用何種壓縮編碼,我們目前使用lzo壓縮資料。採用lzo壓縮而非bz2壓縮,是基於以下測試資料:

event大小(byte)

sink.batch-size

hdfs.batchsize

壓縮格式

總資料大小(g)

耗時(s)

平均events/s

壓縮後大小(g)

544300

10000

bz29.1

2448

6833

1.36

544300

10000

lzo9.1

61227333

3.49

其次,我們的hdfssink增加了建立lzo檔案後自動建立index功能。hadoop提供了對lzo建立索引,使得壓縮檔案是可切分的,這樣hadoop job可以並行處理資料檔案。hdfssink本身lzo壓縮,但寫完lzo檔案並不會建索引,我們在close檔案之後新增了建索引功能。

/**

* rename bucketpath file from .tmp to permanent location.

*/private void renamebucket() throws ioexception, interruptedexception

final path srcpath = new path(bucketpath);

final path dstpath = new path(targetpath);

callwithtimeout(new callrunner()

}return null;

}});

}

我們在hdfssink和dualchannel中增加開關,當開關開啟的情況下,hdfssink不再往hdfs上寫資料,並且資料只寫向dualchannel中的filechannel。以此策略來防止hdfs的正常停機維護。

flume本身提供了memorychannel和filechannel。memorychannel處理速度快,但快取大小有限,且沒有持久化;filechannel則剛好相反。我們希望利用兩者的優勢,在sink處理速度夠快,channel沒有快取過多日誌的時候,就使用memorychannel,當sink處理速度跟不上,又需要channel能夠快取下應用端傳送過來的日誌時,就使用filechannel,由此我們開發了dualchannel,能夠智慧型的在兩個channel之間切換。

其具體的邏輯如下:

/***

* puttomemchannel indicate put event to memchannel or filechannel

* takefrommemchannel indicate take event from memchannel or filechannel

* */

private atomicboolean puttomemchannel = new atomicboolean(true);

private atomicboolean takefrommemchannel = new atomicboolean(true);

void doput(event event)

} else

}event dotake()

} else

}return event;

}

flume提供了nullsink,可以把不需要的日誌通過nullsink直接丟棄,不進行儲存。然而,source需要先將events存放到channel中,nullsink再將events取出扔掉。為了提公升效能,我們把這一步移到了channel裡面做,所以開發了nullchannel。

為支援向storm提供實時資料流,我們增加了kafkasink用來向kafka寫實時資料流。其基本的邏輯如下:

public class kafkasink extends abstractsink implements configurable 

@override

public synchronized void start()

@override

public synchronized void stop()

@override

public status process() throws eventdeliveryexception catch (exception e) finally

return status;}}

scribed在通過scribesource傳送資料報給flume時,大於4096位元組的包,會先傳送乙個dummy包檢查伺服器的反應,而flume的scribesource對於logentry.size()=0的包返回try_later,此時scribed就認為出錯,斷開連線。這樣迴圈反覆嘗試,無法真正傳送資料。現在在scribesource的thrift介面中,對size為0的情況返回ok,保證後續正常傳送資料。

hdfssink的path引數指明了日誌被寫到hdfs的位置,該引數中可以引用格式化的引數,將日誌寫到乙個動態的目錄中。這方便了日誌的管理。例如我們可以將日誌寫到category分類的目錄,並且按天和按小時存放:

lc.sinks.sink_hdfs.hdfs.path = /user/hive/work/orglog.db/%/dt=%y%m%d/hour=%h
hdfss ink中處理每條event時,都要根據配置獲取此event應該寫入的hdfs path和filename,預設的獲取方法是通過正規表示式替換配置中的變數,獲取真實的path和filename。因為此過程是每條event都要做的操作,耗時很長。通過我們的測試,20萬條日誌,這個操作要耗時6-8s左右。

由於我們目前的path和filename有固定的模式,可以通過字串拼接獲得。而後者比正則匹配快幾十倍。拼接定符串的方式,20萬條日誌的操作只需要幾百毫秒。

在我們初始的設計中,所有的日誌都通過乙個channel和乙個hdfssink寫到hdfs上。我們來看一看這樣做有什麼問題。

首先,我們來看一下hdfssink在傳送資料的邏輯:

//從channel中取batchsize大小的events

for (txneventcount = 0; txneventcount < batchsize; txneventcount++) {

}for (bucketwriter bucketwriter : writers) {

//然後對每乙個bucketwriter呼叫相應的flush方法將資料flush到hdfs上

bucketwriter.flush();

其次,對於我們的日誌來說,基本符合80/20原則。即20%的category產生了系統80%的日誌量。這樣對大部分日誌來說,每20萬條可能只包含幾條日誌,也需要往hdfs上flush一次。

上述的情況會導致hdfssink寫hdfs的效率極差。下圖是單channel的情況下每小時的傳送量和寫hdfs的時間趨勢圖。

鑑於這種實際應用場景,我們把日誌進行了大小歸類,分為big, middle和small三類,這樣可以有效的避免小日誌跟著大日誌一起頻繁的flush,提公升效果明顯。下圖是分佇列後big佇列的每小時的傳送量和寫hdfs的時間趨勢圖。

目前,flume日誌收集系統提供了乙個高可用,高可靠,可擴充套件的分布式服務,已經有效地支援了美團的日誌資料收集工作。

後續,我們將在如下方面繼續研究:

基於Flume的美團日誌收集系統 二 改進和優化

dju alex 2013 12 09 22 35 在 基於flume的美團日誌收集系統 一 架構和設計 中,我們詳述了基於flume的美團日誌收集系統的架構設計,以及為什麼做這樣的設計。在本節中,我們將會講述在實際部署和使用過程中遇到的問題,對flume的功能改進和對系統做的優化。在flume的使...

基於Flume的美團日誌收集系統 二 改進和優化

在 基於flume的美團日誌收集系統 一 架構和設計 中,我們詳述了基於flume的美團日誌收集系統的架構設計,以及為什麼做這樣的設計。在本節中,我們將會講述在實際部署和使用過程中遇到的問題,對flume的功能改進和對系統做的優化。在flume的使用過程中,遇到的主要問題如下 a.channel 水...

基於Flume的日誌收集系統方案參考

示例圖如下 說明 每個日誌源 http上報 日誌檔案等 對應乙個agent c用於收集對應日誌,收集來的日誌可以流到agent s 1或agent s 2 agent c的sink處理器採用輪詢負載均衡策略,一方面可以分擔壓力,另一方面可增加系統可用性,即使乙個agent s出現故障,系統可正常執行...