Files
rikako-note/mq/kafka/kafka-尚硅谷.md
2023-10-04 17:51:29 +08:00

58 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Kafka
## 简介
### 消息队列应用场景
缓存/削峰、解耦、异步通信
### 缓存/削峰
当生产端生产数据的速率大于消费端消费数据的速率时,消息队列可用于对消费不完的数据进行缓存
### 解耦
当数据生产方来源存在多个例如数据库、网络接口等且消费方也存在多种Hadoop大数据平台、spring boot服务实例等可以将消息队列中存储的消息作为数据从生产端到消费端的中间格式。
生产端负责将产生的数据转化成特定格式的消息发送到消息队列,而消费端负责消费消息队列中的消息。不同种类的生产端和消费端只用针对消息的队列中的消息各自进行适配即可。
### 异步通信
通过消息队列可以实现多个服务实例之间的异步调用服务调用方在将调用信息封装到消息并发送消息到mq后即可返回并不需要同步等待。被调用方可以异步的从mq中获取消息并进行消费。
### 消息队列模式
#### 点对点
一个消息队列可以对应多个生产者和多个消费者,**但消息只能被一个消费者进行消费**消费者将数据拉取并消费后向mq发送确认mq中将被消费的消息删除
#### 发布订阅模式
**生产者产生的数据可以被多个消费者消费**生产者将消息发送到topic订阅该topic的消费者会拉取消息进行消费消费完成后并不会删除该消息该消息仍可被其他订阅该topic的消费者进行消费。消息并不会永久保存在消息队列中通常会设置超期时间消息保存超过该时间后自动删除
### kafka架构
#### 分区存储
kafka将一个topic分为了多个分区用于分布式存储数据。而每个分区都跨多台服务器实例进行存储从而增加容错性。对特定分区来说其存在于多台服务器实例其中一台为主机其他服务器为从机**主机会处理对该分区数据所有的读写请求**(由于读写操作全都在主机上发生,而每台服务器都担当了某些分区的主机和其他分区的从机,故而读写请求在不同的服务器之间进行了负载均衡),而从机只会被动的复制主机修改。
#### group消费
每个消费者实例都属于一个consume group一个consume group则是可以保存多个消费者实例。对于发送到kafka mq topic的每一条消息都会被广播给订阅了该topic的每个consume group。而consume group接收到消息后只会将消息发送给group中的一个消费者实例来进行处理故而在consume group中实现了消息在不同消费实例之间的负载均衡。
> 在kafka mq中topic的实际订阅者是consume groupkafka mq会将topic中的消息广播给所有订阅了该topic的consume group而每条消息都只会被consume group中的一个消费者实例进行消费
>
> 在一个consume group中每个消费者实例都负责某一topic中相应的分区每个特定分区只有一个消费者实例负责。
#### zookeeper
zookeeper作为注册中心用于记录存在多个kafka实例时当前已上线且状态正常的kafka实例以及各个分区leader实例的信息
#### 生产者
##### 分区
生产者客户端将会决定将消息发送到某个分区可以通过负载均衡随机决定将消息发送到哪个分区也可以提供一个key并通过算法决定将消息发送到哪个分区。
决定将消息发送到哪个分区后生产者会直接将消息发送到该分区对应的leader broker中。
##### 批量发送
生产者并不会每次产生消息后都立即将消息发送到broker而是会累积消息**直到消息数据积累到特定大小默认为16K后**才会将消息发送给broker。
> **消息发送条件**
>
> - batch.size: 当消息累计到特定大小默认为16K发送给broker。如果消息的大小大于`batch.size`,那么并不会对消息做累积操作。**发送到broker的请求将会包含多个batch每个batch对应一个分区不同分区的消息通过不同的batch进行发送**
> - linger.ms: 生产者将会把发送给broker的两个请求之间的消息都累积到一个batch里该batch将会在下次发送请求给broker时发送。但是对特定分区累积大小如果没有达到`batch.size`的限制哪个通过linger.ms来控制该消息延迟发送的最长时间。`linger.ms`单位为ms**其默认值为0代表即使消息累积没有达到`batch.size`也会立马发送给broker**。若`linger.ms`设置为1000则代表没有累积到`batch.size`大小的消息也会在延迟1s后发送给broker
##### ack级别
生产者将消息发送到broker后broker对生产者有三种应答级别
- 0生产者发送数据后无需等待broker返回ack应答
- 1生产者发送消息到broker后leader broker将消息持久化后向生产者返回ack
- -1生产者发送过来的数据leader broker和isr队列中所有的broker都持久化完数据后返回ack
##### 异步发送
kafka生产者异步发送是指生产者调用kafka客户端接口将发送的消息传递给kafka的客户端此时消息并未发送到broker而异步调用接口即返回。调用异步接口可以通过指定回调来获取消息传递到的topic、分区等信息。
##### 同步发送
除了异步调用接口外还可以调用同步调用的接口来发送消息。在调用异步接口发送消息时仅仅将消息放到缓冲区后调用就返回可能放到缓冲区的消息并没有发送到broker。可以通过调用同步发送消息的接口来发送消息其会阻塞并等待broker将消息持久化后返回的异常或者ack应答。
想要同步发送消息只需要对异步接口返回的future对象调用`.get`即可其会等待future对象完成。