有些维度表是存在于Redis或者MySQL中需要读取这些数据,但是现在官网只有Sink。于是可以通过自定义一个Source来实现。自定义的Source需要实现(SourceFunction、ParallelSourceFunction)或者扩展(RichSourceFunction,RichParallelSourceFunction)其中的任意一个。
下面的代码实现一个读出本地文件的一个Source
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
val text = env.addSource(new ReadText)
val mapData = text.map( line => {
println("接收到的数据:"+line)
line
})
mapData.print().setParallelism(1)
env.execute("StreamingDemoWithMyNoParallelSourceScala")
}
class ReadText extends SourceFunction[String]{
private var isRunning = true
override def run(ctx: SourceFunction.SourceContext[String]): Unit ={
val source = scala.io.Source.fromFile("D:\\data\\word.txt")
val lines = source.getLines()
for (line <- lines){
val word=line.split("|",-1)(2)
ctx.collect(word)
}
source.close()
}
override def cancel(): Unit = {
isRunning =false
}
执行结果:
总结:1.网上好多文章都写open和close方法,但是我竟然没有,于是查看了一下SourceFunction、ParallelSourceFunction源码确实没有。于是又查看了一下RichSourceFunction,RichParallelSourceFunction里面竟然有,但是IDE不自动显示只能手动override。下面为RichSourceFunction类继承关系图。
2.由于涉及到序列化问题需要将 val source = scala.io.Source.fromFile(“D:\data\word.txt”)放到run函数里面。同时要注意里面的需要for或者while要及时的退出
3.SourceFunction接口内部有SourceContext接口里面有collectWithTimestamp,emitWatermark方法。