From 7d9b9fa9d86d8f48a37fabeaec4a067d9c955f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E7=A5=A5?= <1366971433@qq.com> Date: Fri, 24 May 2019 10:14:58 +0800 Subject: [PATCH] =?UTF-8?q?streaming=20=E6=95=B4=E5=90=88=20flume?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/spark/spark-streaming-flume/pom.xml | 1 + notes/Spark_Streaming整合Flume.md | 360 +++++++++++++++++++++ notes/大数据应用常用打包方式.md | 52 ++- pictures/spark-streaming-flume-jar.png | Bin 0 -> 21168 bytes 4 files changed, 404 insertions(+), 9 deletions(-) create mode 100644 notes/Spark_Streaming整合Flume.md create mode 100644 pictures/spark-streaming-flume-jar.png diff --git a/code/spark/spark-streaming-flume/pom.xml b/code/spark/spark-streaming-flume/pom.xml index c8fe1e8..d0e8441 100644 --- a/code/spark/spark-streaming-flume/pom.xml +++ b/code/spark/spark-streaming-flume/pom.xml @@ -98,6 +98,7 @@ + org.scala-tools maven-scala-plugin diff --git a/notes/Spark_Streaming整合Flume.md b/notes/Spark_Streaming整合Flume.md new file mode 100644 index 0000000..eacbfd0 --- /dev/null +++ b/notes/Spark_Streaming整合Flume.md @@ -0,0 +1,360 @@ +# Spark Straming 整合 Flume + + + + +## 一、简介 + +Apache Flume是一个分布式,高可用的数据收集系统,可以从不同的数据源收集数据,经过聚合后发送到分布式计算框架或者存储系统中。Spark Straming提供了以下两种方式用于Flume的整合。 + +## 二、推送式方法 + +在推送式方法(Flume-style Push-based Approach)中,Spark Streaming程序需要对某台服务器的某个端口进行监听,Flume通过`avro Sink`将数据源源不断推送到该端口。 + +这里以日志文件内容为例,将不断新增的日志文件内容推送到Streaming程序中,具体整合方式如下: + +### 2.1 配置日志收集Flume + +新建配置`netcat-memory-avro.properties`,使用`tail`命令监听文件内容变化,然后将新的文件内容通过`avro sink`发送到hadoop001这台服务器的8888端口: + +```properties +#指定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-streaming`和`spark-streaming-flume`。 + +```xml + + 2.11 + 2.4.0 + + + + + + org.apache.spark + spark-streaming_${scala.version} + ${spark.version} + + + + org.apache.spark + spark-streaming-flume_${scala.version} + 2.4.3 + + + +``` + +### 2.3 Spark Streaming接收日志数据 + +调用 FlumeUtils工具类的`createStream`方法,对hadoop001的8888端口进行监听,获取到流数据并进行打印: + +```scala +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`目录中已经提供,所以不需要打入。插件配置如下: + +> 关于大数据应用常用打包方式单独整理至:[大数据应用常用打包方式](https://github.com/heibaiying/BigData-Notes/blob/master/notes/大数据应用常用打包方式.md) +> +> 本项目完整源码见:[spark-streaming-flume](https://github.com/heibaiying/BigData-Notes/tree/master/code/spark/spark-streaming-flume) + +```xml + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + + org.apache.maven.plugins + maven-shade-plugin + + true + + + *:* + + META-INF/*.SF + META-INF/*.sf + META-INF/*.DSA + META-INF/*.dsa + META-INF/*.RSA + META-INF/*.rsa + META-INF/*.EC + META-INF/*.ec + META-INF/MSFTSIG.SF + META-INF/MSFTSIG.RSA + + + + + + org.apache.spark:spark-streaming_${scala.version} + org.scala-lang:scala-library + org.apache.commons:commons-lang3 + + + + + + package + + shade + + + + + + + + + + + + + + org.scala-tools + maven-scala-plugin + 2.15.1 + + + scala-compile + + compile + + + + **/*.scala + + + + + scala-test-compile + + testCompile + + + + + + +``` + +使用`mvn clean package`命令打包后会生产以下两个Jar包,提交`非original`开头的Jar即可。 + +
+ +### 2.5 启动服务和提交作业 + + 启动Flume服务: + +```shell +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作业: + +```shell +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接收器。 + +```properties +#指定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 新增依赖 + +使用拉取式方法需要额外添加以下两个依赖: + +```xml + + org.scala-lang + scala-library + 2.12.8 + + + org.apache.commons + commons-lang3 + 3.5 + +``` + +注意:添加这两个依赖只是为了本地开发测试,Spark的安装目录下已经提供了这两个依赖,所以在最终打包时需要进行排除。 + +### 2.3 Spark Streaming接收日志数据 + +这里和上面推送式方法的代码基本相同,只是将调用方法改为`createPollingStream`。 + +```scala +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进行日志收集: + +```shell +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作业: + +```shel +spark-submit \ +--class com.heibaiying.flume.PullBasedWordCount \ +--master local[4] \ +/usr/appjar/spark-streaming-flume-1.0.jar +``` + + + +## 参考资料 + +1. [streaming-flume-integration](https://spark.apache.org/docs/latest/streaming-flume-integration.html) \ No newline at end of file diff --git a/notes/大数据应用常用打包方式.md b/notes/大数据应用常用打包方式.md index c9133a0..f05e267 100644 --- a/notes/大数据应用常用打包方式.md +++ b/notes/大数据应用常用打包方式.md @@ -5,12 +5,15 @@ 二、mvn package
三、maven-assembly-plugin插件
四、maven-shade-plugin插件
-五、使用非Maven仓库中的Jar
-六、排除集群中已经存在的Jar
-七、使用建议
+五、其他打包需求
+        1. 使用非Maven仓库中的Jar
+        2. 排除集群中已经存在的Jar
+        3. 打包.scala文件
+ + ## 一、简介 在提交大数据作业到集群中运行时,通常都需要先将项目打成Jar包。Java项目通常都采用Maven进行构建,Maven提供的常用打包方式及插件有以下四种: @@ -118,6 +121,8 @@ assembly.xml文件内容如下: `maven-shade-plugin`比`maven-assembly-plugin`功能更为强大,比如你的工程依赖很多的JAR包,而被依赖的JAR又会依赖其他的JAR包,这样,当工程中依赖到不同的版本的 JAR时,并且JAR中具有相同名称的资源文件时,shade插件会尝试将所有资源文件打包在一起时,而不是和assembly一样执行覆盖操作。 +**通常使用`maven-shade-plugin`就能够完成大多数的打包需求,其配置简单且适用性最广,因此建议优先使用此方式。** + ### 4.1 基本配置 采用`maven-shade-plugin`进行打包时候,配置示例如下: @@ -192,7 +197,9 @@ assembly.xml文件内容如下: -## 五、使用非Maven仓库中的Jar +## 五、其他打包需求 + +### 1. 使用非Maven仓库中的Jar 通常上面两种打包能够满足大多数的使用场景。但是如果你想把某些没有被Maven管理Jar包打入到最终的Jar中,比如你在`resources/lib`下引入的其他非Maven仓库中的Jar,此时可以使用`maven-jar-plugin`和`maven-dependency-plugin`插件将其打入最终的Jar中。 @@ -238,9 +245,9 @@ assembly.xml文件内容如下: ``` -## 六、排除集群中已经存在的Jar +### 2. 排除集群中已经存在的Jar -为了避免冲突通常官方文档通常都会建议你排除集群中已经提供的Jar包,如下: +通常为了避免冲突,官方文档都会建议你排除集群中已经提供的Jar包,如下: Spark 官方文档 Submitting Applications 章节: @@ -250,14 +257,41 @@ Strom官方文档 Running Topologies on a Production Cluster 章节: >Then run mvn assembly:assembly to get an appropriately packaged jar. Make sure you exclude the Storm jars since the cluster already has Storm on the classpath. - +排除Jar包的方式主要有以下两种: + 对需要排除的Jar包依赖添加`provided`标签,此时该Jar包会被排除,但是不建议使用这种方式,因为此时你在本地运行也无法使用该Jar包; + 建议直接在`maven-assembly-plugin`或`maven-shade-plugin`的配置文件中使用``进行排除。 -## 七、使用建议 +### 3. 打包.scala文件 -通常使用`maven-shade-plugin`就能够完成大多数的打包需求,其配置简单且适用性最广,因此建议使用此方式。 +如果你使用到scala语言进行编程,此时需要特别注意 :默认情况下Maven是不会把`.scala`文件打入最终的Jar中,需要额外添加`maven-scala-plugin`插件,常用配置如下: + +```xml + + org.scala-tools + maven-scala-plugin + 2.15.1 + + + scala-compile + + compile + + + + **/*.scala + + + + + scala-test-compile + + testCompile + + + + +``` diff --git a/pictures/spark-streaming-flume-jar.png b/pictures/spark-streaming-flume-jar.png new file mode 100644 index 0000000000000000000000000000000000000000..a4e8bbe5df6b8e1637096a58d3de7f97dc0486ad GIT binary patch literal 21168 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 literal 0 HcmV?d00001