Flink流处理流程:首先创建环境(类似于spark里的上下文SparkContext);其次,添加数据来源Source;再次,对数据进行Transform处理;最后,添加输出Sink。
准备两个文件hello.txt和sensor.txt
①hello.txt的内容:
how are you
fine thank you
and you
i am fine too thank you
②sensor.txt的内容:
sensor_1, 1547718199, 35.80018327300259
sensor_6, 1547718201, 15.402984393403084
sensor_7, 1547718202, 6.720945201171228
sensor_10, 1547718205, 38.101067604893444
sensor_6, 1547718206, 35.15018227300459
sensor_1, 1547718207, 35.621945601171228
1 Enviroment
(1)getExecutionEnvironment
创建一个执行环境,表示当前执行程序的上下文。 如果程序是独立调用的,则此方法返回本地执行环境;如果从命令行客户端调用程序以提交到集群,则此方法返回此集群的执行环境,也就是说,getExecutionEnvironment会根据查询运行的方式决定返回什么样的运行环境,是最常用的一种创建执行环境的方式。
val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
如果没有设置并行度,会以flink-conf.yaml中的配置为准,默认是1。
(2)createLocalEnvironment
返回本地执行环境,需要在调用时指定默认的并行度。
val env = StreamExecutionEnvironment.createLocalEnvironment(1)
(3)createRemoteEnvironment
返回集群执行环境,将Jar提交到远程服务器。需要在调用时指定JobManager的IP和端口号,并指定要在集群中运行的Jar包。
val env = ExecutionEnvironment.createRemoteEnvironment("jobmanager-hostname", 6123,"C://jar//flink//wordcount.jar")
这里的端口号6123是JobManager的端口号。
2 Source
(1)从集合中读取数据
//定义传感器数据样例类
case class SensorReading(id:String, timeStamp:Long, temperature:Double)
val stream1 = env.fromCollection(List(
SensorReading("sensor_1", 1547718199, 35.80018327300259),
SensorReading("sensor_6", 1547718201, 15.402984393403084),
SensorReading("sensor_7", 1547718202, 6.720945201171228),
SensorReading("sensor_10", 1547718205, 38.101067604893444)
))
stream1.print("stream1")
(2)直接读取
val stream2 = env.fromElements(“flink”,1,2,0.1)
stream2.print(“stream2”)
(3)从文件中读取
val stream3 = env.readTextFile("d:/ sensor.txt")
stream3.print("stream3")
(4)从Kafka中获取
①pom文件:
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka-0.11_2.12</artifactId>
<version>1.7.0</version>
</dependency>
②主函数代码
val properties = new Properties()
properties.setProperty("bootstrap.servers", "ip地址:9092")
properties.setProperty("group.id", "consumer-group")
properties.setProperty("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
properties.setProperty("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
properties.setProperty("auto.offset.reset", "latest")
val stream4 = env.addSource(new FlinkKafkaConsumer011[String]("sensor",
new SimpleStringSchema(),properties))
stream4.print("stream4")
注:① 踩坑:程序运行成功,但获取不到数据。原因:从zookeeper获取broker的meta信息时,返回的不是ip而是hostname。解决方法:将kafka的server.properties配置文件中的host.name写成主机ip。
② SimpleStringSchema 将 kafka 获取的字节流转换为字符串
(4)从自定义的Source中 读取
①创建自定义的SensorSource
class SensorSource() extends SourceFunction[SensorReading]{
// 定义一个flag:表示数据源是否还在正常运行
var running: Boolean = true
override def cancel(): Unit =