Spark Streaming整合Flume实战一
简介
一、简介
Apache Flume 是一个分布式,高可用的数据收集系统,可以从不同的数据源收集数据,经过聚合后发送到分布式计算框架或者存储系统中。Spark Straming 提供了以下两种方式用于 Flume 的整合。
二、推送式方法-Push
在推送式方法 (Flume-style Push-based Approach) 中,Spark Streaming 程序需要对某台服务器的某个端口进行监听,Flume 通过 avro Sink 将数据源源不断推送到该端口。
三、基于拉方式处理-Pull
Spark Streaming 基于拉方式处理 Flume-ng 数据源(Pull-based Approach using a Custom Sink)
这种方式不是 Flume 直接推送数据到 SparkStreaming ,这种方法运行了一个如下所示的 Flume Sink 。
1. Flume 将数据推送到 Sink 中,然后数据在此处缓存。
2. Spark Streaming 使用一个可靠的 Flume 接收器和事务从 Sink 中拉取数据。只有在 SparkStreaming 接收到数据并且把数据复制后才认为操作成功。
这个方法比前面的方法提供了强大的可靠性和容错保证。然而,这需要配置 Flume 运行一个自定义 Sink 。
四、总结
pull模式:这种模式是Spark自定义了一个Flume的sink作为Avro Server,flume收集到的数据发往这个sink,然后数据存储在这个sink的缓存中,然后Spark Streaming启动包含有Avro Client的Recevier从自定义的Flume的sink中拉取数据。一般工作中选择Pull的这种方式,相对于push模式,这种模式更加的可靠不会丢失数据,这个是因为以下两点原因:
1、pull模式的Receiver是一个可靠的Receiver,就是这个Receiver接收到了数据,并且将这个数据存储并且备份了后会发送一个ack响应给Flume的sink
2、结合Flume的事务特性,保证了数据不会丢失,一定会拉取到数据,如果没有拉取成功的话(就是Flume Sink没有接收到Receiver发送的ack),则事务失败
案例一:推送式方法:Flume-style Push-based Approach
1、配置Flume-Agent
- 从配置文件中拷贝一份配置进行修改。
cp exec-memory-avro.conf flume_push_streaming.conf
- 修改后的配置文件内容
simple-agent.sources = netcat-source
simple-agent.sinks = avro-sink
simple-agent.channels = memory-channel
#数据的来源
simple-agent.sources.netcat-source.type = netcat
#从服务器的44444端口获取数据
simple-agent.sources.netcat-source.bind = 192.168.118.151
simple-agent.sources.netcat-source.port = 44444
simple-agent.sinks.avro-sink.type = avro
#接受数据的机器
#实验时为我的开发机器地址。
simple-agent.sinks.avro-sink.hostname = 192.168.31.131
simple-agent.sinks.avro-sink.port = 41414
#simple-agentwhich buffers events in memory
simple-agent.channels.memory-channel.type = memory
#simple-agente and sink to the channel
simple-agent.sources.netcat-source.channels = memory-channel
simple-agent.sinks.avro-sink.channel = memory-channel
2、编写Spark程序
object FlumePushWordCount {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setMaster("local[2]").setAppName("FlumePushWordCount");
val ssc = new StreamingContext(sparkConf,Seconds(5));
val flumeStream = FlumeUtils.createStream(ssc,"0.0.0.0",41414)
flumeStream.map(x=>new String(x.event.getBody.array()).trim).flatMap(_.split(" ")).map((_,1))
.reduceByKey(_+_).print();
ssc.start();
ssc.awaitTermination();
}
}
3、启动
- 先启动IDEA中的Spark Streaming程序。
- 再启动flume。
flume-ng agent \
--name simple-agent \
--conf $FLUME_HOME/job \
--conf-file $FLUME_HOME/job/flume_push_streaming.conf \
-Dflume.root.logger=INFO,console &
- 然后在linux机器上向本机44444端口传输数据。(注意机器名字要用配置文件中的。)
[root@hadoop01 ]# telnet 192.168.118.151 44444
Trying 192.168.118.151...
Connected to 192.168.118.151.
Escape character is '^]'.
a
OK
a
OK
a
OK
d
OK
d
OK
从idea中查看统计单词结果a发送了三次,d发送了两次
4、代码重构
生产上hostname和port应该手动输入,需要对代码进行修改
import org.apache.spark.SparkConf
import org.apache.spark.streaming.flume.FlumeUtils
import org.apache.spark.streaming.{Seconds, StreamingContext}
/**
* Created by llp on 2021/4/30.
* Spark Streaming整合Flume的第一种方式-生产
*/
object FlumePushWordCount2 {
def main(args: Array[String]): Unit = {
if (args.length != 2) {
System.err.println("Usage: FlumePushWordCount <hostname port>")
System.exit(1)
}
val Array(hostname, port) = args
val sparkConf = new SparkConf() //.setMaster("local[2]").setAppName("FlumePushWordCount");
val ssc = new StreamingContext(sparkConf, Seconds(5))
//因为port是int类型,所以需要转成int类型
val flumeDStream = FlumeUtils.createStream(ssc, hostname, port.toInt)
flumeDStream.map(x => new String(x.event.getBody.array()).trim)
.flatMap(_.split(" "))
.map((_, 1))
.reduceByKey(_ + _)
.print()
ssc.start()
ssc.awaitTermination()
}
}
在IDEA中传入参数进行测试,点击右上角,选择Edit Configuration
在Program argument中填入参数,以空格分隔。
5、本地测试总结
1)先启动Spark Streaming作业 (因为Flume需要推送数据)
2)再启动flume agent
3)通过telnet输入数据,观察IDEA控制台的输出
6、Push方式整合服务器联调
1.使用maven对项目进行打包
mvn clean package -DskipTests
得到SparkStreamingProject-1.0.jar(注意此jar包是不包含依赖的),使用spark-submit提交时,要导入所需依赖。
根据官网提示导入依赖使用–packages org.apache.spark:spark-streaming-flume_2.11:2.2.0
官网链接:https://spark.apache.org/docs/2.2.0/streaming-flume-integration.html
2.使用spark-submit命令提交
spark-submit \
--class com.bigdata.streaming.FlumePushWordCount2 \
--master local[2] \
--packages org.apache.spark:spark-streaming-flume_2.11:2.2.0 \
/home/hadoop/lib/SparkStreamingProject-1.0.jar \
hadoop01 41414
注意:–packages org.apache.spark:spark-streaming-flume_2.11:2.2.0是需要联网去下载依赖的,在生产中是不能联网的,需要将jar包下载下来,使用 --jars参数
eg: spark-submit --master yarn-client --jars xxx.jar,xxx.jar (多个jar包,用逗号分隔) ,jar包下载地址
3.启动Flume agent
flume-ng agent \
--name simple-agent \
--conf $FLUME_HOME/job \
--conf-file $FLUME_HOME/job/flume_push_streaming.conf \
-Dflume.root.logger=INFO,console
启动flume之前需要将flume_push_streaming.conf文件中的simple-agent.sinks.avro-sink.hostname配置项改成测试中接收数据的服务器地址
4.通过telnet输入数据
[root@hadoop01 ~]# telnet 192.168.118.151 44444
Trying 192.168.118.151...
Connected to 192.168.118.151.
Escape character is '^]'.
统计结果