DataSources 模块定义了DataStream API 中的数据输入操作,Flink 将数据源主要分为内置数据源和第三方数据源。其中内置数据源包含文件、Socket网络端口、集合类型数据,不需要引入第三方依赖。第三方数据源定义了数据的读写接口和丰富的第三方数据源连接器。例如Kafka 、Elasticsearch 等。同时用户也可以自定义实现Flink中数据接入函数SourceFuntion,并封装成第三方数据源的connector,完成flink与其他外部系统的数据交互。
1、内置数据源
(1)文件数据源
在StreamExecutionEnvironment中,可以使用readTextFile方法直接读取文本文件,也可以使用readFile方法通过指定文件InputFormat来读取指定数据类型的文件,其中InputFormat 可以是系统已经定义的InputFormat类,如CsvInputFormat等,也可以用户自定义实现InputFormat接口类。
var env = StreamExecutionEnvironment.getExecutionEnvironment
//直接读取文本文件
var textFile = env.readTextFile("/user/local/data.log")
//通过指定csvInput
var csvStream = env.readFile(new CsvInputFormat[String](new Path("/user/local/data.csv")) {
override def fillRecord(out: String, objects: Array[AnyRef]): String = {
return null
}
},"/user/local/data.csv")
在DataStreamAPI 中,可以在readFile方法中指定文件读取类型(WatchType),检测文件变化的时间间隔(interval)、文件路径过滤条件(FilePathFilter)等参数,其中WatchType共分为两种模式-PROCESS_CONTINUOUSLY和PROCESS_ONCE模式,在PROCESS_CONTINUOUSLY模式下,一旦检测到文件发生变化,就会把文件内容全部加载到flink系统中进行处理,而在PROCESS_ONCE模式下,当文件发生变化时,只会将发生变化的数据加载到flink系统中,在这种情况数据只会被读取和处理一次。
notes:在PROCESS_CONTINUOUSLY模式下无法保证数据的Excatly Once ,而在PROCESS_ONCE模式下可以。如果使用文件作为数据源时,当某个节点挂了,这种情况下checkpoint不会更新,如果数据一直不断生成将导致数据形成积压,可能需要耗费很长的时间从最新的checkpoint中恢复。
(2)Socker数据源
Flink支持从socket端口中接入数据,在StreamExecutionEnvironment调用SocketTextStream方法。参数有ip地址、端口、字符串切割符delimiter、最大尝试次数maxRetry。
var socketDataStream = env.socketTextStream("localhost",9999)
(3)集合数据源
Flink可以直接将Java或Scala程序中集合类(Collection)转换成DataStream数据集,本质上是将本地集合中的数据分发到远端并行执行的节点中。目前Flink 支持从Java.util.Collection和java.util.Iterator序列中转换成DataStream数据集。数据集内的数据结构必须保持一致,否则可能会出现数据转换异常。
a、通过fromElements从元素集合中创建DataStream 数据集:
val dataStream = env.fromElements(Tuple2(1L,3L),
Tuple2(1L,5L),Tuple2(1L,7L),Tuple2(1L,4L),Tuple2(1L,2L))
b、通过fromCollection从数组转创建DataStream数据集:
String [] elements = new String []{"hello","flink"};
DataStream<String> dataStream = env.fromCollection(Arrays.
asList(elements));
c、将java.util.List转换成DataStream数据集:
List<String> arrayList = new ArrayList<>();
arrayList.add("hello flink");
DataStream<String> dataList = env.fromCollection(arrayList);
2、外部数据源
(1)数据源连接器
对于流式计算的应用来说,数据大部分都来源于第三方系统,所以flink通过实现SourceFunction定义了非常丰富的第三方数据连接器,其中一部分仅支持读取,如Twitter、Netty,另外一部分既支持数据输入又支持数据输出,如Kafka、Amazon Kinesis、RabbitMQ等。
引入kafka连接器:
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka-0.8_2.11</artifactId>
<version>1.7</version>
</dependency>
在kafka connector 中主要的参数有kafka topic、bootstrap.server、zookeeper.connect 。Schema参数的主要作用是根据事先定义好的Schema信息将数据序列化成该Schema定义的数据类型,默认是SimpleStringSchema,表示从Kafka中接入的数据默认转换成String 字符串处理。
//Properties 参数定义
Properties properties = new Properties();
properties.setProperty("bootstrap.servers","localhost:9092");
properties.setProperty("zookeeper.connect","localhost:2181");
properties.setProperty("group.id","test");
DataStream<String> input = env.addSource(
new FlinkKafkaConsumer010<>(
properties.getString("input-data-topic"),
new SimpleStringSchema(),
properties
);
)
(2)自定义数据源连接器
Flink 已经实现了大多数主流的数据源连接器,用户也可以实现自定义的连接器。可以通过实现SourceFuntion 定义单个线程的接入的数据接入器,也可以通过实现ParallelSourceFunction接口或继承RichParallelSourceFunction 类定义并发数据源接入器。定义完数据接入器后,使用StreamExecutionEnvironment 的addSource 方法添加数据源
博主个人微信公众号,不定期发布技术文章,喜欢的可以关注一下哈