Demo-Scala_SBT
使用SBT构建flink的Scala项目:
1.新建一个scala-SBT项目
2.Next
- 目前idea使用的sbt版本为0.13.X系列与我本地的1.0.0版本不同,但是不要紧,不影响执行命令时,会使用本地的SDK。【官方目前主要维护的版本有两个:0.13.X和1.X。需要注意的是,IDEA上的SBT插件暂时是随着0.13.X系列更新的,而我本地是1.0.0】
- scala我这里是2.11.11,虽然我本地有个2.12.3的SDK,spark2开始到目前最新版本是scala2.11构建的(2.3.0开始不再支持2.10.x),Flink的scala部分也是2.11.x构建的。
SBT相关还可以参考IDEA上Spark——Java、Scala的本地测试版与集群运行版和了解、安装sbt,使用sbt(console、IDEA)。
3.修改配置
- sbt.version:
手动修改build.properties中的sbt.version = 1.0.0之后再刷新build.sbt发觉行不通,报错。于是保持
sbt.version = 0.13.17【1.0.0貌似是scala2.12构建,0.13是2.10】 - build.sbt中添加依赖:
libraryDependencies += "org.apache.flink" %% "flink-clients" % "1.6.1"
libraryDependencies += "org.apache.flink" %% "flink-scala" % "1.6.1"
libraryDependencies += "org.apache.flink" %% "flink-streaming-scala" % "1.6.1"
4.code
import org.apache.flink.api.java.utils.ParameterTool
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.streaming.api.windowing.time.Time
/**
* <p>package: </p>
*
* descirption: Flink官方WordCount程序
*
* @author 王海
* @version V1.0
* @since <pre>2018/10/5 21:53</pre>
*/
object SocketWindowWordCount {
def main(args: Array[String]): Unit = {
// 从args中获取用于连接的端口
val port: Int = try {
ParameterTool.fromArgs(args).getInt("port")
} catch {
case e: Exception =>
System.err.println("No port specified. Please run 'SocketWindowWordCount --port <port>'")
return
}
// 获取流式运行环境
val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
// 得到所连接的socket中的流式数据
//【这个地方,建议改为ip address,我在后面踩了这个坑。】
val text = env.socketTextStream("localhost", port, '\n')
// 解析数据, 分组, 窗口化,且聚合求SUM,TIme是windowing.time.Time封装的
val windowCounts = text
.flatMap { w => w.split("\\s") }
.map { w => WordWithCount(w, 1) }
.keyBy("word")
.timeWindow(Time.seconds(5), Time.seconds(1))
.sum("count")
// 单线程打印结果
windowCounts.print().setParallelism(1)
env.execute("Socket Window WordCount")
}
// 定义一个数据类型统计单词出现的次数
case class WordWithCount(word: String, count: Long)
}
5.sbt打包
- IDEA中命令行直接执行
sbt package
命令
- 报错:
could not find implicit value for evidence parameter of type org.apache.flink.api.common.typeinfo.TypeInformation[String]
[error] .flatMap { w => w.split("\\s") }
解决办法
import org.apache.flink.api.scala._
断断续续的用着SBT,真心觉得不如Maven好用,或许是我还没有更多的机会去体会吧。不过目前我觉得,无论是稳定性,还是IDE的支持度,还是社区的活跃度还是用户数,SBT与Maven间还是有很大的差距。
6.netcat
- wget -c http://vault.centos.org/6.9/os/x86_64/Packages/nc-1.84-24.el6.x86_64.rpm
- rpm -iUv nc-1.84-24.el6.x86_64.rpm
- netcat启动一个本地socket
nc -l 8888
- 提交运行flink程序
./flink run /home/flinkdemo1_2.11-1.0.jar --port 8888
报错:
org.apache.flink.client.program.ProgramInvocationException: Neither a 'Main-Class', nor a 'program-class' entry was found in the jar file.
我们大致可以感觉到,是程序入口出了问题,猜测是不是我的jar包里有多个main的原因,去除非相关类。再打包运行。
Caused by: java.net.ConnectException: Connection refused (Connection refused)
为了排除其他原因,先
- 运行官方打包好的例子(examples目录下):
依然报错:Caused by: java.net.ConnectException: Connection refused (Connection refused)
- 防火墙已关,并且socket是连接的本地socket,为何会拒绝?
- 折腾了会,实在是想不出解决办法,于是修改代码中localhost为ip address,打包再运行,竟然成功了。。。
我的输入如下:
out文件如下:
注意:
- 运行时,结果不是print到屏幕的,一边向socket输入流一边盯着"Starting execution of program"是不会变的。
- 执行结果写入了
log/flink-*-taskexecutor-*.out
中,这一点,官方是有写的。 - 并不是所有TaskManager的out文件都有执行结果(照我的理解,只有一台机器参与持久化),各个TaskManager的机器,你都可以试一下。
收回之前说的web端功能”不丰富“的so simple的想法:
hadoop、spark的作业执行页面中的一些统计功能,查看执行stage的功能(spark)等等
Demo-Scala_Maven
等换一个demo再写。
Demo-Java
等换一个demo再写。
TODO
[1.] localhost时socket为何拒绝连接?
[2.] Overview界面中的Tasks各个状态的进一步理解?(tatal,created,scheduled,depoyling,running,finished,canceling,canceled,failed,reconciling)
[3.] out文件为什么每个输出打印5次?代码里面没有这个逻辑;TaskManager也只有3个而不是5个。
参考
[1.] CSDN-Dax1n:No Implicit Value for Evidence Parameter Error
[2.] setup_quickstart