阅读kafka文档

This commit is contained in:
2023-10-04 17:51:29 +08:00
parent fb01d0a2c4
commit 48d52cf098
2 changed files with 91 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
# 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对象完成。

View File

@@ -323,3 +323,36 @@ Kafka的语义是直截了当的当消息被发布时有一个消息被提
- `exactly-once`当写入到外部系统时限制是需要协调消费者位置和实际存储内容。通常情况下实现该功能需要在消费者position的存储系统和消费者输出的存储系统之间引入两阶段提交。但是可以通过将position和consumer output存储在一个位置来简化该过程。因为任何想要写入的系统可能并不支持两阶段提交。
> Kafka在Kafka Streams中支持`exactly-once`传输并且在处理topics之间数据时通过使用transactional producer/consumer来提供`exactly-once`功能。
> 其他情况下kafka默认保证at-least-once传输但是也允许用户实现at-most-once传输通过关闭生产者的重试功能并且在处理数据之前提交position变动。
### 复制
#### 分区备份
kafka会将topic分区复制到多台mq server上mq server的数量可配置。可以针对单个topic来设置replication factor的数量。在其他server上保存副本允许当某台server发生故障宕机后仍然可以从其他server上存储的副本中获取信息。
复制针对的是topic分区。在kafka中每个分区都有一个leader和零或多个follower。leader加上follower的数量构成了replication factor。所有的写操作都会针对leader分区而读操作则是可以针对leader或follower分区。通常情况下分区比broker要多leader分区分布在broker中。follower分区上的日志和leader分区上的日志都相同offset和日志内容都相同在特定时间点leader尾部可能有一些尚未被复制到follower的消息
follower从leader分区消息消息就像一个普通的消费者一样并且将从leader处消费的消息追加到自己分区的尾部。
#### broker节点的活跃状态定义
就像大多数的分布式系统一样自动的故障容灾需要精确定义一个节点的“活跃”状态。在kafka中存在一个节点单独来负责管理集群中broker的注册该节点被称之为controller。broker的活跃状态需要满足如下要求
- broker需要和controller维持一个active session来接收常规的元数据更新
- 作为follower的broker需要从leader处同步leader的写操作变动从而保持分区数据和leader处相同
对于使用zookeeper的集群在broker节点初始化与zookeeper的连接会话时会在zookeeper中创建一个节点如果broker没能在`zookeeper.session.timeout.ms`时间内向zookeeper发送心跳包那么broker就会丢失和zookeeper的会话zookeeper中对应的节点也会被删除。controller会根据zookeeper watch注意到节点的删除并且将该节点对应的broker标记为离线。
#### ISR
满足上述“活跃”要求的节点会被成为"in sync"状态。而leader会跟踪那些处于“in sync”状态的副本处于“in sync”状态的副本集合被称之为ISR(in sync repliasISR中包含leader和follower).
如果ISR中的节点不再满足”活跃“对应的两条要求那么该节点将会从ISR中被移除。例如如果一个follower宕机那么controller将会注意到zookeeper中节点的删除并且将该broker中ISR中移除。
另外,**如果一个节点仍然处于活跃状态但是离同步leader的数据有很长的延迟那么leader将会将该节点从ISR中移除**。延迟的最长时间通过`replica.lag.time.max.ms`来配置。如果在`replica.lag.time.max.ms`时间内副本没能通过leader到日志结尾的数据那么副本节点将会从ISR中被移除。
#### 消息提交的定义
在某分区对应ISR中所有的副本都将消息追加到它们的log后则可以认为该消息被提交。故而消费者并无需担心分区的leader宕机后消息会丢失的问题因为消息在提交前已经持久化到其分区副本中。
作为生产者可以在发送消息时决定是否等待消息被提交这需要在等待提交所带来的延迟和不等待提交所带来的消息丢失风险中进行权衡。是否等待提交取决于生产者的ack设置。
#### 最小写入副本数
topic可以设置一个最小写入的副本数通过配置`min.insync.replicas`可以对最小写入副本数进行配置。即使消息已经同步到所有ISR副本后如果同步数目小于该值同步数目包含leader消息也无法被视为提交
> kafka保证一条消息只要被提交只要有一个in-sync-replica处于活跃状态那么消息就不会被丢失