文章

Kafka介绍

Kafka介绍

该文主要介绍 Kafka

Kafka

1. 简介1

Kafka 是一款开源的消息引擎系统,也是一个分布式流计算平台,此外,还可以作为数据存储。

github: https://github.com/apache/kafka

官网: https://kafka.apache.org/

中文文档: https://kafka.apachecn.org/

1.1. 特性

  • 高性能
    • 分区、分段、索引:基于分区机制提供并发处理能力。分段、索引提升了数据读写的查询效率。
    • 顺序读写:使用顺序读写提升磁盘 I/O 性能。
    • 零拷贝:利用零拷贝技术,提升网络 I/O 效率。
    • 页缓存:利用操作系统的 PageCache 来缓存数据(典型的利用空间换时间)
    • 批量读写:批量读写可以有效提升网络 I/O 效率。
    • 数据压缩:Kafka 支持数据压缩,可以有效提升网络 I/O 效率。
    • pull 模式:Kafka 架构基于 pull 模式,可以自主控制消费策略,提升传输效率。
  • 高可用
    • 持久化:Kafka 所有的消息都存储在磁盘,天然支持持久化。
    • 副本机制:Kafka 的 Broker 集群支持副本机制,可以通过冗余,来保证其整体的可用性。
    • 选举 Leader:Kafka 基于 ZooKeeper 支持选举 Leader,实现了故障转移能力。
  • 伸缩性
    • 分区:Kafka 的分区机制使得其具有良好的伸缩性。

1.2. 术语

  • 消息:Kafka 的数据单元被称为消息。消息由字节数组组成。
  • 批次:批次就是一组消息,这些消息属于同一个主题和分区。
  • 主题(Topic):Kafka 消息通过主题进行分类。主题就类似数据库的表。
    • 不同主题的消息是物理隔离的;
    • 同一个主题的消息保存在一个或多个 Broker 上。但用户只需指定消息的 Topic 即可生产或消费数据而不必关心数据存于何处。
    • 主题有一个或多个分区。
  • 分区(Partition):分区是一个有序不变的消息序列,消息以追加的方式写入分区,然后以先入先出的顺序读取。Kafka 通过分区来实现数据冗余和伸缩性。
  • 消息偏移量(Offset):表示分区中每条消息的位置信息,是一个单调递增且不变的值。
  • 生产者(Producer):生产者是向主题发布新消息的 Kafka 客户端。生产者可以将数据发布到所选择的主题中。生产者负责将记录分配到主题中的哪一个分区中。
  • 消费者(Consumer):消费者是从主题订阅新消息的 Kafka 客户端。消费者通过检查消息的偏移量来区分消息是否已读。
  • 消费者群组(Consumer Group):多个消费者共同构成的一个群组,同时消费多个分区以实现高并发。
    • 每个消费者属于一个特定的消费者群组(可以为每个消费者指定消费者群组,若不指定,则属于默认的群组)。
    • 群组中,一个消费者可以消费多个分区
    • 群组中,每个分区只能被指定给一个消费
  • 再均衡(Rebalance):消费者组内某个消费者实例挂掉后,其他消费者实例自动重新分配订阅主题分区的过程。分区再均衡是 Kafka 消费者端实现高可用的重要手段。
  • Broker - 一个独立的 Kafka 服务器被称为 Broker。Broker 接受来自生产者的消息,为消息设置偏移量,并提交消息到磁盘保存;消费者向 Broker 请求消息,Broker 负责返回已提交的消息。
  • 副本(Replica):Kafka 中同一条消息能够被拷贝到多个地方以提供数据冗余,这些地方就是所谓的副本。副本还分为领导者副本和追随者副本,各自有不同的角色划分。副本是在分区层级下的,即每个分区可配置多个副本实现高可用。

2. 发展2

消息中间件的作用主要有两点:

  • 解耦消息的生产和消费
  • 缓冲

2.1. Kafka一代 - 消息队列

img

消息中间件之所以可以解耦消息的生产和消费,主要是它提供了一个存放消息的地方——生产者把消息放进来,消费者在从中取出消息进行处理。

Kafka 会对数据进行持久化存储(至于存放多长时间,这是可以配置的),消费者端会记录一个 offset,表明该消费者当前消费到哪条数据,所以下次消费者想继续消费,只需从 offset+1 的位置继续消费就好了。消费者甚至可以通过调整 offset 的值,重新消费以前的数据。

问题:

  • Topic未分类。想象一下,一个只订阅了 topicA 的消费者,却要在有 ABCDEF 等各种各样 topic 的队列里头去寻找 topicA 的消息,这样性能岂不是很慢?
  • 吞吐量低。我们把全部消息都放在一条队列了,请求一多,它肯定应付不过来。

2.2. Kafka二代 - Partition

img

要解决 Kafka 一代的那两个问题,很简单——分布存储

二代 Kafka 引入了Partition的概念,也就是采用多条队列, 每条队列里面的消息都是相同的 topic

问题:

  • 万一机器挂掉了怎么办?单点系统总是不可靠的。我们必须考虑备用节点和数据备份的问题。

2.3. Kafka三代 - Broker集群

img

为了解决高可用问题,我们需要集群

每个 partition 不再只有一个,而是有一个 leader 和多个 replica,生产者根据消息的 topic 和key值,确定了消息要发往哪个 partition 之后(假设是p1),会找到partition对应的leader(也就是broker2里的p1),然后将消息发给leaderleader负责消息的写入,并与其余的replica进行同步。一旦某一个 partitionleader 挂掉了,那么只需提拔一个 replica 出来,让它成为 leader 就好了,系统依旧可以正常运行。

通过 Broker 集群的设计,我们不仅解决了系统高可用的问题,还进一步提升了系统的吞吐量,因为 replica 同样可以为消费者提供数据查找的功能。

参考

本文由作者按照 CC BY 4.0 进行授权