kafka学习之旅

117 阅读4分钟

kafka 是什么?

一个天生持久化,高扩展(数据复制),高性能,分布式的流处理(聚合,统计)软件,主要采用发布订阅模式(多生产者,多消费者),并且可以回顾性的处理流事件

kafka 是干什么的?

主要用来处理大规模的流数据(实时,例如视频),收集指标和日志,活动跟踪(埋点看用户点击的习惯),传递消息,提交日志(数据库表)等

为什么使用kafka而不是用RabbitMQ?

当数据量很大的时候,并且做一些流处理时候使用kafka

kafka天生集群,RabbitMQ集群需要配置,并且配置了的集群功能没有kafka强

kafka持久化存储数据,RabbitMQ消费完消息消失

kafka实时处理流数据,RabbitMQ相对来说差很多

RabbitMQ与kafka的区别

RabbitMQ最主要的关键点着眼于数据在传输上的可靠性,相比吞吐量做了一定的舍弃

kafka着眼于数据的流处理,为了增加了吞吐量,提升了一定的速度,牺牲了一定的安全性

kafka在docker上的安装

1.安装zk

# 拉取zookeeper
docker pull zookeeper:3.4.14

# 运行zk在2182端口
docker run -d -p 2181:2181 --name zookeeper zookeeper:3.4.14

2.安装kafka

# 拉取 kafka
docker pull wurstmeister/kafka
​
# 运行容器
docker run -d --name kafka  --publish 9092:9092 --link zookeeper  --env KAFKA_ZOOKEEPER_CONNECT=你的服务器ip:2181 --env KAFKA_ADVERTISED_HOST_NAME=你的服务器ip --env KAFKA_ADVERTISED_PORT=9092 wurstmeister/kafka

数据可视化测试连接与创建topic

kafka Tool 2

1.添加连接

image-20240308145646479.png

2.输入相关信息

image-20240308145830575.png

从上至下依次是:

集群名字,kafka集群版本(可以无视),zk的地址,zk的端口,因为kafka是由于zk来控制的所以只需要填入zk让zk来管理Kafka即可。输入后直接右下角点击Add。

3.添加kafka的信息

image-20240308150549990.png 只需在最上方的空格输入kafka的地址与端口号,多个按逗号分隔(如果不能输入,请点击右下角的取消连接)。

4.创建topic

image-20240308151028052.png

Name:topic名字

Partition Count: 分片数量

Replica Count:副本数量

输入后点击右下角Add。

创建完毕后一般情况下我们传入的都是string字符串所以需要设置key与message

在Topics中点击我们刚刚创建的主题可以在content Types中选择我们的String参数

image-20240308151332052.png

使用springboot操作kafka

1.加入pom文件

<dependencies>
        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka</artifactId>
        </dependency>
</dependencies>

2.yml配置

spring:
   kafka:
    bootstrap-servers: 你kafka的ip:端口号
    producer:
      acks: 1
      # 重试次数
      retries: 0
      # 批量发送的消息数量
      batch-size: 16384
      # 32MB的批处理缓冲区
      buffer-memory: 33554432

    consumer:
      #设置是否自动提交,默认为true
      enable-auto-commit: false
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      #当一个新的消费组或者消费信息丢失后,在哪里开始进行消费。earliest:消费最早的消息。latest(默认):消费最近可用的消息。none:没有找到消费组消费数据时报异常。
      auto-offset-reset: latest
      #批量消费时每次poll的数量
      #max-poll-records: 5
    listener:
      #      当每一条记录被消费者监听器处理之后提交
      #      RECORD,
      #      当每一批数据被消费者监听器处理之后提交
      #      BATCH,
      #      当每一批数据被消费者监听器处理之后,距离上次提交时间大于TIME时提交
      #      TIME,
      #      当每一批数据被消费者监听器处理之后,被处理record数量大于等于COUNT时提交
      #      COUNT,
      #      #TIME | COUNT 有一个条件满足时提交
      #      COUNT_TIME,
      #      #当每一批数据被消费者监听器处理之后,手动调用Acknowledgment.acknowledge()后提交:
      #      MANUAL,
      #      # 手动调用Acknowledgment.acknowledge()后立即提交
      #      MANUAL_IMMEDIATE;
      ack-mode: manual
      #批量消费
      type: batch

3.发送消息使用springboot封装的的KafkaTemplate(生产者)

kafkaTemplate.send(topicName,JSON.toJSONString(object))

4.直接使用@KafkaListener

id:表示唯一消费者,不能重复,当groupId没有设置的时候,默认为groupId

topics:目标组的名称

@Slf4j
@Component
@Api(value = "Kafka消费者端口", tags = {"kafka发送数据信息管理"})
public class MyKafkaConsumers {
​
    @KafkaListener(id = "webGroup", topics = "topic_input")
    public void listen(String input, Acknowledgment ack) {
        log.info("input value: {}" , input);
        if (StrUtil.isEmpty(input)){
            // 确认消息
            ack.acknowledge();
            throw new ExampleException(ExampleErrorCodeEnum.PARAM_ERROR);
        }
        List<类名> haianBizPoliceStationsOverviews = JSONObject.parseArray(input, 类名.class);
        // 消息确认
        ack.acknowledge();
        log.info("转换的数据,{}",haianBizPoliceStationsOverviews);
    }
}

注意:如果不确认ack.acknowledge(); 那么他会每次开启连接都会从kafka的相关topics里面取消息,除非消息到了指定的丢失时间才会消失。

暂未完成,后续更新