flink实战---数据写入redis(redisSink)

版权声明:原创文章 欢迎参考 请勿抄袭 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环境进行通信:

  1. 单Redis服务器
  2. Redis集群
  3. 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 RPUSHLPUSH
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;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/aA518189/article/details/86474512