1. 程式人生 > >Alex 的 Hadoop 菜鳥教程: 第22課 分散式日誌收集元件:flume

Alex 的 Hadoop 菜鳥教程: 第22課 分散式日誌收集元件:flume

本教程的目的:
  1. flume 跟 hadoop 有什麼關係
  2. 介紹flume的結構
  3. 介紹flume的安裝
  4. 做一個簡單的收集網路傳送過來的文字(NetCat Source)並儲存到日誌檔案(Logger Sink)的例子

flume 跟 hadoop 有什麼關係

hadoop是一個分散式系統,跟hadoop配合的一般也是分散式系統,分散式系統帶來的就是分散式日誌,分散式日誌帶來1. 日誌數量多 2. 日誌資料量大, 所以無論是採集分散式的日誌還是儲存海量的日誌到hadoop,都需要一個日誌收集系統,這就是flume。不過其實關係也不是太大,日誌方面沒有太大需求的人其實可以跳過flume的學習


flume 結構

以下是一張解釋flume如何工作的圖


介紹一下概念
Event: 事件是從Flume agent發過來的一個數據流單元。事件從 Source 到 Channel 到 Sink。
Flume agen:  是一個jvm 程序。這個程序負責將外部的來源產生的Event轉發到外部的目的地
Source: 負責消費有特殊格式的Event。這些Event會通過一個外部的來源(比如一個web伺服器)傳遞給Source. 比如一個 AvroSource 用來接收由客戶端或者在同一個流程上其他的Flume agent 發過來的 Avro Event (注意:flume的agent是可以一個接一個的串聯起來的)
當Source接收到Event的時候,它會把Event儲存到Channel(通道)裡面。Channel被動的儲存和保持Event直到Sink消費掉它
打個比方,有一種Channel叫 FileChannel,它使用檔案系統來儲存檔案
Sink:用來從Channel中移除Event,並且把Event放到外部資源庫,比如hdfs(這種Sink叫HDFSEventSink)。或者也可以繼續把Event推送給在同一個流程中的下一個Source。

flume一般是這樣用的


或者是這樣的



安裝 flume

flume有三個元件
flume-ng — flume本身
flume-ng-agent — 把flume agent做成一個服務的指令碼
flume-ng-doc — Flume 文件


$ yum install -y flume-ng flume-ng-agent flume-ng-doc


測試一下
$ flume-ng help


會輸出幫助資訊


使用flume

flume監聽NetCat例子

Step1

介紹下 NetCat Source : 這個source會監聽一個埠,然後把每行通過這個埠發過來的文本當做一個事件傳給channel
介紹下 Logger Sink: 採用日誌的形式來消費Event。日誌級別為INFO
介紹下 Memory Channel : 使用記憶體來暫存Event


$ vim /etc/flume-ng/conf/example.conf


貼上以下文字進example.conf並儲存
# 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

STEP 2 執行 flume

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


如果沒有錯誤的話,shell會保持監聽狀態,此時監聽44444埠


STEP 3 測試 flume

我們新開啟一個ssh連線,然後使用curl 給 44444 埠傳送一條測試文字:"hello world"


$ curl -X GET http://localhost:44444?w=helloworld
OK
OK
OK
OK
OK


這時去看之前監聽的那個ssh視窗會打印出
14/07/04 11:39:12 INFO sink.LoggerSink: Event: { headers:{} body: 47 45 54 20 2F 3F 77 3D 68 65 6C 6C 6F 77 6F 72 GET /?w=hellowor }
14/07/04 11:39:12 INFO sink.LoggerSink: Event: { headers:{} body: 55 73 65 72 2D 41 67 65 6E 74 3A 20 63 75 72 6C User-Agent: curl }
14/07/04 11:39:12 INFO sink.LoggerSink: Event: { headers:{} body: 48 6F 73 74 3A 20 6C 6F 63 61 6C 68 6F 73 74 3A Host: localhost: }
14/07/04 11:39:12 INFO sink.LoggerSink: Event: { headers:{} body: 41 63 63 65 70 74 3A 20 2A 2F 2A 0D             Accept: */*. }
14/07/04 11:39:12 INFO sink.LoggerSink: Event: { headers:{} body: 0D    

以上是flume的最簡單的例子,接下來介紹一個稍微複雜一點,但是真正實用的例子

Flume 收集log4j日誌檔案並寫入hdfs的例子

在這個例子中我們由本機將日誌傳送到host1上,並由host1上的flume將日誌儲存到hdfs上 。架構圖
我們會用到 log4j的一個Appender FlumeAppender 這個外掛,是由Flume開發的適用於log4j的Appender

step1

修改 /etc/flume-ng/conf/flume.conf 的內容為
# source, channel, sink definition
agent.channels = mem-channel
agent.sources = log4j-avro-source
agent.sinks = hdfs-sink

# Channel
# Define a  memory channel called mem-channel on agent
agent.channels.mem-channel.type = memory

# Source
# Define an Avro source called log4j-avro-channel on agent and tell it
# to bind to host1:12345. Connect it to channel mem-channel.
agent.sources.log4j-avro-source.type = avro
agent.sources.log4j-avro-source.bind = 192.168.1.126
agent.sources.log4j-avro-source.port = 12345
agent.sources.log4j-avro-source.channels = mem-channel

# Sink 
# Define a logger sink that simply logs all events it receives
# and connect it to the other end of the same channel.
agent.sinks.hdfs-sink.type = hdfs
agent.sinks.hdfs-sink.hdfs.path = hdfs://mycluster/flume/events/
agent.sinks.hdfs-sink.channel = mem-channel



然後重啟flume
service flume-ng-agent restart

step2

在hdfs上建立flume要寫的資料夾
sudo -u flume hdfs dfs -mkdir -p /flume/events/


step3

建立一個簡單的maven專案叫 play-flume
pom.xml  的內容是
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.crazycake</groupId>
  <artifactId>play-flume</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>play-flume</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
		<dependency>
  		<groupId>log4j</groupId>
  		<artifactId>log4j</artifactId>
  		<version>1.2.17</version>
  	</dependency>
	<dependency>
		<groupId>org.apache.flume.flume-ng-clients</groupId>
		<artifactId>flume-ng-log4jappender</artifactId>
		<version>1.4.0</version>
	</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>${project.artifactId}-${timestamp}</finalName>
		<plugins>
			<!-- compiler -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.5.1</version>
				<inherited>true</inherited>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>

			<!-- jar -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<version>2.4</version>
				<extensions>false</extensions>
				<inherited>true</inherited>
			</plugin>
		</plugins>
	</build>
</project>

增加log4j.properties  到 src/main/resources 資料夾下,如果沒有這個資料夾就自己建一個,並新增到 java build path 作為一個source folder 。
log4j.properties 內容為
# Define the root logger with appender file
log4j.rootLogger = DEBUG, stdout, flume

# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
 
# Define the flume appender
log4j.appender.flume = org.apache.flume.clients.log4jappender.Log4jAppender
log4j.appender.flume.Hostname = host1
log4j.appender.flume.Port = 12345
log4j.appender.flume.UnsafeMode = false
log4j.appender.flume.layout=org.apache.log4j.PatternLayout

建立一個 FlumeLog.java
package org.crazycake.play_flume;

import org.apache.log4j.Logger;

public class FlumeLog {
    public static void main(String[] args)
    {
        Logger logger = Logger.getLogger(App.class);
        logger.info("hello world");
        logger.info("My name is alex");
        logger.info("How are you?");
    }
}


step4

執行 FlumeLog.java ,然後等幾秒鐘就可以看到在 /flume/events 目錄下生成的日誌檔案,不過是序列化成LongWritable 後的日誌,無法直接檢視
你也可以用 HBaseSink 直接把日誌寫到Hbase裡面,這樣就更省事一點,再結合上 Phoenix 可以直接寫SQL日誌查出來,不過就喪失了 MapReduce 的特性,不過真的要做MapReduce也不是不可以,就自己寫程式把日誌匯出來,再跑Map Reduce 就行了,具體的選擇看應用場景決定,如果你只是查日誌,那用Hbase就行了

真實環境下的架構

這個例子只是一個最簡單的情況,真實環境的日誌情況下,會有多臺機器收集log4j生成的日誌並統一存放到hdfs上。比如我們從host1 和 host2 上都收集日誌,並通過其中一臺機器的flume將日誌儲存到hdfs上。架構圖 
這樣做的好處是
  1. 分散風險,提高容錯率,因為flume本身有一個快取機制,如果寫入hdfs的flume出問題了,比如關機,或者升級,web伺服器的日誌還是可以收集,只是暫時先放在本機的硬碟上
  2. 緩解hdfs的寫入壓力,由於日誌在各個層級被快取了,並以一定的速度寫入hdfs,這樣不會造成hdfs的機器負載過大以致影響正常業務

參考資料 

相關推薦

AlexHadoop 教程: 22 分散式日誌收集元件flume

本教程的目的:flume 跟 hadoop 有什麼關係介紹flume的結構介紹flume的安裝做一個簡單的收集網路傳送過來的文字(NetCat Source)並儲存到日誌檔案(Logger Sink)的例子flume 跟 hadoop 有什麼關係hadoop是一個分散式系統,

AlexHadoop 教程: 6 Hbase 安裝教程

原帖地址: http://blog.csdn.net/nsrainbow/article/details/38515007 宣告: 本文基於Centos 6.x + CDH 5.x 官方英文安裝教程http://www.cloudera.com/content/cloud

AlexHadoop 教程: 5 YARN 安裝以及helloworld (基於centos的CDH)

原帖地址:http://blog.csdn.net/nsrainbow/article/details/36627675 新老MapReduce的比較 說到YARN肯定要先說下老的MapReduce MRv1 (MapReduce v1)的架構圖 從上圖中可以清楚的看出

AlexHadoop 教程: 9 zookeeper 介紹和使用

ZooKeeper是一個分散式的,開放原始碼的分散式應用程式協調服務。ZooKeeper的目標就是封裝好複雜易出錯的關鍵服務,將簡單易用的介面和效能高效、功能穩定的系統提供給使用者ZooKeeper包含一個簡單的原語集,提供Java和C的介面。    在Zookeeper中,znode是一個跟Unix檔案系

AlexHadoop 教程: 12 Sqoop1 安裝/匯入/匯出教程

原帖地址: http://blog.csdn.net/nsrainbow/article/details/41575807 Sqoop是什麼 sqoop是用於在傳統關係型資料庫跟hdfs之間進行資料匯入匯出的工具。目前sqoop已經出了2,但是截至當前,s

破解教程 22 一個新的破解方法---OllyDbg破解法

[例二]軟體名稱:網咖計費軟體專用版 2.0 下載地址: ftp://211.100.8.153/download/102/12112_netbar.zip 破解:忘了自己步驟: 1。用OllyDbg載入網咖計費軟體專用版 2.0。按F9執行。 2。回到Ollydbg 介面,通常Ollydbg介面有四個視窗,

教程之工具使用(五)——JRebel與Windows服務的Tomcat集成

-m end 個人 再見 proc key pre 安裝 target 之前寫過一篇Tomcat借助JRebel支持熱部署的文章——《借助JRebel使Tomcat支持熱部署 》。介紹的是在開發、測試環境中的配置。可是正式的部署環境。我們不會通過命令行來啟動Tomcat,

22 單鏈表的實現

.cn toa nod 越界 bool 遞歸調用 isp {} log 1. LinkList類的設計要點 (1)用類模板實現,通過頭結點訪問後繼結點 (2)定義內部結點類型Node(註意繼承於自定義的Objec

Angular js 過濾器 筆記(轉自教程

per test 筆記 ring ood filter 子集 true 貨幣格式 1、uppercase,lowercase 大小寫轉換 {{ "lower cap string" | uppercase }} // 結果:LOWER CAP STRING {{ "TA

教程-練習實例答案I

core 其中a是一個數字 再落下 乘法 white 超過 -1 英文字母 三位數 題目:有四個數字:1、2、3、4,能組成多少個互不相同且無重復數字的三位數?各是多少? 1 #coding=utf-8 2 3 from itertools import permuta

ionic新手教程-簡要說明幾種界面之間的參數傳遞及優缺點

get art 簡單的 edi adc spa pan 業務 route 截至2016年4月13日19點32分,我公布的ionic新手教程,已經公布6課了, 總訪問量將近6000,平均每節課能有1000的訪問量。當中訪客最多的是第三課有2700的訪客。

ionic新手教程-在項目中使用requirejs分離controller文件和server文件

做了 不難 定位 nts center str 報錯 去掉 x文件 繼上篇教程中提到的,我們新建一個簡單的tabs類型的Ionic項目。 依據文件夾文件我們知道,系統自己主動創建了一個controller文件和server文件,而且把全部的控制器和服務都寫到這兩個

教程 Python 手記 1

報錯信息 數據類型 字符串表 ring max last pda 每次 none Python是一種解釋型、面向對象、動態數據類型的高級程序設計語言。 編碼 編碼默認情況下,Python 3 源碼文件以 UTF-8 編碼,所有字符串都是 unicode 字符串。 當然你

sphinx 教程

edt cool lis file lpad 抽象 mage settings length 簡介 Sphinx 是一種工具,它允許開發人員以純文本格式編寫文檔,以便采用滿足不同需求的格式輕松生成輸出。這在使用 Version Control System 追蹤變更時非常有

JPA 教程 15 繼承-一個表-SINGLE_TABLE

column turn rate pre school fill 技術 一個表 tor 原地址:http://blog.csdn.net/JE_GE/article/details/53678422 繼承映射策略 一個類繼承結構一個表的策略,最終只生成一個表,這是繼承映射的

Java 8 新特性-教程 (3) -Java 8 函數式接口

但是 style vax arr 結果 友好 face todo 兩個 Java 8 函數式接口 函數式接口(Functional Interface)就是一個有且僅有一個抽象方法,但是可以有多個非抽象方法的接口。 函數式接口可以被隱式轉換為lambda表達式。 函數式接口

Linux學習_教程_1

ssh sync 起點 計算機 16px 指令 span 語句 完成 Linux系統啟動過程:內核的引導 、運行init、系統初始化、建立終端、用戶登錄系統 內核引導:計算機開機,然後BIOS開機自檢,按照BIOS中設置的啟動設備(通常是硬盤)來啟動。 操作系統接管硬件以後

Java教程———學習筆記

class this 關鍵字 多繼承 之間 字母 ext javac 多個 編譯錯誤 (1)Java中的繼承有兩種:extends 和 implements extends 類的繼承是單一繼承,也就是說,一個子類只能擁有一個父類,所以 extends 只能繼承一個類。 使用

教程】小白接觸白鷺引擎4天,成功做了一款足球小遊戲

下一步 發現 https sta 圖片 sce 變量名 找到 是否 寫在前面:隨著越來越多的新人開始接觸白鷺引擎,創作屬於自己的遊戲。考慮到初學者會遇到一些實際操作問題,我們近期整理推出“菜鳥”系列技術文檔,以便更好的讓這些開發者們快速上手,Egret大神們可以自動忽略此類

PHP Ajax 跨域問題最佳解決方案 【摘自教程

set color ray quest origin tty 所有 $origin con PHP Ajax 跨域問題最佳解決方案 分類 編程技術 http://www.runoob.com/w3cnote/php-ajax-cross-border.html 本文