轉:使用Flume+Kafka+SparkStreaming進行實時日誌分析

版權聲明:本文爲博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/Trigl/article/details/70237981
每個公司想要進行數據分析或數據挖掘,收集日誌、ETL都是第一步的,今天就講一下如何實時地(準實時,每分鐘分析一次)收集日誌,處理日誌,把處理後的記錄存入Hive中,並附上完整實戰代碼

1. 整體架構
思考一下,正常情況下我們會如何收集並分析日誌呢?

首先,業務日誌會通過Nginx(或者其他方式,我們是使用Nginx寫入日誌)每分鐘寫入到磁盤中,現在我們想要使用Spark分析日誌,就需要先將磁盤中的文件上傳到HDFS上,然後Spark處理,最後存入Hive表中,如圖所示:

我們之前就是使用這種方式每天分析一次日誌,但是這樣有幾個缺點:

首先我們的日誌是通過Nginx每分鐘存成一個文件,這樣一天的文件數很多,不利於後續的分析任務,所以先要把一天的所有日誌文件合併起來

合併起來以後需要把該文件從磁盤傳到Hdfs上,但是我們的日誌服務器並不在Hadoop集羣內,所以沒辦法直接傳到Hdfs上,需要首先把文件從日誌服務器傳輸到Hadoop集羣所在的服務器,然後再上傳到Hdfs

最後也是最重要的,滯後一天分析數據已經不能滿足我們新的業務需求了,最好能控制在一個小時的滯後時間

可以看出來我們以前收集分析日誌的方式還是比較原始的,而且比較耗時,很多時間浪費在了網絡傳輸上面,如果日誌量大的話還有丟失數據的可能性,所以在此基礎上改進了一下架構:

整個過程就是,Flume會實時監控寫入日誌的磁盤,只要有新的日誌寫入,Flume就會將日誌以消息的形式傳遞給Kafka,然後Spark Streaming實時消費消息傳入Hive

那麼Flume是什麼呢,它爲什麼可以監控一個磁盤文件呢?簡而言之,Flume是用來收集、匯聚並且移動大量日誌文件的開源框架,所以很適合這種實時收集日誌並且傳遞日誌的場景

Kafka是一個消息系統,Flume收集的日誌可以移動到Kafka消息隊列中,然後就可以被多處消費了,而且可以保證不丟失數據

通過這套架構,收集到的日誌可以及時被Flume發現傳到Kafka,通過Kafka我們可以把日誌用到各個地方,同一份日誌可以存入Hdfs中,也可以離線進行分析,還可以實時計算,而且可以保證安全性,基本可以達到實時的要求

整個流程已經清晰了,下面各個突破,我們開始動手實現整套系統

2. 實戰演練
2.1 安裝Kafka
下載安裝Kafka以及一些基本命令請傳送到這裏: Kafka安裝與簡介

安裝好以後新建名爲launcher_click的topic:

bin/kafka-topics.sh --create --zookeeper hxf:2181,cfg:2181,jqs:2181,jxf:2181,sxtb:2181 --replication-factor 2 --partitions 2 --topic launcher_click
1
查看一下該topic:

bin/kafka-topics.sh --describe --zookeeper hxf:2181,cfg:2181,jqs:2181,jxf:2181,sxtb:2181 --topic launcher_click
1


2.2 安裝Flume
1、下載解壓

下載地址: https://flume.apache.org/download.html 
注意進入下載地址頁面,使用清華大學的那個地址,否則會很慢

wget http://apache.fayea.com/flume/1.7.0/apache-flume-1.7.0-bin.tar.gz
tar -xvf apache-flume-1.7.0-bin.tar.gz
1
2
2、修改配置文件

進入flume目錄,修改conf/flume-env.sh

export JAVA_HOME=/data/install/jdk
export JAVA_OPTS="-Xms1000m -Xmx2000m -Dcom.sun.management.jmxremote"
1
2
添加配置文件:conf/flume_launcherclick.conf

# logser可以看做是flume服務的名稱,每個flume都由sources、channels和sinks三部分組成
# sources可以看做是數據源頭、channels是中間轉存的渠道、sinks是數據後面的去向
logser.sources = src_launcherclick
logser.sinks = kfk_launcherclick
logser.channels = ch_launcherclick

# source
# 源頭類型是TAILDIR,就可以實時監控以追加形式寫入文件的日誌
logser.sources.src_launcherclick.type = TAILDIR
# positionFile記錄所有監控的文件信息
logser.sources.src_launcherclick.positionFile = /data/install/flume/position/launcherclick/taildir_position.json
# 監控的文件組
logser.sources.src_launcherclick.filegroups = f1
# 文件組包含的具體文件,也就是我們監控的文件
logser.sources.src_launcherclick.filegroups.f1 = /data/launcher/stat_app/.*

# interceptor
# 寫kafka的topic即可
logser.sources.src_launcherclick.interceptors = i1 i2
logser.sources.src_launcherclick.interceptors.i1.type=static
logser.sources.src_launcherclick.interceptors.i1.key = type
logser.sources.src_launcherclick.interceptors.i1.value = launcher_click
logser.sources.src_launcherclick.interceptors.i2.type=static
logser.sources.src_launcherclick.interceptors.i2.key = topic
logser.sources.src_launcherclick.interceptors.i2.value = launcher_click

# channel
logser.channels.ch_launcherclick.type = memory
logser.channels.ch_launcherclick.capacity = 10000
logser.channels.ch_launcherclick.transactionCapacity = 1000

# kfk sink
# 指定sink類型是Kafka,說明日誌最後要發送到Kafka
logser.sinks.kfk_launcherclick.type = org.apache.flume.sink.kafka.KafkaSink
# Kafka broker
logser.sinks.kfk_launcherclick.brokerList = 10.0.0.80:9092,10.0.0.140:9092

# Bind the source and sink to the channel
logser.sources.src_launcherclick.channels = ch_launcherclick
logser.sinks.kfk_launcherclick.channel = ch_launcherclick
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
3、啓動

nohup bin/flume-ng agent --conf conf/ --conf-file conf/flume_launcherclick.conf --name logser -Dflume.root.logger=INFO,console >> logs/flume_launcherclick.log &
1
此時Kafka和Flume都已經啓動了,從配置可以看到Flume的監控文件是/data/launcher/stat_app/.*,所以只要該目錄下文件內容有增加就會發送到Kafka,大家可以自己追加一些測試日誌到這個目錄的文件下,然後開一個Kafka Consumer看一下Kafka是否接收到消息,這裏我們完成SparkStreaming以後再看測試結果

2.3 SparkStreaming編程
SparkStreaming是Spark用來處理實時流的,能夠實時到秒級,我們這裏不需要這麼實時,是每分鐘執行一次日誌分析程序,主要代碼如下:

  def main(args: Array[String]) {

    Logger.getLogger("org.apache.spark").setLevel(Level.WARN)
    System.setProperty("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
    val sparkConf = new SparkConf().setAppName("LauncherStreaming")

    //每60秒一個批次
    val ssc = new StreamingContext(sparkConf, Seconds(60))

    // 從Kafka中讀取數據
    val kafkaStream = KafkaUtils.createStream(
      ssc,
      "hxf:2181,cfg:2181,jqs:2181,jxf:2181,sxtb:2181", // Kafka集羣使用的zookeeper
      "launcher-streaming", // 該消費者使用的group.id
      Map[String, Int]("launcher_click" -> 0, "launcher_click" -> 1), // 日誌在Kafka中的topic及其分區
      StorageLevel.MEMORY_AND_DISK_SER).map(_._2) // 獲取日誌內容

    kafkaStream.foreachRDD((rdd: RDD[String], time: Time) => {
      val result = rdd.map(log => parseLog(log)) // 分析處理原始日誌
        .filter(t => StringUtils.isNotBlank(t._1) && StringUtils.isNotBlank(t._2))
      // 存入hdfs
      result.saveAsHadoopFile(HDFS_DIR, classOf[String], classOf[String], classOf[LauncherMultipleTextOutputFormat[String, String]])
    })

    ssc.start()
    // 等待實時流
    ssc.awaitTermination()
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
篇目有限,完整代碼訪問我的github:https://github.com/Trigl/SparkLearning/blob/master/src/main/scala/com/trigl/spark/streaming/LauncherStreaming.scala

然後打包上傳到master運行:

nohup /data/install/spark-2.0.0-bin-hadoop2.7/bin/spark-submit  --master spark://hxf:7077  --executor-memory 1G --total-executor-cores 4   --class com.analysis.main.LauncherStreaming --jars /home/hadoop/jar/kafka-clients-0.10.0.0.jar,/home/hadoop/jar/metrics-core-2.2.0.jar,/home/hadoop/jar/zkclient-0.3.jar,/home/hadoop/jar/spark-streaming-kafka-0-8_2.11-2.0.0.jar,/home/hadoop/jar/kafka_2.11-0.8.2.1.jar  /home/hadoop/jar/SparkLearning.jar  >> /home/hadoop/logs/LauncherDM.log &
1
然後開始測試,往Flume監控目錄/data/launcher/stat_app/.*寫日誌,原始日誌內容類似下面這樣:

118.120.102.3|1495608541.238|UEsDBBQACAgIACB2uEoAAAAAAAAAAAAAAAABAAAAMGWUbW7bMAyGb6NfnUFRFEWhJ+gBdgBZVjpjjp04brMAO*yY2DKa9Y+B1+DnQ1LCztoITgK4wPGHfNUhmKGUPOn3DyP*zdOxSWM3T33XXMqy9OP7xXTZiTC1xlL0HgMEi+BfHoooBEGKr3fPpYy5jMse4Xzupus4TKkrs4kZOhI51CgWWKxsUQBRPMDr1*w5Hcuc0LiUEFBwdXQxAARXHb3+QXlOfzya0uZWOGwlEwBDwLD5oJBVFHsEEPF2U0EUToyr8k4tg9v8AkRrIcKmxGsU2eqQIM45dKuKFICo5oveEqOjh2JAIITImyIJqBk3JS4qh7Wby*TroxnL9ZKHXrsyWeBQoMXaEgXUKh6mOQ1l7NLc*Hwz8aDpAtndLFJEetkVc6S9V*bg+RFiKMvnTv6ahuGUTmWexqEfi3Elezx0botJrCCQn5jfCzWaqaUOqNpFYO23ckYl5GOlx4rLQuUllh27SsjZyLQTUn4K+3uVczlOi+7uuMzTYLoibeIspk71DtKuJC+7T5qXPg9lLddaZs6+Lolnj7ANW0dBGKOn72m3cbQJI2Kq4*C6Xhz9E5Pzeeg*i2l1IAJtpReILNq6DY4peFjHeO5vffPZd2UyejEJ28Puo0sI*2*5ojvhfNcquWomFMVp02Pz++M6Nach3e6XR5wOlrdSg4T7RkgtQAuC6HYl2sc62i6dUq*om+HWjvdHAPSk8hYkegHraxC8PwPons73XZeozDfXmaRzzzaD2XI4fX0QX*8BUEsHCKeftc48AgAAmQQAAA==
1
查看HDFS的對應目錄是否有內容:

HDFS存儲的分析後的日誌內容如下:

99000945863664;864698037273329|119.176.140.248|1495594615129|2017-05-24 10:56:55|xiaomi|redmi4x|com.jingdong.app.mall&0ae359b6&1495534579412&1;com.autonavi.minimap&279f562f&1495534597934,1495534616627&2;com.android.contacts&91586932&1495538267103,1495540527138,1495576834653,1495583404117,1495591231535&5
1
SparkStreaming任務狀態如下:

可以看到的確是每分鐘執行一次

Refer

http://blog.xiaoxiaomo.com/2016/05/22/Flume-%E9%9B%86%E7%BE%A4%E5%8F%8A%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/

http://lxw1234.com/archives/2015/11/552.htm
————————————————
版權聲明:本文爲CSDN博主「Trigl」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Trigl/article/details/70237981

發佈了12 篇原創文章 · 獲贊 121 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章