Kafka 基础知识

2023-09-07 16:21:59 浏览数 (1)

一、什么是Kafka

Apache Kafka是一个分布式的基于发布订阅消息系统的消息队列,可以处理大量的数据,并使您能够将消息从一个端点传递到另一个端点

  • Kafka适合离线和在线消息消费
  • Kafka消息保留在磁盘上,并在群集内复制以防止数据丢失
  • Kafka构建在ZooKeeper同步服务之上。 它与Apache Storm和Spark非常好地集成,用于实时流式数据分析

消息队列是一个用于接收消息、存储消息并且转发消息的中间件,主要是用于解决如下的场景:

  • 异步:A服务做了一些事情,异步发送消息给服务B;
  • 削峰/限流:有些服务(例如电商服务的秒杀),请求量很高,服务端处理不过来,那么请求先放到消息队列里面,然后服务端按照自己的能力来消费处理;
  • 解耦:应用之间减少代码的耦合,使得应用的部署更加灵活;

二、基本架构介绍

  1. Producer :消息生产者,就是向 kafka broker 发消息的客户端
  2. Consumer :消息消费者,向 kafka broker 取消息的客户端
  3. Consumer Group (CG):消费者组,由多个 consumer 组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者【提高消费能力】
  4. Broker :一台 kafka 服务器就是一个 broker。一个集群由多个 broker 组成。一个 broker 可以容纳多个 topic
  5. Topic :消息主题分类,生产者和消费者面向的都是一个 topic,我们在收发消息时只需指定 topic。
  6. Partition: 分区。为了提升系统的吞吐,一个 topic 下通常有多个 partition,partition 分布在不同的 Broker 上,用于存储 topic 的消息,这使 Kafka 可以在多台机器上处理、存储消息,给 kafka 提供给了并行的消息处理能力和横向扩容能力。
  7. Replica: 副本,为保证集群中的某个节点发生故障时,该节点上的 partition 数据不丢失,且 kafka 仍然能够继续工作,kafka 提供了副本机制,一个 topic 的每个分区都有若干个副本, 一个 leader 和若干个 follower
    1. leader:每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是 leader
    2. follower:每个分区多个副本中的“从”,实时从 leader 中同步数据,保持和 leader 数据 的同步。leader 发生故障时,某个 follower 会成为新的 follower

三、Kafka 架构深入

3.1 工作流程及文件存储机制

3.1 Kafka 生产者

数据可靠性保证

Kafka 高可靠性的核心是保证消息在传递过程中不丢失,涉及如下核心环节:

  • 消息从生产者可靠地发送至 Broker;-- 网络、本地丢数据;
  • 发送到 Broker 的消息可靠持久化;-- Pagecache 缓存落盘、单点崩溃、主从同步跨网络;
  • 消费者从 Broker 消费到消息且最好只消费一次 -- 跨网络消息传输 。

ack 策略

针对问题 1,Kafka 为我们提供了三种 ack 策略,

  • Request.required.acks = 0:请求发送即认为成功,不关心有没有写成功,常用于日志进行分析场景;
  • Request.required.acks = 1:当 leader partition 写入成功以后,才算写入成功,有丢数据的可能;
  • Request.required.acks= -1:ISR 列表里面的所有副本都写完以后,这条消息才算写入成功,强可靠性保证;

故障处理细节:Log 文件中的 HW 所有副本中最小的 LEO 和 LEO 每个副本的最后一个 offset,保证消费数据的完整性

消息发送策略

kafka 提供两类消息发送方式:同步(sync)发送和异步(async)发送,相关参数如下:

同步发送支持接受消息发送结果的回调

3.2 发送到 Broker 的消息可靠持久化

  • Broker 异步刷盘机制
    • Broker 接收到消息后只是将数据写入 PageCache 后便认为消息已写入成功,而 PageCache 中的数据通过 linux 的 flusher 程序进行异步刷盘(刷盘触发条:主动调用 sync 或 fsync 函数、可用内存低于阀值、dirty data 时间达到阀值),将数据顺序写到磁盘。
  • Replica 副本机制
    • 每组分区通常有多个副本,同组分区的不同副本分布在不同的 Broker 上,保存相同的消息(可能有滞后)

3.3 Kafka 消费者

一、消费方式:consumer 采用 pull(拉)模式从 broker 中读取数据

二、分区分配策略

一个 consumer group 中有多个 consumer,一个 topic 有多个 partition,确定那个 partition 由哪个 consumer 来消费

三、offset 维护

consumer 需要实时记录自己消费到了哪个 offset

offset 是消息在分区中的唯一标识,是一个单调递增且不变的值。Kafka 通过它来保证消息在分区内的顺序性,不过 offset 并不跨越分区,也就是说,Kafka 保证的是分区有序而不是主题有序

四:可靠消费:

Consumer 在消费消息的过程中需要向 Kafka 汇报自己的位移数据,只有当 Consumer 向 Kafka 汇报了消息位移,该条消息才会被 Broker 认为已经被消费。因此,Consumer 端消息的可靠性主要和 offset 提交方式有关,Kafka 消费端提供了两种消息提交方式:

通常是通过手动提交 幂等实现消息的可靠消费。

3.4 分区的原因 Partition

  • 方便在集群中扩展, topic 分为多个 partition 传递到多个 kafka 主机实现消息发送,可以更好的实现负载均衡
  • 提高并发,以 Partition 为单位读写

数据进行 Partition 分区的原则

  • 指明 partition 的情况
  • 没有指明 partition 值但有 key 的情况,将 key 的 hash 值与 topic 的 partition 数进行取余得到 partition 值
  • 既没有 partition 值又没有 key 值的情况下:第一次调用时随机生成一个整数,之后每次调用自增,将这个值与 topic 可用的 partition 总数取余得到 partition 值, round-robin 轮询调度算法

文件存储

为防止 log 文件,Kafka 采取了分片和索引机制,将每个 partition 分为多个 segment。每个 segment 对应两个文件——“.index”文件和“.log”文件

segment:分段。宏观上看,一个 partition 对应一个日志(Log)。由于生产者生产的消息会不断追加到 log 文件末尾,为防止 log 文件过大导致数据检索效率低下,Kafka 采取了分段和索引机制,将每个 partition 分为多个 segment,同时也便于消息的维护和清理。每个 segment 包含一个.log 日志文件、两个索引(.index、timeindex)文件以及其他可能的文件,每个 Segment 的数据文件以该段中最小的 offset 为文件名,当查找 offset 的 Message 的时候,通过二分查找快找到 Message 所处于的 Segment 中。

四、参考链接

Kafka 高可靠高性能原理探究

一文理解 kafka 如何保证消息顺序性

由于Kafka的一个 Topic 可以分为了多个 Partition,Producer发送消息的时候,是分散在不同 Partition,会导致消息顺序顺序是乱的。

  • 全局有序:需要1个Topic只能对应1个Partition(降低了吞吐量)
  • 局部有序:发消息的时候指定 Partition Key,Kafka对其进行Hash计算,Partition Key 相同的消息会放在同一个Partition(降低了吞吐量)

Kafka 为什么如此之快

  • 磁盘顺序读写
  • pageCache 缓存技术(内存中)
  • 零拷贝技术(零拷贝技术不是指不发生拷贝,而是在用户态没有进行拷贝)
    • sendfile零拷贝技术在内核态将数据从PageCache拷贝到了Socket缓冲区,这样就大大减少了不同形态的切换以及拷贝
  • kafka分区架构和批量操作

kafka 和 rabbitmq 的区别

参考链接

主要是设计理念和使用场景的不同:

Rabbitmq 比 kafka可靠,kafka更适合IO高吞吐的处理

0 人点赞