Flink流处理API
Environment
创建一个执行环境,表示当前执行程序的上下文。 如果程序是独立调用的,则此方法返回本地执行环境;如果从命令行客户端调用程序以提交到集群,则此方法返回此集群的执行环境,也就是说,getExecutionEnvironment
会根据查询运行的方式决定返回什么样的运行环境,是最常用的一种创建执行环境的方式。
创建一个批处理
val env = ExecutionEnvironment.getExecutionEnvironment
创建一个流处理
val env = StreamExecutionEnvironment.getExecutionEnvironment
如果没有设置并行度,会以flink-conf.yaml
中的配置为准,默认是 1。
并行度的优先级是
每个函数 > 整个程序 > 配置文件
Source
从集合读取数据
package Source
import org.apache.flink.streaming.api.scala._
//定义样例类
case class SensorReading(id: String, timeStamp: Long, temperature: Double)
object SourceFromCollection {
def main(args: Array[String]): Unit = {
//创建执行环境
val env = StreamExecutionEnvironment.getExecutionEnvironment
//从集合中读取数据
val dataList = (List(
SensorReading("sensor_1", 1547718199, 35.8),
SensorReading("sensor_6", 1547718201, 15.4),
SensorReading("sensor_7", 1547718202, 6.7),
SensorReading("sensor_10", 1547718205, 38.1)
))
//从集合中读取数据
val stream1 = env.fromCollection(dataList)
stream1.print()
env.execute()
}
}
我们可以发现我们输出的数据和输入数据的顺序是不一样的,这是因为我们没有设置并行度,那么他就会按照CPU
的个数来设置并行度,由于是并行的那么输出的顺序就是不一样的
在读取数据的时候有一个特殊的方法fromElements
,他读取的数据类不限,你给他说明他就输出说明
val stream1 = env.fromElements(dataList)
val stream2 = env.fromElements(1.0,"aa",1)
stream1.print()
stream2.print()
从文件读取数据
先创建文件数据
sensor_1,1547718199,35.8
sensor_6,1547718201,15.4
sensor_7,1547718202,6.7
sensor_10,1547718205,38.1
package Source
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
object SourceFromFile {
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
//读取文件
val filePath = "src/main/resources/SensorReading"
val inputStream = env.readTextFile(filePath)
inputStream.print()
env.execute()
}
}
从Kafka读取数据
在与Kafka
连接时,需要先导入一个依赖
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka-0.11_2.12</artifactId>
<version>1.10.1</version>
</dependency>
为什么程序中是消费者?
- 因为我们从
Kafka
的生产者中输出数据,在通过Kafka
的消费者里读取数据
package Source
import org.apache.flink.api.common.serialization.SimpleStringSchema
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer011
import org.apache.flink.streaming.api.scala._
import java.util.Properties
object SourceFromKafka {
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
//配置项
val properties = new Properties()
properties.setProperty("bootstrap.servers", "master: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")
//这边是要读取Kafka的数据,所以算是一个消费者
/**
* 第一个泛型:读取过来的数据类型
* 第一个参数:Kafka名
* 第二个参数:序列化
* 第三个参数:配置项
*/
val stream =
env.addSource(new FlinkKafkaConsumer011[String]
("first", new SimpleStringSchema(), properties))
stream.print()
env.execute()
}
}
FlinkKafkaConsumer011
的参数解释
- 泛型是获取到的数据类型
- 第一个参数是
Kafka
得到管道名 - 第二个参数是获取数据类型的序列化
- 第三个参数是配置项
确保zookeeper
和Kafka
开启
zookeeper
开启命令:zkServer.sh start
kafka
开启命令:bin/kafka-server-start.sh -daemon config/server.properties
创建Kafka
管道
- 命令如下:
bin/kafka-topics.sh --create --zookeeper 192.168.23.69:2181 --replication-factor 3 --partitions 1 --topic first
- 开生产者:
bin/kafka-console-producer.sh --broker-list a:9092 --topic first
需要修改window
的映射文件,否则会报错
结果展示
自定义Source
我首先需要先自定义个Source
,需要继承SourceFunction
类,泛型是输出的数据类型
/**
* 自定义Source类
*/
class MySensorSource() extends SourceFunction[SensorReading] {
//定义一个标志位flag,依赖表示数据源是否正常运行发出数据
var flag