一、简介

Apache Flume是一个分布式,高可用的数据收集系统,可以从不同的数据源收集数据,经过聚合后发送到分布式计算框架或者存储系统中。Spark Straming提供了以下两种方式用于Flume的整合。

二、推送式方法

在推送式方法(Flume-style Push-based Approach)中,Spark Streaming程序需要对某台服务器的某个端口进行监听,Flume通过avro Sink将数据源源不断推送到该端口。这里以监听日志文件为例,具体整合方式如下:

2.1 配置日志收集Flume

新建配置netcat-memory-avro.properties,使用tail命令监听文件内容变化,然后将新的文件内容通过avro sink发送到hadoop001这台服务器的8888端口:

#指定agent的sources,sinks,channels
a1.sources = s1
a1.sinks = k1
a1.channels = c1

#配置sources属性
a1.sources.s1.type = exec
a1.sources.s1.command = tail -F /tmp/log.txt
a1.sources.s1.shell = /bin/bash -c
a1.sources.s1.channels = c1

#配置sink
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = hadoop001
a1.sinks.k1.port = 8888
a1.sinks.k1.batch-size = 1
a1.sinks.k1.channel = c1

#配置channel类型
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

2.2 项目依赖

项目采用Maven工程进行构建,主要依赖为spark-streamingspark-streaming-flume

<properties>
    <scala.version>2.11</scala.version>
    <spark.version>2.4.0</spark.version>
</properties>

<dependencies>
    <!-- Spark Streaming-->
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-streaming_${scala.version}</artifactId>
        <version>${spark.version}</version>
    </dependency>
    <!-- Spark Streaming整合Flume依赖-->
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-streaming-flume_${scala.version}</artifactId>
        <version>2.4.3</version>
    </dependency>
</dependencies>

2.3 Spark Streaming接收日志数据

调用 FlumeUtils工具类的createStream方法,对hadoop001的8888端口进行监听,获取到流数据并进行打印:

import org.apache.spark.SparkConf
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.streaming.flume.FlumeUtils

object PushBasedWordCount {

  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf()
    val ssc = new StreamingContext(sparkConf, Seconds(5))
    // 1.获取输入流
    val flumeStream = FlumeUtils.createStream(ssc, "hadoop001", 8888)
    // 2.打印输入流的数据
    flumeStream.map(line => new String(line.event.getBody.array()).trim).print()

    ssc.start()
    ssc.awaitTermination()
  }
}

2.4 项目打包

因为Spark安装目录下是不含有spark-streaming-flume依赖包的,所以在提交到集群运行时候必须提供该依赖包,你可以在提交命令中使用--jar指定上传到服务器的该依赖包,或者使用--packages org.apache.spark:spark-streaming-flume_2.12:2.4.3指定依赖包的完整名称,这样程序在启动时会先去中央仓库进行下载。

这里我采用的是第三种方式:使用maven-shade-plugin插件进行ALL IN ONE打包,把所有依赖的Jar一并打入最终包中。需要注意的是spark-streaming包在Spark安装目录的jars目录中已经提供,所以不需要打入。插件配置如下:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>8</source>
                <target>8</target>
            </configuration>
        </plugin>
        <!--使用shade进行打包-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <configuration>
                <createDependencyReducedPom>true</createDependencyReducedPom>
                <filters>
                    <filter>
                        <artifact>*:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.sf</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.dsa</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                            <exclude>META-INF/*.rsa</exclude>
                            <exclude>META-INF/*.EC</exclude>
                            <exclude>META-INF/*.ec</exclude>
                            <exclude>META-INF/MSFTSIG.SF</exclude>
                            <exclude>META-INF/MSFTSIG.RSA</exclude>
                        </excludes>
                    </filter>
                </filters>
                <artifactSet>
                    <excludes>
                        <exclude>org.apache.spark:spark-streaming_${scala.version}</exclude>
                        <exclude>org.scala-lang:scala-library</exclude>
                        <exclude>org.apache.commons:commons-lang3</exclude>
                    </excludes>
                </artifactSet>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <transformer
                              implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                            <transformer
                              implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            </transformer>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <!--打包.scala文件需要配置此插件-->
        <plugin>
            <groupId>org.scala-tools</groupId>
            <artifactId>maven-scala-plugin</artifactId>
            <version>2.15.1</version>
            <executions>
                <execution>
                    <id>scala-compile</id>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                    <configuration>
                        <includes>
                            <include>**/*.scala</include>
                        </includes>
                    </configuration>
                </execution>
                <execution>
                    <id>scala-test-compile</id>
                    <goals>
                        <goal>testCompile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

本项目完整源码见:spark-streaming-flume

使用mvn clean package命令打包后会生产以下两个Jar包,提交非original开头的Jar即可。

2.5 启动服务和提交作业

启动Flume服务:

flume-ng agent \
--conf conf \
--conf-file /usr/app/apache-flume-1.6.0-cdh5.15.2-bin/examples/netcat-memory-avro.properties \
--name a1 -Dflume.root.logger=INFO,console

提交Spark Streaming作业:

spark-submit \
--class com.heibaiying.flume.PushBasedWordCount \
--master local[4] \
/usr/appjar/spark-streaming-flume-1.0.jar

2.6 测试

这里使用echo命令模拟日志产生的场景,往日志文件中追加数据,然后查看程序的输出:

Spark Streaming程序成功接收到数据并打印输出:

2.7 注意事项

1. 启动顺序

这里需要注意的,不论你先启动Spark程序还是Flume程序,由于两者的启动都需要一定的时间,此时先启动的程序会短暂地抛出端口拒绝连接的异常,此时不需要进行任何操作,等待两个程序都启动完成即可。

2. 版本一致

最好保证用于本地开发和编译的Scala版本和Spark的Scala版本一致,至少保证大版本一致,如都是2.11

三、拉取式方法

拉取式方法(Pull-based Approach using a Custom Sink)是将数据推送到SparkSink接收器中,此时数据会保持缓冲状态,Spark Streaming定时从接收器中拉取数据。这种方式是基于事务的,即只有在Spark Streaming接收和复制数据完成后,才会删除缓存的数据。与第一种方式相比,具有更强的可靠性和容错保证。整合步骤如下:

3.1 配置日志收集Flume

新建Flume配置文件netcat-memory-sparkSink.properties,配置和上面基本一致,只是把a1.sinks.k1.type的属性修改为org.apache.spark.streaming.flume.sink.SparkSink,即采用Spark接收器。

#指定agent的sources,sinks,channels
a1.sources = s1
a1.sinks = k1
a1.channels = c1

#配置sources属性
a1.sources.s1.type = exec
a1.sources.s1.command = tail -F /tmp/log.txt
a1.sources.s1.shell = /bin/bash -c
a1.sources.s1.channels = c1

#配置sink
a1.sinks.k1.type = org.apache.spark.streaming.flume.sink.SparkSink
a1.sinks.k1.hostname = hadoop001
a1.sinks.k1.port = 8888
a1.sinks.k1.batch-size = 1
a1.sinks.k1.channel = c1

#配置channel类型
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

2.2 新增依赖

使用拉取式方法需要额外添加以下两个依赖:

<dependency>
    <groupId>org.scala-lang</groupId>
    <artifactId>scala-library</artifactId>
    <version>2.12.8</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.5</version>
</dependency>

注意:添加这两个依赖只是为了本地测试,Spark的安装目录下已经提供了这两个依赖,所以在最终打包时需要进行排除。

2.3 Spark Streaming接收日志数据

这里和上面推送式方法的代码基本相同,只是将调用方法改为createPollingStream

import org.apache.spark.SparkConf
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.streaming.flume.FlumeUtils

object PullBasedWordCount {

  def main(args: Array[String]): Unit = {

    val sparkConf = new SparkConf()
    val ssc = new StreamingContext(sparkConf, Seconds(5))
    // 1.获取输入流
    val flumeStream = FlumeUtils.createPollingStream(ssc, "hadoop001", 8888)
    // 2.打印输入流中的数据
    flumeStream.map(line => new String(line.event.getBody.array()).trim).print()
    ssc.start()
    ssc.awaitTermination()
  }
}

2.4 启动测试

启动和提交作业流程与上面相同,这里给出执行脚本,过程不再赘述。

启动Flume进行日志收集:

flume-ng agent \
--conf conf \
--conf-file /usr/app/apache-flume-1.6.0-cdh5.15.2-bin/examples/netcat-memory-sparkSink.properties \
--name a1 -Dflume.root.logger=INFO,console

提交Spark Streaming作业:

spark-submit \
--class com.heibaiying.flume.PullBasedWordCount \
--master local[4] \
/usr/appjar/spark-streaming-flume-1.0.jar

参考资料

更多大数据系列文章可以参见个人 GitHub 开源项目: 程序员大数据入门指南

Spark学习之路(十五)—— Spark Streaming 整合 Flume的更多相关文章

  1. Spark学习之路 (五)Spark伪分布式安装

    一.JDK的安装 JDK使用root用户安装 1.1 上传安装包并解压 [root@hadoop1 soft]# tar -zxvf jdk-8u73-linux-x64.tar.gz -C /usr ...

  2. Spark学习之路(五)—— Spark运行模式与作业提交

    一.作业提交 1.1 spark-submit Spark所有模式均使用spark-submit命令提交作业,其格式如下: ./bin/spark-submit \ --class <main- ...

  3. Spark学习之路 (五)Spark伪分布式安装[转]

    JDK的安装 JDK使用root用户安装 上传安装包并解压 [root@hadoop1 soft]# tar -zxvf jdk-8u73-linux-x64.tar.gz -C /usr/local ...

  4. zigbee学习之路(十五):基于协议栈的按键实验

    一.前言 经过上次的学习,相信大家已经初步学会使用zigbee协议进行发送和接受数据了.今天,我们要进行的实验是按键的实验,学会如何在协议栈里实现按键中断. 二.实验功能 在协议栈上实现按键中断,BU ...

  5. salesforce零基础学习(八十五)streaming api 简单使用(接近实时获取你需要跟踪的数据的更新消息状态)

    Streaming API参考链接: https://trailhead.salesforce.com/en/modules/api_basics/units/api_basics_streaming ...

  6. 嵌入式Linux驱动学习之路(十五)按键驱动-定时器防抖

    在之前的定时器驱动程序中,我们发现在连续按下按键的时候,正常情况下应该是一次按下对应一次松开.而程序有时候会显示是两次按下,一次松开.这个问题是因为在按下的时候,因为是机械按键,所以电压信号会产生一定 ...

  7. IOS学习之路十五(UIView 添加背景图片以及加边框)

    怎样给UIview添加背景图片呢很简单,就是先给view添加一个subview,然后设为背景图片: 效果图如下: 很简单直接上代码: //设置内容 self.myTopView.backgroundC ...

  8. Spark学习之路(十四)—— Spark Streaming 基本操作

    一.案例引入 这里先引入一个基本的案例来演示流的创建:获取指定端口上的数据并进行词频统计.项目依赖和代码实现如下: <dependency> <groupId>org.apac ...

  9. Spark 系列(十五)—— Spark Streaming 整合 Flume

    一.简介 Apache Flume 是一个分布式,高可用的数据收集系统,可以从不同的数据源收集数据,经过聚合后发送到分布式计算框架或者存储系统中.Spark Straming 提供了以下两种方式用于 ...

随机推荐

  1. 各个版本 Windows 10 系统中自带的 .NET Framework 版本

    原文各个版本 Windows 10 系统中自带的 .NET Framework 版本 Windows 名称 Windows 版本 自带的 .NET Framework 版本 Windows 10 Oc ...

  2. wpf之自定义滚动条

    原文:wpf之自定义滚动条 首先我们添加一个带滚动条的textbox控件: <ScrollViewer Height="130" Width="620" ...

  3. SIIA CODIE AWARDS 2017

    Business Technology Best Advertising or Campaign Management Platform Albert, Albert Choozle, Choozle ...

  4. windows 7 SDK和DDK下载

    检查小数据,获取地址.顺便记录下来. Windows Driver Kit Version 7.1.0 http://www.microsoft.com/downloads/details.aspx? ...

  5. httpclient POST请求(urlencoded)

    搬砖搬砖~ Content-Type:application/x-www-form-urlencoded的请求如下 var nvc = new List<KeyValuePair<stri ...

  6. 使用aws和tomcat搭建服务器过程中的一些坑.

    在国外没啥事做, 考前也不愿意复习, 看到aws能免费试用一年, 于是就试着搞了搞, 就准备搭建个个人网站玩玩. aws的注册与创建实例 首先个人感觉这个东西使用起来还是很方便的, 一开始注册完验证完 ...

  7. 微信小程序把玩(二十九)video组件

    原文:微信小程序把玩(二十九)video组件 视频播放组件与图片加载组件也没啥差别,使用起来也没啥注意的 重要属性: wxml <!--监听button点击事件--> <button ...

  8. 危险的DDD聚合根

    原文:危险的DDD聚合根 DDD的核心是聚合.这没有问题,大家都认同.但关于DDD中的聚合方式,其实我还是有些担心,下面说说我的想法,希望大家参与讨论.其实当初第一次看到DDD中关于聚合根部分论述的时 ...

  9. C#图片灰度处理(位深度24→位深度8)

    #region 灰度处理 /// <summary> /// 将源图像灰度化,并转化为8位灰度图像. /// </summary> /// <param name=&qu ...

  10. VCL的通用属性,方法和事件 good

    Action 一些组件标识与组件相连接的活动对象Align 一些组件确定组件在父类组件区内的对齐方式Anchors 大部分组件说明与组件连接的窗体的位置点AutoSize 一些组件说明组件是否可根据内 ...