DataStream API(四)
今天我们来聊聊Flink中的Sink操作。
Sink
了解Spark的童鞋应该都知道Spark的输出是迭代进行的。可是Flink好像没有类似于Spark中的foreach的方法。怎么办呢?虽然Flink并没有和Spark类似的forEach方法,让用户进行迭代操作。但是Flink为对外的输出操作提供了Sink API。所有的Sink操作最后都是通过以下方式完成的
stream.addSink(new MySink(xxxx))
其中MySink类继承自RichSinkFunction类,而RichSinkFunction类实现了SinkFunction接口。
Flink官方为我们提供了一部分框架的Sink,Apache Bahir也为我们提供了一部分框架的Sink,除了这些之外我们只能自定义Sink。下面是官网上列出的一些Sink。
从上图我们可以看出Flink官方并没有给出Redis的Sink而Bahir为我们提供了。所以当我们想输出数据到Redis时,需要引用Bahir的依赖。
Kafka Sink
pom.xml中引用kafka依赖
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka_2.11</artifactId>
<version>1.11.0</version>
</dependency>
主函数中添加sink
map.addSink(new FlinkKafkaProducer<String>("localhost:9092", "test", new SimpleStringSchema()));
Redis
pom.xml中引入Bahir依赖
<dependency>
<groupId>org.apache.bahir</groupId>
<artifactId>flink-connector-redis_2.11</artifactId>
<version>1.0</version>
</dependency>
自定义Redis的Mapper类
private static class MyRedisMapper implements RedisMapper<Sensor>{
public RedisCommandDescription getCommandDescription() {
return new RedisCommandDescription(RedisCommand.HSET,"sensor_temperature");
}
public String getKeyFromData(Sensor sensor) {
return sensor.getId();
}
public String getValueFromData(Sensor sensor) {
return sensor.getTemperature().toString();
}
}
主函数调用
FlinkJedisPoolConfig conf = new FlinkJedisPoolConfig.Builder().setHost("localhost").setPort(6379).build();
heigh.addSink(new RedisSink<Sensor>(conf,new MyRedisMapper()));
Elasticsearch
pom.xml中引入elasticsearch依赖
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-elasticsearch6_2.11</artifactId>
<version>1.11.0</version>
</dependency>
主函数调用ES Sink
List<HttpHost> httpHosts = new ArrayList<HttpHost>();
httpHosts.add(new HttpHost("localhost",9200));
ElasticsearchSink.Builder<Sensor> esSinkBuilder = new ElasticsearchSink.Builder<Sensor>(httpHosts, new ElasticsearchSinkFunction<Sensor>() {
public void process(Sensor sensor, RuntimeContext runtimeContext, RequestIndexer requestIndexer) {
HashMap<String, String> json = new HashMap<String, String>();
json.put("data", sensor.toString());
IndexRequest indexRequest = Requests.indexRequest().index("sensor").type("readingdata").source(json);
requestIndexer.add(indexRequest);
}
});
dataStream.addSink(esSinkBuilder.build());
经过四个章节的介绍一些基本的DataStream API也介绍的差不多了,现在算是一个小小的里程碑吧!经过上面的学习我们完全可以实现一些简单的流处理了。但是,要想实现更复杂的需求还是比较困难的。举个栗子:想要每1秒钟计算一次最近5秒内的传感器最高温度。要实现这个需求用以前的知识肯定是不能或者说不容易完成的。那么我们要怎么实现这个功能呢?请听下回分解…