版权声明:原创文章 欢迎参考 请勿抄袭 https://blog.csdn.net/aA518189/article/details/86474512
简介
通过flink操作redis其实我们可以通过传统的redis连接池Jpoools进行redis的相关操作,但是flink提供了专门操作redis的Redis Sink,使用起来更方便,而且不用我们考虑性能的问题,接下来将主要介绍Redis Sink如何使用。
Redis Sink简介
Redis Sink 提供用于向Redis发送数据的接口的类。接收器可以使用三种不同的方法与不同类型的Redis环境进行通信:
- 单Redis服务器
- Redis集群
- Redis Sentinel
注意:本文主要介绍如何创建与单个redis服务器通信的接收器,其他模式请参考flink官网。
如何使用Redis Sink?
Redis Sink 核心类是 RedisMappe 是一个接口,使用时我们要编写自己的redis操作类实现这个接口中的三个方法,如下所示:
getCommandDescription():设置使用的redis数据结构类型,和key的名词,通过RedisCommand设置数据结构类型 String getKeyFromData(T data):设置value中的键值对 key的值 String getValueFromData(T data);设置value中的键值对 value的值
举例:
public static class RedisExampleMapper implements RedisMapper<Tuple2<String, String>>{
public RedisCommandDescription getCommandDescription() {
return new RedisCommandDescription(RedisCommand.HSET, "HASH_NAME");
}
public String getKeyFromData(Tuple2<String, String> data) {
return data.f0;
}
public String getValueFromData(Tuple2<String, String> data) {
return data.f1;
}
}
FlinkJedisPoolConfig conf = new FlinkJedisPoolConfig.Builder().setHost("127.0.0.1").build();
DataStream<String> stream = ...;
stream.addSink(new RedisSink<Tuple2<String, String>>(conf, new RedisExampleMapper());
使用RedisCommand设置数据结构类型时和redis结构对应关系。
Data Type | Redis Command [Sink] |
---|---|
HASH | HSET |
LIST | RPUSH, LPUSH |
SET | SADD |
PUBSUB | PUBLISH |
STRING | SET |
HYPER_LOG_LOG | PFADD |
SORTED_SET | ZADD |
SORTED_SET | ZREM |
实战开发
第一步:导入Redis Sink的依赖
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-redis_2.10</artifactId>
<version>1.1.5</version>
</dependency>
第二步:编写代码 案例如下:
public class Data2Redis {
public static void main(String[] args) throws Exception {
String kafkaBrokers = null;
String zkBrokers = null;
String topic = null;
String groupId = null;
if (args.length == 4) {
kafkaBrokers = args[0];
zkBrokers = args[1];
topic = args[2];
groupId = args[3];
} else {
System.exit(1);
}
System.out.println("===============》 flink任务开始 ==============》");
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//设置kafka连接参数
Properties properties = new Properties();
properties.setProperty("bootstrap.servers", kafkaBrokers);
properties.setProperty("zookeeper.connect", zkBrokers);
properties.setProperty("group.id", groupId);
//设置时间类型
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
//设置检查点时间间隔
env.enableCheckpointing(5000);
//设置检查点模式 //env.getCheckpointConfig.setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
System.out.println("===============》 开始读取kafka中的数据 ==============》");
//创建kafak消费者,获取kafak中的数据
FlinkKafkaConsumer010<String> kafkaConsumer010 = new FlinkKafkaConsumer010<>(topic, new SimpleStringSchema(), properties);
kafkaConsumer010.setStartFromEarliest();
DataStreamSource<String> kafkaData = env.addSource(kafkaConsumer010);
kafkaData.print();
//解析kafka数据流 转化成固定格式数据流
SingleOutputStreamOperator<Tuple5<Long, Long, Long, String, Long>> userData = kafkaData.map(new MapFunction<String, Tuple5<Long, Long, Long, String, Long>>() {
@Override
public Tuple5<Long, Long, Long, String, Long> map(String s) throws Exception {
String[] split = s.split(",");
long userID = Long.parseLong(split[0]);
long itemId = Long.parseLong(split[1]);
long categoryId = Long.parseLong(split[2]);
String behavior = split[3];
long timestamp = Long.parseLong(split[4]);
Tuple5<Long, Long, Long, String, Long> userInfo = new Tuple5<>(userID, itemId, categoryId, behavior, timestamp);
return userInfo;
}
});
//实例化Flink和Redis关联类FlinkJedisPoolConfig,设置Redis端口
FlinkJedisPoolConfig conf = new FlinkJedisPoolConfig.Builder().setHost("127.0.0.1").build();
//实例化RedisSink,并通过flink的addSink的方式将flink计算的结果插入到redis
userData.addSink(new RedisSink<Tuple5<Long, Long, Long, String, Long>>(conf, new RedisExampleMapper()));
System.out.println("===============》 flink任务结束 ==============》");
//设置程序名称
env.execute("data_to_redis_wangzh");
}
//指定Redis key并将flink数据类型映射到Redis数据类型
public static final class RedisExampleMapper implements RedisMapper<Tuple5<Long, Long, Long, String, Long>> {
//设置数据使用的数据结构 HashSet 并设置key的名称
public RedisCommandDescription getCommandDescription() {
return new RedisCommandDescription(RedisCommand.HSET, "flink");
}
/**
* 获取 value值 value的数据是键值对
* @param data
* @return
*/
//指定key
public String getKeyFromData(Tuple5<Long, Long, Long, String, Long> data) {
return data.f0.toString();
}
//指定value
public String getValueFromData(Tuple5<Long, Long, Long, String, Long> data) {
return data.f1.toString()+data.f3;
}
}
}