kafka stream简单使用教程

该代码示例展示了Apache Kafka的生产者、消费者以及KStream的使用。生产者向主题`my-producer`发送消息,消费者从`stream`主题消费并打印消息。KStream部分则演示了数据流的各种操作,如过滤、映射、扁平化、聚合等,并将结果写入`stream`主题。

produce代码

public class Producer {

    public static void main(String[] args) {
        Properties prop = new Properties();
        prop.put("bootstrap.servers","192.168.232.144:9092");
        prop.put("acks", "all");
        prop.put("retries", 0);
        prop.put("batch.size", 16384);
        prop.put("linger.ms", 1);
        prop.put("buffer.memory", 33554432);
        prop.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        prop.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

        KafkaProducer<String, String> producer = new KafkaProducer<>(prop);

        while (true){
//            String v = new Random().nextInt(1000)+"";
            String v = "this is word count test,this is kafka test";

            producer.send(new ProducerRecord<>("my-producer",v));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

Kstream代码

public class KafStream {

    public static void main(String[] args) {
        Properties props = new Properties();
        props.put(StreamsConfig.APPLICATION_ID_CONFIG, "streams-temperature");
        props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.232.144:9092");
        props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
        props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());

        props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "latest");
        props.put(StreamsConfig.CACHE_MAX_BYTES_BUFFERING_CONFIG, 0);

        StreamsBuilder builder = new StreamsBuilder();
        try {
            Serde<String> string = Serdes.String();
            KStream<String, String> source = builder.stream("my-producer",Consumed.with(string, string));
            //foreach 为消费型函数  不会产生新的stream 所以 kafka订阅端不会获取数据
//            source.foreach((k,v)->{
//
//                System.out.println(k);
//                System.out.println(v + " ****************** ");
//
//            });

//            KStream<String, String> filter = source.filter((k, v) -> {
//                if(Integer.parseInt(v) >890){
//                    return true;
//                }
//                return false;
//            });

//            KStream<String, String> rdd = source.map((k, v) -> {
//                System.out.println(v);
//                KeyValue<String, String> kv = new KeyValue<>(k, "1 :" + v);
//                return kv;
//            });

            //分支 参数为 Predicate (k,v) -> boolean 类型的lambda表达式
//            KStream<String, String>[] branch = source.branch((k,v)->{
//                return Integer.parseInt(v)<100;
//            });
//
//            KStream<String, String> rdd = branch[0];

            //过滤功能  (k,v)->boolean 类型参数
//            KStream<String, String> rdd = source.filter((k, v) -> {
//                return v.startsWith("1");
//            });


            //filterNot
            //翻转过滤:将一个Stream经过Boolean函数处理保留不符合条件的结果

//            KStream<String, String> rdd = source.flatMap((k,v)->{
//                List<KeyValue<String,String>> kvs = new ArrayList<>();
//                String[] split = v.split("1");
//                for (String sv : split) {
//                    kvs.add(new KeyValue<String, String>(k,sv));
//                }
//                return kvs;
//            });

            //感觉是flatMap的一种优化写法
//            KStream<String, String> rdd = source.flatMapValues((k,v)-> Arrays.asList(v.split("1")));


            //map 既可以对key进行修改 又可以对value进行修改
//            KStream<String, String> rdd = source.map((k, v) -> new KeyValue<String, String>(k, v+"-->"));

            //mapValues 只对value进行修改
//            KStream<String, String> rdd = source.mapValues((k, v) -> v + 1);
//
//            rdd.to("stream", Produced.with(string, string));

//            KTable<String, Long> count = source.flatMapValues(v -> {
//                return Arrays.asList(v.toLowerCase().split("\\W"));
//            }).selectKey((key, word) -> word).groupByKey().count();
//
//            count.toStream().to("stream", Produced.with(Serdes.String(), Serdes.Long()));


            KTable<String, Long> count = source.flatMapValues(v -> {
                return Arrays.asList(v.toLowerCase().split("\\W"));
            }).selectKey((key, word) -> word).groupByKey().count();

            count.toStream().to("stream", Produced.with(Serdes.String(), Serdes.Long()));


            KafkaStreams kafkaStreams = new KafkaStreams(builder.build(), props);

            kafkaStreams.start();
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

consumer代码

public class Consumer {

    public static void main(String[] args) {

        Properties props = new Properties();
        props.put("bootstrap.servers", "192.168.232.144:9092");
        props.put("group.id", "test");//消费者的组id
        props.put("enable.auto.commit", "true");
        props.put("auto.commit.interval.ms", "1000");
        props.put("session.timeout.ms", "30000");
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.LongDeserializer");

        KafkaConsumer<String, Long> consumer = new KafkaConsumer<String, Long>(props);
        //订阅主题列表topic
        consumer.subscribe(Arrays.asList("stream"));

        while (true) {
            ConsumerRecords<String, Long> records = consumer.poll(100);
            for (ConsumerRecord<String, Long> record : records){
                System.out.println();
                System.out.println();
                System.out.println();
                System.out.println();
                System.out.println(record.key() + " : " + record.value());
                System.out.println();
                System.out.println();
                System.out.println();
                System.out.println();
                System.out.println();
            }


        }
    }
}

### Kafka Streams 使用教程及常见问题解决 Kafka Streams 是 Apache Kafka 提供的一个流处理库,允许开发者在应用程序中直接构建和操作流数据[^2]。以下是一些关于 Kafka Streams 的使用教程以及常见问题的解决方案。 #### 1. Kafka Streams 基本用法 Kafka Streams 的核心概念包括拓扑(Topology)、KStream 和 KTable。通过这些组件,可以轻松实现数据流的转换、聚合和连接等操作。 ```python from kafka import KafkaConsumer, KafkaProducer from kafka.streams import StreamsBuilder, Topology # 创建一个 StreamsBuilder 对象 builder = StreamsBuilder() # 定义输入流 input_stream = builder.stream("input-topic") # 对流进行简单的转换操作 output_stream = input_stream.map(lambda key, value: (key.upper(), value.upper())) # 将结果写入到输出主题 output_stream.to("output-topic") # 构建拓扑 topology = builder.build() ``` 此代码片段展示了如何使用 Kafka Streams API 构建一个简单的流处理应用[^4]。 #### 2. 常见问题及解决方法 - **问题:应用程序崩溃后无法恢复状态** 解决方案:Kafka Streams 利用了 Kafka 的高可用性和复制功能[^2]。当应用程序实例失败时,任务会被自动重新分配到其他正在运行的实例上。确保正确配置了 `application.id` 参数,并且 Kafka 集群具有足够的分区副本数以支持容错。 - **问题:状态存储的性能优化** 解决方案:可以通过调整 RocksDB 的配置来优化状态存储的性能。例如,增加缓存大小或调整压缩策略。此外,合理设置 `cache.max.bytes.buffering` 参数可以减少磁盘 I/O 操作[^1]。 - **问题:如何处理延迟消息** 解决方案:可以使用 Kafka Streams 提供的窗口机制来处理延迟消息。通过设置适当的窗口大小和保留时间,可以确保所有相关消息都被正确处理[^1]。 #### 3. 示例项目推荐 Winton Kafka Streams 是一个开源项目,提供了 Kafka Streams API 的 Python 实现[^3]。对于熟悉 Python 的开发者来说,这是一个很好的选择。该项目基于 Confluent 的 librdkafka 和 Python Kafka 库,能够与现有的 Kafka 集成无缝协作。 ```python from winton_kafka_streams.processor import BaseProcessor, StreamThread class MyProcessor(BaseProcessor): def process(self, key, value): print(f"Processing key: {key}, value: {value}") stream_thread = StreamThread( application_id="my-app", bootstrap_servers="localhost:9092", processor=MyProcessor(), input_topics=["input-topic"], ) stream_thread.start() ``` 上述代码展示了如何使用 Winton Kafka Streams 构建一个简单的处理器。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值