Flink接入Redis

Flink接入Redis

创建Redis连接池 RedisUtils

package com.pls.common;

import java.util.LinkedList;
import java.util.List;


import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedisPool;

public class RedisUtils {
    private static ShardedJedisPool pool;
    public ShardedJedisPool GetRedisSource() {
        try {
            //创建一个配置对象
            JedisPoolConfig config = new JedisPoolConfig();
            //最大活动对象数
            config.setMaxTotal(1000);
            //最大能够保持idel状态的对象数
            config.setMaxIdle(50);
            config.setMaxWaitMillis(3000);
            config.setTestOnBorrow(true);
            config.setTestOnReturn(true);
            // 集群
            JedisShardInfo jedisShardInfo1 = new JedisShardInfo("127.0.0.1", 6379);
            jedisShardInfo1.setPassword("123456");
            List<JedisShardInfo> list = new LinkedList<JedisShardInfo>();
            list.add(jedisShardInfo1);
            pool = new ShardedJedisPool(config, list);
        } catch (Exception e) {
            String content = e.getClass().getName() + "  Redis连接池出错:  " + JsonUtils.objectToJson(e);
            SysLog.error(content);
        }
        return pool;
    }
}



写入数据到Redis,可根据自己的需求使用Redis存储类型,我这里写的是list集合 RedisSinkAdplay

package com.pls.sink;

import com.pls.common.JsonUtils;
import com.pls.common.RedisUtils;
import com.pls.models.AdvertisementPlayModel;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

import java.util.UUID;

public class RedisSinkAdplay extends RichSinkFunction<AdvertisementPlayModel> {
    ShardedJedis jedis;
    @Override
    public void open(Configuration parameters) throws Exception {
        super.open(parameters);
    }

    @Override
    public void invoke(AdvertisementPlayModel value, Context context) {
        if(jedis==null){
            ShardedJedisPool pool = new RedisUtils().GetRedisSource();
            jedis = pool.getResource();
        }
        String uuid = String.valueOf(UUID.randomUUID());
        value.uuid=uuid;
        jedis.lpush("list_adplaysinkredis", JsonUtils.objectToJson(value));
    }

    @Override
    public void close() throws Exception {
        super.close();
        jedis.close();
    }
}

读取Redis缓存数据,写入到数据库 EventSinkCK

package com.pls.sink;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.pls.common.DateUtils;
import com.pls.common.DbConfig;
import com.pls.common.JsonUtils;
import com.pls.common.RedisUtils;
import com.pls.common.SysLog;
import com.pls.models.EventMonitoringModel;
import com.pls.models.UserDurationModel;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

import java.sql.*;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

public class EventSinkCK extends Thread {
    private DruidDataSource dataSource;
    ShardedJedis jedis=null;
    public void run() {
        if(dataSource==null){
            dataSource = new DbConfig().OpenDb();
        }
        adddata();
    }
    private void adddata() {
        while (true) {
            try {
                if(jedis==null){
                    ShardedJedisPool pool = new RedisUtils().GetRedisSource();
                    jedis = pool.getResource();
                }
                var list = jedis.lrange("list_eventsinkredis", 0, 499);
                if(list!=null){
                    int num = list.size();
                    if(num==0){
                        Thread.sleep(10000);
                        continue;
                    }
//                    SysLog.redisLogData("读出数据"+num+"条");
                    Integer rescode= insert(list);
//                    SysLog.redisLogData("成功处理"+rescode+"条");
                    //将list做修剪,去掉已经读出的数据
                    if(rescode>0){
                        jedis.ltrim("list_eventsinkredis", num, -1);
                    }
                    Thread.sleep(1000);
                }
            } catch (Exception x) {
//                System.out.println("读取报错");
                String content = x.getClass().getName() +DateUtils.GetNowDate("yyyy-MM-dd HH:mm:ss")+ "  读取Redis数据报错:  " + x;
                SysLog.error(content);
                continue;
            }
        }
    }
    private Integer insert(List<String> values) throws Exception {
        DruidPooledConnection conn=null;
        PreparedStatement stat = null;
        Integer num=0;
        try {
            if (values == null || values.size()==0) {
                return -1;
            }
            if (dataSource == null) {
                dataSource = new DbConfig().OpenDb();
            }
            conn = dataSource.getConnection();
            Map<String, String> dic = new Hashtable<String, String>();
            if (values != null && values.size() > 0) {
                for (String v : values) {
                    EventMonitoringModel item=JSONObject.parseObject(v,EventMonitoringModel.class);
                    if (item.versionnumber == null || item.versionnumber == "null") {
                        item.versionnumber = "";
                    }
                    if (!dic.containsKey(item.dbname)) {
                        String insertSql = "insert into " + item.dbname + ".t_ysbl_eventfunnel(platform, channel, dateday, eventname, eventid, userid, triggercount,lasttimestamp,eventparameter,versionnumber) values";
                        dic.put(item.dbname, insertSql);
                    }
                    String sql = dic.get(item.dbname);
                    String log_date = DateUtils.getDatetime(String.valueOf(item.dateday), "yyyy-MM-dd");
                    String sql_tc = String.format("(%d,%d,'%s','%s',%d,%d,%d,%d,'%s','%s')", item.platform, item.channel, log_date, item.eventname, item.eventid, item.userid,item.triggercount, item.lasttimestamp,item.eventparameter,item.versionnumber);
                    sql = sql + sql_tc;
                    dic.replace(item.dbname, sql);
                    num++;
                }
                if (dic.size() > 0) {
                    for (Map.Entry<String, String> item : dic.entrySet()) {
                        stat = conn.prepareStatement(item.getValue());
                        stat.execute();
                    }
                }
//                System.out.println("成功处理数据" + num + "条");
            }
        } catch (Exception e) {
//            System.out.println("插入报错");
            String content = e.getClass().getName() +DateUtils.GetNowDate("yyyy-MM-dd HH:mm:ss")+ "  Sink报错:  " + e;
            SysLog.error(content);
            num=-1;
        }finally {
            JdbcUtils.close(stat);
            JdbcUtils.close(conn);
        }
        return num;
    }
}

在启动函数里面调用Redis遍历

           EventSinkCK event = new EventSinkCK();
            event.start();

在处理函数里面调用写入Redis算子

windowData.addSink(new RedisSinkEvent()).setParallelism(1);

至此,flink接入Redis缓冲区完成,主要是减轻数据库写入压力,防止并发,我这里数据库是用的clickhouse
本人初涉java,写的不好,请多多建议

FlinkRedis是两种常用的技术,分别用于流处理和内存数据存储。将FlinkRedis结合使用可以实现高效的数据处理和实时分析。 ### Flink Apache Flink是一个开源的流处理框架,具有高性能和低延迟的特点。它支持事件时间处理、状态管理和容错机制,适用于复杂的流处理场景。Flink的主要特点包括: 1. **流处理和批处理统一**:Flink可以在同一个平台上处理流数据和批数据。 2. **状态管理**:Flink提供了强大的状态管理功能,支持有状态计算。 3. **容错机制**:Flink支持精确一次(exactly-once)语义,确保数据处理的一致性。 ### Redis Redis是一个开源的内存数据结构存储系统,常用于数据库、缓存和消息代理。它支持多种数据结构,如字符串、哈希、列表、集合、有序集合等。Redis的主要特点包括: 1. **高性能**:Redis将数据存储在内存中,读写速度非常快。 2. **丰富的数据结构**:支持多种数据结构,方便不同的应用场景。 3. **持久化**:Redis支持数据持久化,可以将内存中的数据保存到磁盘。 ### Flink + RedisFlinkRedis结合使用,可以实现实时数据处理和存储的完整解决方案。以下是一些常见的应用场景: 1. **实时数据处理**:Flink可以实时处理流数据,并将处理结果存储到Redis中,供后续查询和分析使用。 2. **状态存储**:Flink的状态可以存储在Redis中,实现分布式状态管理。 3. **缓存**:Flink处理的数据可以缓存在Redis中,提高数据访问速度。 ### 示例 假设我们有一个实时数据流,需要对数据进行实时统计,并将统计结果存储到Redis中。可以使用Flink进行数据处理,并将结果写入Redis。具体步骤如下: 1. **数据流接入**:Flink从数据源(如Kafka)接入实时数据流。 2. **数据处理**:Flink对数据进行处理,如聚合、过滤等操作。 3. **结果存储**:将处理结果写入Redis,供后续查询和分析使用。 ```java import org.apache.flink.api.common.functions.MapFunction; import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.connectors.redis.RedisSink; import org.apache.flink.streaming.connectors.redis.common.config.FlinkJedisPoolConfig; import org.apache.flink.streaming.connectors.redis.common.mapper.RedisCommand; import org.apache.flink.streaming.connectors.redis.common.mapper.RedisCommandDescription; import org.apache.flink.streaming.connectors.redis.common.mapper.RedisMapper; public class FlinkRedisExample { public static void main(String[] args) throws Exception { // 创建Flink执行环境 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 创建数据流 DataStream<String> dataStream = env.socketTextStream("localhost", 9999); // 处理数据 DataStream<String> processedStream = dataStream.map(new MapFunction<String, String>() { @Override public String map(String value) throws Exception { // 数据处理逻辑 return value.toUpperCase(); } }); // 配置Redis连接 FlinkJedisPoolConfig conf = new FlinkJedisPoolConfig.Builder().setHost("localhost").setPort(6379).build(); // 创建RedisSink RedisSink<String> redisSink = new RedisSink<>(conf, new RedisMapper<String>() { @Override public RedisCommandDescription getCommandDescription() { return new RedisCommandDescription(RedisCommand.SET, "processed_data"); } @Override public String getKeyFromData(String data) { return "key"; } @Override public String getValueFromData(String data) { return data; } }); // 将数据写入Redis processedStream.addSink(redisSink); // 执行任务 env.execute("Flink Redis Example"); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雷霆无情哈啦少

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值