Flink框架关于Kafka生产消费的实现demo

flink作为一个大数据框架,已经由阿里充分的证实了其性能和前景。但对国内仍然是一个比较陌生的状态,无论是开源的文档和实例都比较缺乏。之前找到的demo很多都是旧版本;同时flink本身面临版本演进,blink开源等一些影响,也会在之后出现一些比较大的变化。

我根据目前的资料,编写了基于flink的Kafka生产消费demo,便于初步的了解flink的特性,也希望能对他人了解flink提供一些小小的帮助。

以下demo是我根据一些其他的demo整合而成,引用申明见最下方。

 


导包

flink的导包是常见的核心+拓展模式

flink-java是flink的核心实现.我使用的是(看起来比较成熟的1.5.0,可能1.6.0更合适)

flink-streaming-java_2.11是使用flink流接入的包

flink-connector-kafka-0.10_2.11是为了使用Kafka开发的中间件,而使用这个包必须保证版号对应,及使用kafka0.10和flink流2.11

    <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-java</artifactId>
            <version>1.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-streaming-java_2.11</artifactId>
            <version>1.5.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.flink/flink-connector-kafka-0.10 -->
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-connector-kafka-0.10_2.11</artifactId>
            <version>1.5.0</version>
        </dependency>

写入(生产者)

源为一个循环的数据产生器,输出为对应的kafka topic

public class WriteIntoKafka {
    public static void main(String[] args) throws Exception {
        // create execution environment
 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        Map properties= new HashMap();
        properties.put("bootstrap.servers", "/*服务地址*/");
        properties.put("topic", "/*topic*/");
        
        // parse user parameters
        ParameterTool parameterTool = ParameterTool.fromMap(properties);

        // add a simple source which is writing some strings
        DataStream<String> messageStream = env.addSource(new SimpleStringGenerator());

        // write stream to Kafka
        messageStream.addSink(new FlinkKafkaProducer010<>(parameterTool.getRequired("bootstrap.servers"),
                parameterTool.getRequired("topic"),
                new SimpleStringSchema()));

        messageStream.rebalance().map(new MapFunction<String, String>() {
            //序列化设置
            private static final long serialVersionUID = 1L;

            @Override
            public String map(String value) throws Exception {
                return value;
            }
        });

        messageStream.print();

        env.execute();
    }

    public static class SimpleStringGenerator implements SourceFunction<String> {
    	//序列化设置
        private static final long serialVersionUID = 1L;
        boolean running = true;

        @Override
        public void run(SourceContext<String> ctx) throws Exception {
            while(running) {
                ctx.collect(prouderJson());
            }
        }

        @Override
        public void cancel() {
            running = false;
        }
    }
 }

读取(消费者)

采用Kafka消费者作为源,通过MapFunction转换后输出

public class ReadFromKafka {

    public static void main(String[] args) throws Exception {
// create execution environment
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        Map properties= new HashMap();
        properties.put("bootstrap.servers", "/*服务地址*/");
        properties.put("group.id", "test");
        properties.put("enable.auto.commit", "true");
        properties.put("auto.commit.interval.ms", "1000");
        properties.put("auto.offset.reset", "earliest");
        properties.put("session.timeout.ms", "30000");
        properties.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        properties.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        properties.put("topic", "/*topic*/");
        // parse user parameters
      
        ParameterTool parameterTool = ParameterTool.fromMap(properties);

        FlinkKafkaConsumer010 consumer010 = new FlinkKafkaConsumer010(
                         parameterTool.getRequired("topic"), new SimpleStringSchema(), parameterTool.getProperties());
	

        DataStream<String> messageStream = env
                .addSource(consumer010);

        // print() will write the contents of the stream to the TaskManager's standard out stream
        // the rebelance call is causing a repartitioning of the data so that all machines
        // see the messages (for example in cases when "num kafka partitions" < "num flink operators"
        messageStream.rebalance().map(new MapFunction<String, String>() {
            private static final long serialVersionUID = 1L;

            @Override
            public String map(String value) throws Exception {
                return value;
            }
        });


 messageStream.print();

 env.execute();
}
}

细节

1,配置我采用了 Map properties= new HashMap(); 这种在程序内部写入的方式。

也可以采用读取文件的配置的方式。

3,另一种配置方式,可以对FlinkKafkaConsumer010进行配置,具体使用待补充

采用Kafka为data Source使用

2,新旧版本的最大区别就是 使用FlinkKafkaProducer010和FlinkKafkaProducer010作为生产者和消费者的实例,具体方法的使用和之前的版本有些差别

4,生产者源的产生方式是值得研究的,也应该有其他的产生方式。很多实现细节没有弄清楚(待补充)

5.消费者转换的MapFunction感觉仍有不清楚的地方,这一步可以实现什么逻辑,适合写什么样的逻辑呢(待补充)

6,输出细节,可以在 实现中输出,也可以使用messageStream.print(),进行输出,具体格式可以自行验证。


问题

以上两个demo是调用flink—Kafka的api实现的,但是仍有一些的问题,没有弄清:

1,关于生产者,如何自定义发送数据格式,如byte[],如何自定义发送的分区

2,关于消费者kafka低级api的使用,seek2end,拉取指定分区,手动提交偏移量等设置的实现


引用

https://www.jianshu.com/p/f9d447a3c48f

https://blog.csdn.net/lmalds/article/details/51780950

https://ci.apache.org/projects/flink/flink-docs-stable/dev/connectors/kafka.html

github中的某段代码(找了很久,忘了出处了)


补充

10.28

最近把一些用过的demo放在了GitHub上,可以看下:https://github.com/jyj019/flinkDemo

好的,以下是一个 Flink Table 读取 Kafka 多个表的示例代码,使用的是 Flink 1.17.0 版本,并且可以通过 Maven 构建: ```java import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.table.api.EnvironmentSettings; import org.apache.flink.table.api.Table; import org.apache.flink.table.api.bridge.java.StreamTableEnvironment; import org.apache.flink.table.descriptors.Kafka; import org.apache.flink.table.descriptors.Schema; import org.apache.flink.table.descriptors.FormatDescriptor; import org.apache.flink.table.descriptors.Json; import org.apache.flink.table.descriptors.ConnectorDescriptor; public class FlinkKafkaTableDemo { public static void main(String[] args) throws Exception { // 创建 Flink Streaming 执行环境 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.setParallelism(1); // 创建 Flink Table 执行环境 EnvironmentSettings settings = EnvironmentSettings.newInstance().useBlinkPlanner().inStreamingMode().build(); StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env, settings); // 定义 Kafka 连接器 ConnectorDescriptor kafkaConnector = new Kafka() .version("universal") .topic("topic-name") .startFromLatest() .property("bootstrap.servers", "localhost:9092") .property("group.id", "group-name"); // 定义 Schema Schema schema = new Schema() .field("field1", "VARCHAR") .field("field2", "BIGINT") .field("field3", "VARCHAR"); // 定义格式化器 FormatDescriptor format = new Json().failOnMissingField(true); // 注册 Kafka 连接器和 Schema tableEnv .connect(kafkaConnector) .withFormat(format) .withSchema(schema) .createTemporaryTable("table1"); // 注册另一个 Kafka 连接器和 Schema tableEnv .connect(kafkaConnector) .withFormat(format) .withSchema(schema) .createTemporaryTable("table2"); // 按照指定条件连接多个表 Table result = tableEnv.sqlQuery("SELECT t1.field1, t1.field2, t2.field3 FROM table1 t1 JOIN table2 t2 ON t1.field1 = t2.field1"); // 输出结果 result.printSchema(); result.execute().print(); // 执行任务 env.execute("Flink Kafka Table Demo"); } } ``` 你可以将这个代码保存为 `FlinkKafkaTableDemo.java` 文件,并在同一目录下创建一个 `pom.xml` 文件,内容如下: ```xml <project> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>flink-kafka-table-demo</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-streaming-java_2.12</artifactId> <version>1.17.0</version> </dependency> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-table-api-java-bridge_2.12</artifactId> <version>1.17.0</version> </dependency> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-connector-kafka_2.12</artifactId> <version>1.17.0</version> </dependency> </dependencies> </project> ``` 然后,在命令行中进入到该目录,并执行以下命令进行编译和打包: ``` mvn package ``` 编译完成后,在 `target` 目录下会生成一个名为 `flink-kafka-table-demo-1.0-SNAPSHOT.jar` 的可执行 JAR 文件。你可以使用以下命令在 Flink 中运行它: ``` ./bin/flink run flink-kafka-table-demo-1.0-SNAPSHOT.jar ``` 注意,以上命令中的 `./bin/flink` 可能需要根据你的实际情况调整。另外,示例中的 Kafka 版本为 `universal`,因此可以适用于不同版本的 Kafka。如果你的 Kafka 版本与本示例不同,请根据实际情况调整。
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值