目前業界大概這麼幾個開源的分布式日誌系統,notify+rsync,Facebook 的Scribe,apache的chukwa,linkin的kafa和cloudera的flume。對這幾款開源分布式日誌系統的比較,參見這篇文章,講的比較細緻http://dongxicheng.org/search-engine/log-systems/之所以自己設計一台這麼一個平台,而沒有採用開源,主要是基於這麼考慮 1、以上這幾種開源日誌系統,雖然提供了日誌tail即時輸出的功能,但是在tail進程宕掉後,無法從收集的點開始收集,只能重新開始,這樣有很多重複的日誌 2、這幾種開源的日誌系統功能比較全面,但是對我們平台來說,只用部分的功能,設計一個簡單可用可控的平台是我們的一個目標這篇文章講述了筆者以前自己設計的一個日誌收集平台的技術細節,在電商開放平台中有應用到。應用情境是這樣的,平台中各個應用用戶端會即時產生大量的日誌,需要即時把各個應用用戶端的日誌收集起來,發送到Distributed File System中,供後續的資料採礦和分析。資料會收集到HDFS中,每天定時產生一個檔案(檔案首碼為日期,尾碼為序號從0開始),並且當檔案的大小超多一定大小時,自動產生一個新的檔案,檔案首碼為當前日期,尾碼為當前序號遞增。系統的運行架構圖,以及相關說明 說明如下:1、首先啟動一個日誌掃描線程(掃描日誌目錄),當有本地記錄檔產生的時,會產生一個日誌tail任務,放到日誌tail隊列中等待調度。2、對任務隊列中的tail任務從線程池擷取一個tail線程,該線程的職責是tail記錄檔,輸出到MQ中。在輸出到MQ的同時,把當前的行號LSN記錄到LSN Store中, 這裡有一個考慮是如果日誌tail線程宕掉,可以從宕掉時的日誌行開始tail(seek操作)。3、Collector節點啟動多個線程從MQ中擷取日誌資料,並梳理日誌的類別(動作記錄,訪問日誌,業務日誌等),根據不同的類型寫到HDFS中不同的檔案。如果在寫入過程中,出現錯誤(比如HDFS暫時不可訪問,這裡有警示機制),那麼就暫存在本地,等待恢複正常後,大量匯入到HDFS中。4、Lsn記錄器,記錄日誌當前tail到哪一行了,在tail時,先寫入Lsn Buffer中,是append方式,當超過一定的100M大小或者一定時間間隔時,就寫到LSN File,唯寫最後的行號,並清除buffer。 這樣做的好處是,append資料到buffer(而不是update操作)的記憶體操作非常快。宕機恢複,在查詢時,先從buffer尋找,如果buffer中不存在,再從File中尋找。5、對於HDFS檔案名稱的切換按照以下策略進行 每天定時產生一個檔案(檔案首碼為日期,尾碼為序號從0開始),並且當檔案的大小超多一定大小時,自動產生一個新的檔案,文 件首碼為當前日期,尾碼為當前序號遞增。 實現了兩個Trigger,分別為SizeTriger(在調用HDFS輸出資料流寫的同時,count該流已經寫入的大小總和,若超過一定大小,則建立新的檔案和輸出資料流,寫入操作指向新的輸出資料流,同時close以前的輸出資料流)和TimeTriger(開啟定時器,當到達該點時,自動建立新的檔案和輸出資料流,新的寫入重新導向到該流中,同時close以前的輸出資料流)。 附帶HDFS flush寫資料說明:HDFS操作過程中,只有在流flush(當資料包滿的時,會自動flush;或者手動flush)和關閉的時候,才真正的寫資料到datenode的硬碟上,那麼對於HDFS來講,預設的packet是64K,當超過資料超過64K時,會自動進行輸出到dataNode的輸出資料流中。調用close時候,會自動把未構成一個packet的資料,也輸出到dataNode輸出資料流中寫到datanode硬碟,完成後彙報給NameNode(當然datanode中的資料大小超過一個塊如64M的時候,也會向NameNode彙報)