1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-08-01 16:28:03 +08:00

add chapter message queue & ch1 kafka

This commit is contained in:
戴林峰 2023-09-29 18:07:09 +08:00
parent b83d88ce1d
commit d9e554a4a6
3 changed files with 133 additions and 0 deletions

View File

@ -327,6 +327,16 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8](https://docs.oracle.
[Web 实时消息推送详解](./system-design/web-real-time-message-push.md)
## 消息队列
### Kafka
[Kafka基础](./mq/kafka/kafka-basis.md)
## 分布式
### 理论&算法&协议

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 KiB

View File

@ -0,0 +1,123 @@
---
title: Kafka基础
category: 消息队列
tag:
- 消息队列
head:
- - meta
- name: keywords
content: Kafka基础
- - meta
- name: description
content: Kafka是一个分布式系统由服务器和客户端组成通过高性能的TCP网络协议进行通信。它可以部署在本地和云环境中的裸机硬件、虚拟机和容器上。
---
## 什么是Kafka
**KafKa**是一个**分布式**的基于**发布/订阅模式**的消息队列主要应用于大数据实时处理领域。Kafka由**服务端**和**客户端**组成通过高性能的TCP网络协议进行通信。它可以部署在本地和云环境中的裸机硬件、虚拟机和容器上。
+ 服务端Kafka作为一个或多个服务器集群运行其中部分服务器构成了存储层Brokers。其他服务器作为[Kafka Connect](https://kafka.apache.org/documentation/#connect)以事件流的形式持续导入和导出数据。同时Kafka集群具有高度的**可扩展性**和**容错性**:如果其中任何一台服务器出现故障,其他服务器将接管其工作,以确保其保持持续运行状态。
+ 客户端:提供接口编写分布式和微服务程序,以并行、大规模和容错的方式读取、写入和处理事件流。
## Kafka的使用背景为什么要使用Kafka
这道题可以理解为为什么要使用消息队列? (消息队列的作用?优点?)
+ **缓冲和削峰**:消息队列在应对类似双十一这样的突发高流量场景中发挥着关键的作用,它可以被视为一个非常有效的**缓冲**和**削峰**机制。考虑以下情形:当突然涌入大量订单请求时,下游的处理服务器可能不具备足够的计算资源来立即处理这些请求。直接将这些请求传递给下游服务器可能导致其超负荷运行,甚至崩溃。消息队列通过将这些突发的订单流量缓存到消息队列中,允许订单处理端按照其自身的处理能力逐一从消息队列中提取订单并进行处理。这种方式有效地平滑了流量高峰,确保了系统的稳定性。因此,消息队列在这里扮演了一个关键的角色,既能够充当缓冲,将请求暂时保存在队列中,又能够削减流量高峰,防止直接冲击到下游服务器,从而实现了系统的平稳运行。
+ **解耦和扩展性**:在项目开发中,由于需求的不确定性,消息队列充当了一个关键的接口层,通过将关键的业务流程解耦。这种解耦使得在后续业务需要扩展时,只需遵循约定并进行数据编程,就能轻松实现所需的扩展能力。
+ **异步通信**:消息队列提供了一种强大的机制,允许用户将消息放入队列中,而无需立即处理它们。这种异步处理方式可以显著提高业务处理速度,例如在需要发送短信验证码的用户注册等场景中,业务主线程可以将发送短信验证码的任务放入消息队列,然后继续处理其他业务,而无需等待短信发送完成。这种机制极大地提高了系统的效率和响应性。
+ **可恢复性**:即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
## Kafka的使用场景
+ **日志收集**:一个公司可以用 Kafka 可以收集各种服务的 log通过 Kafka 以统一接口服务的方式开放给各种 consumer。也就是在系统各个运行的位置将日志输送到一个统一的地方进行保存和处理。
+ **消息系统**:将业务进行解耦合,分成消息的生产者和消费者,实现异步通信、可恢复、解耦和缓冲与削峰。
+ **用户行为跟踪**Kafka 经常被用来记录web用户或者 app 用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到 kafka 的 Topic 中然后订阅者通过订阅这些topic来做实时的监控分析或者装载到 Hadoop、数据仓库中做离线分析和挖掘。
## Kafka架构
<img src="kafka-basis.assets/image-20230929154749134.png" alt="image-20230929154749134" style="zoom:50%;" />
+ **Producer**(生产者):生产者可以将数据发布到所选择的topic主题中。生产者负责将记录分配到topic的指定分区partition这里可以使用多个partition循环发送来实现多个server负载均衡。
+ **Consumer**(消费者): 消息消费者,从 Kafka Broker 取消息的客户端。
+ **Broker**Broker是kafka的服务节点一个Broker就是一个服务节点即Kafka服务器。一个broker可以容纳多个topic。broker可以看作事消息的代理Producers往Brokers里面指定的Topic写消息Consumers从Brokers里面拉取指定的消息然后进行业务处理broker在中间起到一个代理保存消息的中转站。
+ **Topic**(主题):可以理解为一个队列,一个 Topic 又分为一个或多个分区。
+ **Partition**分区Topic 是一个逻辑的概念,它可以细分为多个分区,每个分区只属于单个主题。 同一个主题下不同分区包含的消息是不同的分区在存储层面可以看作一个可追加的日志Log文件消息在被追加到分区日志文件的时候都会分配一个特定的偏移量Offset
+ **Offset**偏移量是消息在分区中的唯一标识Kafka 通过它来保证消息在分区内的顺序性,不过 Offset 并不跨越分区也就是说Kafka 保证的是分区有序性而不是主题有序性,即局部有序。
+ **Replication** (副本):是 Kafka 保证数据高可用的方式Kafka 同一 Partition 的数据可以在多 Broker 上存在多个副本,通常只有主副本对外提供读写服务,当主副本所在 Broker 崩溃或发生网络一场Kafka 会在 Controller 的管理下会重新选择新的 Leader 副本对外提供读写服务。
+ **Record** :实际写入 Kafka 中并可以被读取的消息记录。每个 Record 包含了 key、value 和 timestamp。
+ **Consumer Group** 消费者组CG消费者组内每个消费者负责消费不同分区的数据提高消费能力。一个分区只能由组内一个消费者消费消费者组之间互不影响。所有的消费者都属于某个消费者组即消费者组是逻辑上的一个订阅者。
## Kafka为什么要分区Kafka分区的目的
+ **提供并行处理能力**通过将消息分散到多个分区Kafka可以实现消息的并行处理。消费者可以独立地从不同的分区中读取消息从而提高整体的处理能力。
+ **提高可靠性和可伸缩性**Kafka通过复制机制实现数据的可靠性和冗余存储每个分区可以配置多个副本这些副本分布在不同的Broker节点上当一个副本不可用时可以使用其他副本来继续提供服务。同时通过增加分区的数量可以增加整个系统的处理能力、存储容量和实现负载均衡提高并发度提高效率。
## Kafka如何实现消息有序性
kafka中每一个partition中的消息在写入的时候都是有序的而且单独一个partition只能由一个消费者去消费可以在里面保证消息的顺序性但是分区之间的额消息是不保证有序的。总结就是kafka只保证了单个partition的有序性并没有保证多个partition的有序性因为如果需要保证多个partition的有序性那么整个kafka就退化成了单一队列毫无并发性可言了。
**那如果需要保证全局的有序性怎么办呢?**
1. 创建一个Topic只创建一个Partition这样就不会存在多个partition也自然是全局有序的了。
2. 生产者发送消息的时候发送到指定的partition。
## Kafka为什么这么快
kafka会把接收到的信息都写入硬盘中来保证消息的不丢失。为了优化写入速度Kafka采用了顺序写入和MMFile两个技术。
**写入数据**
1. 顺序写入:因为硬盘是机械结构,每次读写都会寻址->写入其中寻址是一个“机械动作”它是最耗时的。所以硬盘最讨厌随机I/O最喜欢顺序I/O。为了提高读写硬盘的速度Kafka就是使用顺序I/O。
2. MMFile即使是顺序写入硬盘的访问速度还是与内存速度有较大的差距。因此Kafka并不是实时写入硬盘的它还利用了操作系统的分页存储来利用内存提高I/O效率。
> Memory Mapped Files(后面简称mmap)也被翻译成 内存映射文件 在64位操作系统中一般可以表示20G的数据文件它的工作原理是直接利用操作系统的Page来实现文件到物理内存的直接映射。完成映射之后你对物理内存的操作会被同步到硬盘上操作系统在适当的时候
**读取数据**
1. 基于sendfile实现**零拷贝**,减少拷贝次数。
> 零拷贝是指计算机执行IO操作时CPU不需要将数据从一个存储区域复制到另一个存储区域从而可以减少上下文切换以及CPU的拷贝时间。它是一种`I/O`操作优化技术。(减少用户态与内核态之间的数据复制次数)
>sendfile具体流程如下
>
>1. sendfile系统调用文件数据被copy至内核缓冲区
>2. 从内核缓冲区copy至内核中socket相关的缓冲区
>3. socket相关的缓冲区copy到协议引擎
2. 批量压缩它把所有的消息都变成一个批量的文件并且进行合理的批量压缩减少网络IO损耗。Producer使用GZIP或者Snappy格式对消息几个进行压缩压缩的好处就是减少传输的数据量减轻对网络传输的压力。
**文件分段**
kafka 的队列topic被分为了多个区partition每个partition又分为多个段segment所以一个队列中的消息实际上是保存在N多个片段文件中。通过分段的方式每次文件操作都是对一个小文件的操作非常轻便同时也增加了并行处理能力。
**批量发送**
Kafka 允许进行批量发送消息先将消息缓存在内存中然后一次请求批量发送出去比如可以指定缓存的消息达到某个量的时候就发出去或者缓存了固定的时间后就发送出去如100条消息就发送或者每5秒发送一次这种策略将大大减少服务端的I/O次数。
## Kafka中的消息是否会丢失和重复消费
## 参考
+ Kafka官方文档https://kafka.apache.org/documentation
+ Kafka 设计架构原理详细解析https://blog.csdn.net/qq_32828253/article/details/110732652
+ Kafka为什么这么快https://zhuanlan.zhihu.com/p/147054382