connector
指定了需要连接table connector对应的Descriptor
withFormat
指定了输出或输入的文件格式,例如JSON或parquet等
withSchema
指定注册在Table Environment中的表结构
InAppendMode
指定了数据更新模式,
registerTable Source
将本次连接的数据源对应的TableSource注册在TableEnvironment中
tableEnviroment
.connect(...) //指定Table Connector Descriptor
.withFormat(...) //指定数据格式
.withSchema(...) //指定表结构
.inAppendMode() //指定更新模式
.registerTableSource("MyTable") //注册TableSource
Table API和SQL中使用 org.apache.flink.table.descriptors.Descriptor 接口实现类来创建Table Connector实例,在Flink内置的Table Connector有File System Connector,KafkaConnector ,以及 ES Connector等
允许用户从本地文件或者分布式文件系统中读取和写入数据,在Table API中文件系统的Table Connector可以通过FileSystem类来创建,只需要指定相应的参数即可
val env = StreamExecutionEnvironment.getExecutionEnvironment
val tabEnv = StreamTableEnvironment.create(env)
tabEnv.connect(
new FileSystem()
.path("") //可以是文件夹或文件
)
Kafka Connector支持从Kafka中消费和写入数据
tabEnv.connect(
new Kafka()
.version("0.11") //指定Kafka的版本,支持0.8,0.9,0.10,0.11
.topic("") // 指定topic信息
.property("zookeeper.connect","")
.property("bootstrap.servers","")
.property("group.id","")
//从kafka中读取数据: 指定offset的启动模式(可选)
.startFromEarliest() //从最早的offset开始消费
.startFromLatest() //从最新的offset开始消费
// .startFromSpecificOffset(...) //从指定的offset开始消费
//向kafka中写入数据,指定Flink和Kafka的数据分区策略
.sinkPartitionerFixed() //每个Flink分区最多被分配到一个kafka分区上
.sinkPartitionerRoundRobin() //flink中分区随机映射到Kafka分区上
.sinkPartitionerCustom(xxx.class) //自定义KafkaPartitioner
)
对于端到端的一致性保障,默认kafka的table connector支持到at-least-once级别,同时flink提供exactly-once级别的一致性保障,前提需要集群打开CheckPointing功能
Flink中提供了常用的Table Format,可以在Table Connector中使用,支持Connector 传输不同格式类型不同格式的数据,例如CSV,JSON,Avro等,通过withFormat方法指定
CSV Format指定分隔符切分数据记录中字段,可以使用field字段来指定字段名称和类型,使用fieldDelimiter方法来指定切割符,使用lineDelimiter来指定行切割符
需要引入依赖
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-csv</artifactId>
<version>1.9.1</version>
</dependency>
.withFormat(
new Csv()
.field("field1", Types.STRING) // 根据顺序字段指明字段名以及类型 (必选)
.field("field2", Types.INT())
.fieldDelimiter(",") // 列切割符 (可选)
.lineDelimiter("\n") // 行切割符 (可选)
.quoteCharacter('"') // 指定字符串中单个字符,默认为空 (可选)
.commentPrefix('#') // 指定comment的前缀,默认为空 (可选)
.ignoreFirstLine() // 可忽略第一行 (可选)
.ignoreParseErrors() // 是否忽略解析错误的数据,默认开启(true)
)
JSON Format 支持读取或写入的数据映射成JSON格式,在Table API中JSON Format具有三种定义方式,通过Flink数据类型定义,直接使用JSON Schema定义,将Flink Table Schema转换成JSON Schema的方式来定义,其中,JSON Schema能够定义非常复杂和嵌套的数据结构,而flink内部数据类型定义比较适合简单的Mapping关系,Flink会根据映射关系将Table中的数据类型转换成JOSN格式.如FLink中Row类型对应JSON中的object结构,String类型对应于JSON中的VARCHAR结构等,如果Flink Table Schema信息和JSON的Schema一致,则可以直接使用deriveShema从table中抽取JSON Schema信息,使用这种方式,用户只需定义一Table Schema,字段名称,类型,位置都是由Table Schema确定的
.withFormat(
new Json()
.failOnMissingField(true) //当字段缺失的时候是否解析失败(可选)
//[方式一:] 使用Flink数据类型定义,然后通过Mapping映射成JSON Schema
.schema(Types.ROW(...))
//[方式二:] 通过配置jsonSchema构建JSON Format
.jsonSchema(
"""
|{
|type:'object',
|properties:{
|id:{
|type:'number',
|},
|name:{
|type:'string',
|},
|rowtime:{
|type:'string',
|format:'date-time'
|}
|}
|}
|""".stripMargin)
//[方式三:] 直接使用Table中的Schema信息,转换成JSON结构
.deriveSchema()
)
Flink只支持object,array,number等常用的JSON Schema的子集数据类型,不支持类似于allof,anyOf,not等复杂JSON数据结构
支持读取和写入Avro格式数据,和JSON Format一样,Avro Format数据具有丰富的数据结构类型,以及快速可压缩的二进制数据形式,Avro Format结构可以通过定义Avro的SpecificRecord Class来实现.或者通过指定avroSchema的方式来定义
.withFormat(
new Avro()
//(1):通过avro SpecificRecord Class来实现
// .recordClass(xxx.class)
//(2):通过avroSchema字符串定义
.avroSchema(
"""
| {
| "type":"record",
| "name":"envent",
| "field":[
| {"name":"id","type":"long"},
| {"name":"name","type":"string"}
| ]
| }
|""".stripMargin)
)