kafka

一、kafka简介

Kafka由Scala和Java编写,是一种高吞吐量的分布式发布订阅消息系统‌

特点:
1、Kafka能够统一线上和离线的消息处理,通过集群提供实时的消息服务‌
2、支持高吞吐量的数据传输
3、Kafka采用了发布/订阅的消息模式,允许消息的异步发送和接收‌
4、允许集群中节点失败,通过多副本机制提供高可用的持久化消息存储‌
5、Kafka集群支持热扩展,可以方便地增加或减少节点‌
6、Kafka中的消息是以文件的方式持久化到磁盘中进行存储的

基础架构:
包括Producer(生产者)、Broker(代理)和Consumer(消费者)
1、Kafka运行在集群上,集群包含一个或多个服务器(Broker)
2、Broker是指运行Kafka服务的单个服务器节点,它负责存储和处理消息。Kafka集群由多个Broker组成,每个Broker可以容纳多个主题(Topic)‌;
2、消息生产者是向Kafka发送消息的客户端,而消息消费者则负责消费Kafka服务器上的消息‌;
3、Topic是用户定义并配置在Kafka服务器的,用于建立Producer和Consumer之间的订阅关系‌;
4、Partition是消息的分区,一个Topic可以分为多个Partition,每个Partition是一个有序的队列‌

1.1 工作流程

1.1.1 生产者工作流程

1、生产者首先创建一个KafkaProducer对象,然后构建消息记录(ProducerRecord),创建的对象包含了目标主题(Topic)、消息键(Key)和消息值(Value)
3、生产者将消息键和消息值序列化为字节数组,以便在网络上传输和存储
4、Kafka根据消息键和分区策略(如轮询或哈希)选择目标分区。如果消息键为空,Kafka会使用轮询策略将消息均匀分配到各个分区
5、生产者调用send()方法将消息发送到Kafka集群。生产者可以选择同步或异步发送消息
6、每个分区内的消息都是有序的、不可变的,当生产者发送消息到Kafka集群时,这些消息会被顺序的追加到指定主题和分区的末尾;每个消息都有一个连续的序列号,称之为偏移量(Offset),用于在分区内唯一标识消息。

1.1.2 消费者工作原理

1、消费者创建一个KafkaConsumer实例
‌2、消费者调用subscribe()方法订阅一个或多个主题。
‌3、调用poll()方法从Kafka集群拉取消息。消费者可以根据需要设置拉取间隔和拉取数量。
‌4、消费者将消息键和消息值反序列化为原始数据类型,以便进行处理。
‌5、处理拉取到的消息,执行必要的业务逻辑。
‌6、定期提交消费进度(偏移量),以确保消息的准确处理和故障恢复。消费者可以选择自动提交或手动提交偏移量。

1.2 一些关系

1.2.1 消费者、消费者组、分区的关系

1、消费者组可以包含多个消费者实例,这些实例共同订阅并消费主题下的消息。Kafka会自动将主题的分区分配给消费者组内的消费者,以实现负载均衡‌
2、一个分区在同一时间内只能被一个消费者组中的一个消费者所消费,这是为了保证消息的顺序性‌
3、一个消费者可以消费多个分区的数据
4、在设置消费者数量和分区数量时,消费者数量应与主题的所有分区数量相等
如果消费者组中的消费者数量超过了分区的数量,那么多余的消费者将无法消费数据,因为每个分区只能被一个消费者消费,这可能会造成资源浪费‌
如果消费者数量少于分区数,那么一个消费者可能会消费多个分区的数据‌

1.2.2 broker和分区的关系

1、Broker是Kafka集群中的服务器节点,负责处理客户端的请求和数据的存储。
2、Kafka能够将一个Topic的消息打散到多个分区上,这些分区的副本可以分布在不同的Broker上,以实现负载均衡。每个Broker都会处理一部分分区的数据
3、通常建议Broker的数量大于等于分区数量,这样可以确保每个分区都有一个对应的Broker来管理
过多的分区可能会导致吞吐量增加,而过少的分区则可能无法充分利用Kafka的并行处理能力

1.2.3 分区和副本的关系

1、每个分区都有一个领袖副本(Leader Replica)和若干个跟随者副本(Follower Replica)。
2、领袖副本负责处理所有的读写请求,而跟随者副本则负责从领袖副本那里复制消息,保持与领袖一致的状态。如果领袖副本发生故障,系统可以自动将其中一个跟随者副本提升为新的领袖副本,从而保证服务的连续性‌

1.2.4 key和偏移量

1、key是生产者在发送消息时可以为每条消息指定的一个可选属性;key的主要作用是用于计算消息应该被发送到哪个分区
2、如果生产者没有为消息指定key,Kafka则会使用默认的分区器来计算消息的分区,这通常是通过轮询的方式将消息分配到不同的分区
3、偏移量是Kafka中用于标识分区内每条消息位置的唯一标识符;偏移量从0开始递增,每条消息都有一个唯一的偏移量,它保证了消息在分区内的顺序性
4、消费者在消费消息时,会记录自己当前消费到的偏移量,以便在下次消费时能够继续从上次消费的位置开始消费,避免消息丢失或重复消费
5、Kafka可以通过key和偏移量保证消费的顺序性,通过key将相关消息发送到同一分区,确保分区内消息的有序性;同时,利用偏移量记录消费者在分区中的消费进度,从而保证消息按照发送顺序被消费。

二、kafka使用

2.1 kafka安装

Kafka自2.8版本起可以不使用Zookeeper,新版本中Zookeeper不再是必需的组件。安装Kafka时,可以选择使用内置的Zookeeper或独立的Zookeeper集群。另一种选择是使用KRaft组件,通过分布式协议生成集群,无需Zookeeper。

1、从Apache Kafka官方网站下载最新版本的Kafka安装包

# 使用wget命令下载Kafka安装包
wget https://dlcdn.apache.org/kafka/3.6.0/kafka_2.13-3.6.0.tgz

2、解压Kafka安装包

# 解压Kafka安装包
tar -xzf kafka_2.13-3.6.0.tgz

3、配置kafka
主要通过编辑config/目录下的属性文件来完成。对于集群安装,需要编辑server.properties文件来为每个Broker指定唯一的broker.id和listeners;
如果使用内置zookeeper不需要额外配置ZooKeeper的连接信息

# 如果有三台机器
# 第一台配置
broker.id=1
listeners=PLAINTEXT://192.168.1.1:9092
log.dirs=/tmp/kafka-logs-1

# 第二台配置
broker.id=2
listeners=PLAINTEXT://192.168.1.2:9092
log.dirs=/tmp/kafka-logs-2

# 第三台配置
broker.id=3
listeners=PLAINTEXT://192.168.1.3:9092
log.dirs=/tmp/kafka-logs-3

4、启动kafka
如果使用zookeeper,需要先启动zookeeper

# 进入Kafka解压后的目录
cd /home/kafka/kafka_2.13-3.6.0

# 使用内置zookeeper时,可以用该命令启动
bin/zookeeper-server-start.sh config/zookeeper.properties

# 启动Kafka Server
bin/kafka-server-start.sh config/server.properties

5、创建并测试topic
bin/kafka-topics.sh --create --topic <主题名称> --partitions <分区数量> --replication-factor <副本因子>–bootstrap-server hostname:port 指定Kafka集群的Bootstrap服务器地址。Bootstrap服务器是客户端用于初始化与Kafka集群连接的服务器列表。可以是一个或多个服务器的地址,多个服务器地址用逗号分隔

# 创建topic
bin/kafka-topics.sh --create --topic test-topic --bootstrap-server 192.168.1.1:9092,192.168.1.2:9092,192.168.1.3:9092 --replication-factor 3 --partitions 1

测试生产者和消费者

# 在一个终端中运行生产者
bin/kafka-console-producer.sh --topic test-topic --bootstrap-server 192.168.1.1:9092,192.168.1.2:9092,192.168.1.3:9092

# 在另一个终端中运行消费者
bin/kafka-console-consumer.sh --topic test-topic --bootstrap-server 192.168.1.1:9092,192.168.1.2:9092,192.168.1.3:9092 --from-beginning

2.2 使用示例

2.2.1 生产者端

1、引入依赖

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

2、生产者配置
application.yml文件

spring:
  kafka:
    bootstrap-servers: localhost:9092 # Kafka集群的地址,可以是一个或多个broker地址,用逗号分隔
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer # 键的序列化器
      value-serializer: org.apache.kafka.common.serialization.StringSerializer # 值的序列化器
      acks: all # 生产者要求所有副本都确认收到消息后才认为消息发送成功
      retries: 3 # 发送失败后的重试次数
      buffer-memory: 33554432 # 生产者可以使用的总内存大小
      batch-size: 16384 # 批次的大小,当多条消息发送到同一个分区时,生产者会尝试将它们合并成一个批次发送,达到这个大小发送批次
      linger-ms: 1 # 生产者在发送批次之前等待更多消息加入批次的时间
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer # 键的反序列化器(通常用于消费者配置)
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer # 值的反序列化器(通常用于消费者配置)

3、生产者代码示例

package com.project.myStudy.service.kafka;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

@Service
public class KafkaProducer {
    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    public void sendMessage(String topic, String message) {
        kafkaTemplate.send(topic, message);
    }
}

使用

package com.project.myStudy.service.kafka;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class KafkaService {
    @Autowired
    private KafkaProducer producerService;

    public void doSomething() {
        producerService.sendMessage("myTopic", "Hello, Kafka!");
    }
}

2.2.2 消费者端

​1、引入依赖

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

2、消费者配置

spring:
  kafka:
  	bootstrap-servers: localhost:9092 # Kafka集群地址
    consumer:
      group-id: my-consumer-group # 消费者组ID
      auto-offset-reset: earliest # 自动重置偏移量到最早位置
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer # 键的反序列化器
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer # 值的反序列化器
      enable-auto-commit: true # 是否启用自动提交偏移量
      auto-commit-interval-ms: 1000 # 自动提交偏移量的间隔(毫秒)
      max-poll-records: 100 # 每次轮询的最大记录数

3、使用示例

@Service
public class KafkaConsumer {
    @KafkaListener(topics = "my-topic", groupId = "my-consumer-group")
    public void listen(String message) {
        // 处理接收到的消息
        System.out.println("Received message: " + message);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值