flink 四 kafka sink mysql

1 maven依赖

        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-connector-kafka_2.11</artifactId>
            <version>1.10.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-java</artifactId>
            <version>1.10.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-streaming-java_2.11</artifactId>
            <version>1.10.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-clients_2.11</artifactId>
            <version>1.10.0</version>
        </dependency>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.8.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.73</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-dbcp2</artifactId>
            <version>2.1.1</version>
        </dependency>

2 消息生产者

import com.alibaba.fastjson.JSON;
import com.test.domain.MessageEntity;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.stereotype.Component;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;

import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;


@Slf4j
@Component
public class MessageProducter {

    private static Properties getProps(){
        Properties props =  new Properties();
        props.put("bootstrap.servers", "192.168.9.10:9092");
        props.put("acks", "all"); // 发送所有ISR
        props.put("retries", Integer.MAX_VALUE); // 重试次数
        props.put("batch.size", 16384); // 批量发送大小
        props.put("buffer.memory", 102400); // 缓存大小,根据本机内存大小配置
        props.put("linger.ms", 1000); // 发送频率,满足任务一个条件发送
        props.put("client.id", "producer-syn-1"); // 发送端id,便于统计
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        return props;
    }


    public static void main(String[] args) throws Exception {
        KafkaProducer<String, String> producer = new KafkaProducer<>(getProps());
        for (int i=30;i<=100;i++){
            MessageEntity message = new MessageEntity();
            message.setMessage("第"+i+"条:message");
            message.setTotalDate(DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
            message.setMessageId(System.currentTimeMillis());
            log.info(JSON.toJSONString(message));
            ProducerRecord<String, String> record = new ProducerRecord<>("flink_test_01",
                    System.currentTimeMillis()+"", JSON.toJSONString(message));
            Future<RecordMetadata> metadataFuture = producer.send(record);
            RecordMetadata recordMetadata;
            try {
                recordMetadata = metadataFuture.get();
                log.info("发送成功!");
                log.info("topic:"+recordMetadata.topic());
                log.info("partition:"+recordMetadata.partition());
                log.info("offset:"+recordMetadata.offset());
            } catch (InterruptedException|ExecutionException e) {
                System.out.println("发送失败!");
                e.printStackTrace();
            }
            Thread.sleep(10000);
        }
    }
}
./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic flink_test_01  --from-beginning

在这里插入图片描述

3 从kafka中读取数据,转成Message实体来写入

public class KafkaToMysql {
    public static void main(String[] args) throws Exception{
        // 构建环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        //指定checkpoint的触发间隔
        env.enableCheckpointing(5000);
        env.setParallelism(1);
        env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
        Properties properties = new Properties();
        properties.setProperty("bootstrap.servers", "192.168.0.96:9092");
        properties.setProperty("group.id", "flink_consumer_01");
        properties.setProperty("auto.offset.reset", "earliest");

        SingleOutputStreamOperator<MessageEntity> streamOperator = env.addSource(
                new FlinkKafkaConsumer<>("flink_test_01",
                        new MessageDeSerializationSchema(), properties)).setParallelism(1)
                .map(record -> {
                    MessageEntity message = null;
                    try {
                        System.out.println("consumerRecord"+record.value());
                        message = JSON.parseObject(record.value(), MessageEntity.class);
                        System.out.println(message.toString());
                    }catch (Exception e){
                        System.out.println("格式问题:"+ record);
                    }
                    return message;
                });

        SingleOutputStreamOperator<List<MessageEntity>> process = streamOperator.timeWindowAll(Time.seconds(10))
                .process(new AllWindownFunction1());
        process.addSink(new SinkToMysql()).setParallelism(1).name("flink_test_01");
        env.execute("consumer start");
    }

    public static class AllWindownFunction1 extends ProcessAllWindowFunction<MessageEntity, List<MessageEntity>, TimeWindow> {
        @Override
        public void process(ProcessAllWindowFunction<MessageEntity, List<MessageEntity>,
                TimeWindow>.Context context, Iterable<MessageEntity> iterable,
                            Collector<List<MessageEntity>> collector) throws Exception {
            if (iterable != null){
                System.out.println("非空集合"+iterable);
                ArrayList<MessageEntity> list = Lists.newArrayList(iterable);
                if (list.size() > 0) {
                    System.out.println("10s数据条数:" + list.size());
                    collector.collect(list);
                }
            }else {
                System.out.println("空集合");
            }
        }
    }
}

@Data
public class MessageEntity {
    private Long messageId;
    private String message;
    private String totalDate;
}

4 mysqlSink类

import com.test.domain.MessageEntity;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.List;

public class SinkToMysql extends RichSinkFunction<List<MessageEntity>> {

    PreparedStatement ps;
    BasicDataSource dataSource;
    private Connection connection;

    @Override
    public void open(Configuration parameters) throws Exception {
        System.out.println("1111111111111");
        dataSource = new BasicDataSource();
        connection = getConnection(dataSource);
        String sql = "insert into flink_test_01(message_id, message, total_date) values(?, ?, ?);";
        ps = this.connection.prepareStatement(sql);
    }

    @Override
    public void close() throws Exception {
        super.close();
        //关闭连接和释放资源
        if (connection != null) {
            connection.close();
        }
        if (ps != null) {
            ps.close();
        }
    }

    @Override
    public void invoke(List<MessageEntity> value, Context context) throws Exception {
        //遍历数据集合
        for (MessageEntity message : value) {
            ps.setLong(1, message.getMessageId());
            ps.setString(2, message.getMessage());
            System.out.println("message--------------------------:"+message.getMessage());
            ps.setString(3, message.getTotalDate());
            ps.addBatch();
        }
        int[] count = ps.executeBatch();//批量后执行
        System.out.println("成功了插入了" + count.length + "行数据");
    }

    private static Connection getConnection(BasicDataSource dataSource) {
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://192.168.0.216:3306/hela?useUnicode=true&characterEncoding=utf8");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        dataSource.setInitialSize(10);
        dataSource.setMaxTotal(50);
        dataSource.setMinIdle(2);
        Connection con = null;
        
        try {
            con = dataSource.getConnection();
        } catch (Exception e) {
            System.out.println("msg:" + e.getMessage());
        }
        return con;
    }

}

运行效果:
在这里插入图片描述

Flink是一个分布式流处理框架,能够处理和分析实时数据流。Kafka是一个分布式流式数据处理平台,能够实时地收集、存储和处理大规模数据流。 在Flink中读取Kafka数据并将其写入MySQL数据库需要以下步骤: 1. 配置Kafka Consumer:通过配置Kafka Consumer相关的属性,如bootstrap.servers(Kafka的地址)、group.id(消费者组标识)、topic(要读取的主题名称)等。 2. 创建Flink Execution Environment:通过创建Flink执行环境,可以定义Flink作业的运行模式和相关配置。 3. 创建Kafka Data Source:使用FlinkKafka Consumer API创建一个Kafka数据源,通过指定Kafka Consumer的配置和要读取的主题,可以从Kafka中获取数据。 4. 定义数据转换逻辑:根据需要,可以使用Flink提供的转换算子对Kafka数据进行处理,如map、filter、reduce等。 5. 创建MySQL Sink:通过配置MySQL数据库的连接信息,如URL、用户名、密码等,创建一个MySQL数据池。 6. 将数据写入MySQL:通过使用FlinkMySQL Sink API,将经过转换后的数据写入MySQL数据库。可以指定要写入的表名、字段映射关系等。 7. 设置并执行作业:将Kafka数据源和MySQL Sink绑定在一起,并设置作业的并行度,然后执行Flink作业。 通过以上步骤,我们可以将Kafka中的数据读取出来,并经过转换后写入MySQL数据库,实现了从KafkaMySQL的数据传输。 需要注意的是,在配置Kafka Consumer和MySQL数据库时,要确保其正确性和可用性,以确保数据的正确读取和写入。同时,在处理大规模数据流时,还需要考虑分布式部署、容错性和高可用性等方面的问题,以保证系统的稳定性和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

高并发

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

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

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

打赏作者

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

抵扣说明:

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

余额充值