[1] Flume简介与安装配置
1.Flume简要介绍
Flume是Cloudera提供的一个高可用、高可靠、分布式的海量日志采集、聚合和传输的系统。Flume支持在日志系统中定制各类数据发送方用于收集数据,同时Flume提供对数据的简单处理,并将数据处理结果写入各种数据接收方的能力。
官网 http://flume.apache.org/index.html
Flume的主要构件如下:
理解Flume的工作原理可以从其逻辑上的三层架构上着手:
agent用于数据的采集,collector是扮演汇总数据的功能,storage是存储系统,可以是文件、数据库等。
2.Flume安装、配置与测试
(1)Flume安装
在安装之前确保已经按照好Java和Spark的环境,下载并解压对应版本的Flume安装包,我需要下载的版本是1.7.0(link)。
S1:解压安装包(建议切换到root权限下进行)
tar -zxvf apache-flume-1.7.0-bin.tar.gz
进入目录下,可以看到以下内容:
S2:配置环境变量
vi ~/.bashrc
在文件中配置以下路径:
export FLUME_HOME=/opt/flume
export FLUME_CONF_DIR=$FLUME_HOME/conf
export PATH=$PATH:$FLUME_HOME/bin
重新使之生效:
source ~/.bashrc
(2)Flume配置
修改配置文件,进入/opt/flume/conf目录,复制.template为新的.sh文件
cd /opt/flume/conf
cp ./flume-env.sh.template ./flume-env.sh
vi ./flume-env.sh
在flume-env.sh中插入java环境变量
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.272.b10-1.el8_2.x86_64
进入bin目录下,并查看版本
cd /opt/flume/bin
flume-ng version
出现下图表示Flume安装成功:
(3)Flume测试——netcat数据源
S1:创建agent配置文件
cd /opt/flume/conf
vi example.conf #创建配置文件,命名为example.conf
在配置文件中写入以下内容:
# 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
#满足题目要求,开放的是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
在配置文件中写入的内容描述了sink、channel、sources的基本配置以及三者之间的关系。
S2:启动flume agent
输入以下命令(建议在flume目录下操作,因为要跨bin目录和conf目录):
./bin/flume-ng agent --conf ./conf --conf-file ./conf/example.conf --name a1 -Dflume.root.logger=INFO,console
上图展示了flume终端启动的结果,可以看到在本地44444端口已经启动了flume agent的服务。
另启一个cmd窗口,尝试使用telnet进行连接:
>>>telnet localhost 44444
PS:telnet没有安装的话自行安装,不再赘述。
输入若干数据进行测试:
在新开启的终端(称为telnet端)中:
在agent服务端显示的结果:
说明基于netcatsource的Flume测试成功!
[2] Sparkstreaming 接收Flume数据
1.配置Spark的流处理环境
S1:下载流处理需要的jar包:
jar包的下载地址为:
https://mvnrepository.com/artifact/org.apache.spark/spark-streaming-flume_2.11/2.4.7注意jar包版本的对应关系
2.4.7是spark的版本,Scala适用版本是2.11,下载jar包即可。其他版本做相应修改即可。
S2:将jar包放入/jars/flume文件夹中,使用docker cp命令
docker cp F:\spark-streaming-flume_2.11-2.4.7.jar f9327942ac73:/opt/spark-2.4.7-bin-hadoop2.7/jars
S3:将flume安装路径下的lib目录下的所有jar包拷贝到spark的jars目录下
cp /opt/flume/lib/* /opt/spark-2.4.7-bin-hadoop2.7/jars/flume
overwrite是正常的,一直按Enter即可。
S4:测试
打开spark-shell,输入以下命令
import org.apache.spark.streaming.flume._
在使用spark-shell的时候出现了一些小插曲:
错误的信息是本地启动spark-shell无法找到“sparkDriver”,在查阅资料后发现是spark-env.sh中需要进行如下配置,加入一行IP设置:
SPARK_LOCAL_IP = 127.0.0.1
出现上图说明环境配置完毕,输入:quit退出spark-shell。
2.命令行中编写scala程序测试流处理过程
S1:Flume配置
进入flume的conf目录下,新建一个配置文件flume2spark.conf,写入以下内容:
#flume2spark.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 = 33333
# Describe the sink
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = localhost
a1.sinks.k1.port =44444
# Use a channel which buffers events in memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000000
a1.channels.c1.transactionCapacity = 1000000
# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
可以与前面的example.conf进行对比,可以看到sink多了一些配置项:类别设置为avro,绑定到localhost的44444端口。这样,Flume Source把采集到的消息汇集到Flume Sink以后,Sink会把消息推送给localhost的44444端口,而我们编写的Spark Streaming程序一直在监听localhost的44444端口,一旦有消息到达,就会被Spark Streaming应用程序取走进行处理。
S2:sbt安装
下载安装包:https://www.scala-sbt.org/download.html 如果没有梯子的话下载的速度很慢很慢,可以去csdn上找别人下载好的,而后执行以下步骤:
tar -zxvf sbt-1.1.4.tgz # 解压
cd /usr/software/sbt/ # 进入解压目录
vim sbt # 新建一个名字为sbt的文本,并在在文本中加入以下内容
#!/bin/bash
SBT_OPTS="-Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M"
java $SBT_OPTS -jar /usr/software/sbt/bin/sbt-launch.jar "$@" # 注意对应路径
# wq保存退出
chmod u+x ./sbt # 修改sbt脚本文件权限
sudo vim /etc/profile # 配置PATH环境变量
# 在文件最后添加:
export PATH=/usr/software/sbt/:$PATH
# wq保存退出
source /etc/profile # 使配置文件立刻生效
而后可以进行测试
sbt sbtVersion
这之后会进行依赖包的下载,也非常的慢:
下载完成后再次执行上述命令,可以打印出版本信息。
多写一点吧:初始化的时候这些库下载很慢可以通过配置国内源解决,具体方法如下:
cd ~./sbt
vi repositories
#以下是要写在文件repositories的内容
[repositories]
local
osc: http://maven.aliyun.com/nexus/content/groups/public/
typesafe: http://repo.typesafe.com/typesafe/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext], bootOnly
sonatype-oss-releases
maven-central
sonatype-oss-snapshots
#end(阿里云的服务截止到2021.01还可以使用,有些国内服务可能不太行了,大家慎重选择!)
完事之后可以进行初始化工作。
S3:编写程序
mkdir mycode
mkdir -p src/main/scala
vi FlumeEventCount.scala
vi StreamingExamples.scala
其中 FlumeEventCount.scala中写入:
package org.apache.spark.examples.streaming
import org.apache.spark.SparkConf
import org.apache.spark.storage.StorageLevel
import org.apache.spark.streaming._
import org.apache.spark.streaming.flume._
import org.apache.spark.util.IntParam
object FlumeEventCount {
def main(args: Array[String]) {
if (args.length < 2) {
System.err.println(
"Usage: FlumeEventCount <host> <port>")
System.exit(1)
}
StreamingExamples.setStreamingLogLevels()
val Array(host, IntParam(port)) = args
val batchInterval = Milliseconds(2000)
// Create the context and set the batch size
val sparkConf = new SparkConf().setAppName("FlumeEventCount").setMaster("local[2]")
val ssc = new StreamingContext(sparkConf, batchInterval)
// Create a flume stream
val stream = FlumeUtils.createStream(ssc, host, port, StorageLevel.MEMORY_ONLY_SER_2)
// Print out the count of events received from this server in each batch
stream.count().map(cnt => "Received " + cnt + " flume events." ).print()
ssc.start()
ssc.awaitTermination()
}
}
StreamingExamples.scala中写入:
package org.apache.spark.examples.streaming
import org.apache.log4j.{Level, Logger}
import org.apache.spark.internal.Logging
object StreamingExamples extends Logging {
/** Set reasonable logging levels for streaming if the user has not configured log4j. */
def setStreamingLogLevels() {
val log4jInitialized = Logger.getRootLogger.getAllAppenders.hasMoreElements
if (!log4jInitialized) {
// We first log something to initialize Spark's default logging, then we override the
// logging level.
logInfo("Setting log level to [WARN] for streaming example." +
" To override add a custom log4j.properties to the classpath.")
Logger.getRootLogger.setLevel(Level.WARN)
}
}
}
再次切换到mycode目录下,新建一个simple.sbt文件,用于完成对资源的编译。
在文件中写入:
name := "Simple Project"
version := "1.0"
scalaVersion := "2.11"
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.4.7"
libraryDependencies += "org.apache.spark" % "spark-streaming_2.11" % "2.4.7"
libraryDependencies += "org.apache.spark" % "spark-streaming-flume_2.11" % "2.4.7"
修改对应版本号即可。
S4:打包并运行
切换到mycode目录下,完成编译打包工作:
cd /opt/spark-2.4.7-bin-hadoop2.7/mycode/
/opt/sbt_1.2.1_linux/sbt/sbt package
(1)第一个终端:执行Scala程序
cd /opt/spark-2.4.7-bin-hadoop2.7
./bin/spark-submit --driver-class-path /opt/spark-2.4.7-bin-hadoop2.7/jars/*:/opt/spark-2.4.7-bin-hadoop2.7/jars/flume/* --class "org.apache.spark.examples.streaming.FlumeEventCount" /opt/spark-2.4.7-bin-hadoop2.7/mycode/target/scala-2.11/simple-project_2.11-1.0.jar localhost 44444
(2)第二个终端:启动Flume服务
cd /opt/flume
bin/flume-ng agent --conf ./conf --conf-file ./conf/flume2spark.conf --name a1 -Dflume.root.logger=INFO,console
这时Flume的agent会一直监听33333端口消息,并把消息传递在44444端口工作的Scala程序。
(3)第三个终端:telnet连接
>>>telnet localhost 33333
类似于Flume测试时的netcat测试,在第三个终端输入文本,可以由Flume采集到数据并传递给Scala程序进行处理。
[3] 总结
1.上述完成了对Flume+SparkStreaming从无到有的全部实验过程,对Spark技术栈中的Spark Streaming有了进一步的认识;
2.在编写程序过程全程使用的Terminal的方法,使用了sbt编译工具,简单方便。当然也可以在IDEA中进行编写,打jar包提交执行,在第二次实验中直接提交集群一直出错,目前仍未得到解决。考虑到下一步可能使用python语言在jupyter中与Spark集群进行链接。这里不再做基于IDEA的程序执行工作;
3.在实验的过程中没有很复杂的内容,只是网络一直不行,下载各种安装包很慢;