flink监听kafka的数据保证程序健壮执行且只执行一次,并将结果保存到mysql中

flink监听kafka的数据保证程序健壮执行且只执行一次,并将结果保存到mysql中

注意
程序执行的时候只有一个前提就是你的机器的Zookeeper个kafka的程序必须是开启的要不然会执行失败!
因为我们设定了程序健壮代码但是也仅仅是没有开启生产窗口可以将历史数据收集齐而已,kafka服务必须开启!
flink程序主要就是分为三步:
1.数据的来源:Source
监听kafka保证 Exactly-Once执行且执行一次

2.数据的转换:Transformation
wordcount逻辑

3.数据的保存:Sink
保存到mysql

具体的代码实现

1.接收kafka的数据:Source

//创建一个计算实时流的flink环境
		StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();        
//告诉程序我们要接收哪那台机器上的数据,topic的分区名称(方便查询抓取)以及从头开始读
        Properties properties = new Properties();
        properties.setProperty("bootstrap.servers", "doit01:9092,doit02:9092,doit03:9092");
        properties.setProperty("group.id", args[1]);
        properties.setProperty("auto.offset.reset", "earliest");
//设置kafka的框架,传入kafka的话题名称,框架已经性质!
        FlinkKafkaConsumer<String> flinkKafkaConsumer = new FlinkKafkaConsumer<String>(args[2], new SimpleStringSchema(), properties);
//在Checkpoint的时候将Kafka的偏移量保存到Kafka特殊的Topic中,默认是true
        flinkKafkaConsumer.setCommitOffsetsOnCheckpoints(false);
//将kafka的数据添加到我们程序梳理来源之一
        DataStreamSource<String> lines = env.addSource(flinkKafkaConsumer);

保证数据的健壮Exactly-once前提是必须设置Checkpoint检查站

//开启Checkpoint(检查站)30秒钟检查一次
        env.enableCheckpointing(30000);
//设置检查站的模式:(最少的执行次数)
        env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.AT_LEAST_ONCE);
//设置如果job cancel后,依然保存对应的checkpoint数据
        env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
//检查站每次将检查结果的偏移量保存的一个路径(防止数据丢失)
        env.setStateBackend(new FsStateBackend(args[0]));
//设置一个从起策略(一旦遇到问题,最多伪重启10次,重启延迟为30秒)
        env.setRestartStrategy(RestartStrategies.fixedDelayRestart(10, 30000));

2.数据的转换:Transformation

//调用flatMap算子(重写flatmapfunction方法)
SingleOutputStreamOperator<Tuple2<String, Integer>> wordAndOne = lines.flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() {
            @Override
            public void flatMap(String line, Collector<Tuple2<String, Integer>> out) throws Exception {
                String[] words = line.split(" ");
                for (String word : words) {
                //将单词跟1组合
                    out.collect(Tuple2.of(word, 1));
                }
            }
        });
//按照第一个分组
        KeyedStream<Tuple2<String, Integer>, Tuple> keyed = wordAndOne.keyBy(0);
//按照第二个聚合
        SingleOutputStreamOperator<Tuple2<String, Integer>> summed = keyed.sum(1);

3.数据的保存:Sink

//创建一个保存到mysql的环境
        summed.addSink(new MysqlSink());
//执行这个job自己起名字
        env.execute("KafkaSourceToMySQLDemo");

需要创建一个mysql自己写一个MysqlSink的类用来设置路径以及存储格式

public class MysqlSink extends RichSinkFunction<Tuple2<String,Integer>> {
//ctrl+i重写方法  ctrl+o实现方法
    private Connection connection = null;
    @Override
    public void open(Configuration parameters) throws Exception {
        //可以创建数据库连接
        connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/bigdata?characterEncoding=UTF-8", "root", "123456");
    }
    @Override
    public void invoke(Tuple2<String, Integer> value, Context context) throws Exception {
        PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO t_wordcount VALUES (?, ?) ON DUPLICATE KEY UPDATE counts = ?");
        preparedStatement.setString(1, value.f0);
        preparedStatement.setLong(2, value.f1);
        preparedStatement.setLong(3, value.f1);
        preparedStatement.executeUpdate();
        preparedStatement.close();
    }
    @Override
    public void close() throws Exception {
        connection.close();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值