Kafka 基础
基础简介
Kafka 是一个分布式的、多分区的、多副本的、多订阅者的,基于 Zookeeper 协调的分布式日志系统,也可以作为 MQ 系统使用。
Kafka 特性
- 高吞吐量、低延迟:每秒可处理十万级的数据,延迟最低仅几毫秒
- 可扩展性:集群支持热扩展
- 持久性、可靠性:消息可持久化到硬盘,支持数据备份
- 容错性:允许集群中的节点失败
- 高并发:单机可支持数千客户端同时读写
Kafka 应用场景
- 服务日志收集
- 作为消息系统
- 用户活动跟踪
- 记录运营监控数据
- 流式处理
Kafka 架构
基本术语
broker
:Kafka 集群包含一个或者多个服务器,每一个服务器节点都称为一个 broker;topic
:主题,所有发布到 Kafka 的消息都有一个类别,这个类别称为主题,即消息按照主题进行分类。同一个 topic 的数据既可以都在一个 broker 节点上,也可以在不同的节点上;partition
:分区,每一个 topic 可分为多个分区,在创建 topic 时可指定分区;- 每一个分区在物理上对应着一个文件夹,里面存储着该分区的所有消息和索引文件。当生产者将消息发布到 topic 时,消息将根据分区策略被分配到不同的分区。消息将被追加到分区末尾,属于顺序写磁盘,故效率高
offset
:可以理解为消息的下标索引,partition 中的每一条消息都被标记了一个序号,该序号表示当前消息在 partition 中的偏移量,消费者可以通过设置的 offset 消费指定的消息;- 正常情况下,消费者消费完消息后会将 offset 递增,但是也可以将 offset 设置为较小的值,对之前消费过的消息进行重新消费
producer
:生产者,负责产生消息并将消息发送到指定的 topic;consumer
:消费者,从 topic 消费消息;group
:消费者组,每个消费者都属于一个特定的消费者组,可以进行指定,若不指定则属于默认的消费者组;- 同一个 topic 的消息只能被一个 group 内的一个消费者消费,但是多个 group 可以同时消费这一消息。这也是 Kafka 实现单播和广播的方式:若要实现单播,将所有消费者放置在一个消费者组即可;若要实现广播,则每一个消费者组只设置一个消费者即可
leader
:partition 副本领导者,负责所有客户端的读写操作,类似于 Redis 主从模式follower
:follower不对外提供服务,其作为备份,只与 leader 保持一致。若 leader 失效,则通过重新选举的方式,选择一个 follower 成为新的 leader。当 follower 卡住或者同步太慢时,leader 会将该 follower 删除并重新创建一个 follower;
关于 Kafka 的几个问题
与传统 MQ 的区别
对于传统 MQ,已经被消费过的消息将会在队列中删除,而 Kafka 中的消息在被消费过后不会立即删除。Kafka 配置文件 server.properties 中定义了数据的保存时间,当文件的保存时间到期后才会执行删除。
# 数据的保存时间(单位:小时,默认为7天)
log.retention.hours=168
点对点模式与发布订阅模式
- 点对点模式:生产者发布消息到队列中,消息队列可存在多个消费者。但是对于某一条消息而言,其只能被一个消费者消费,被消费过的消息将从消息队列中删除,不再进行存储;
- 发布订阅模式:生产者发布消息到 topic 中,该 topic 可以被多个消费者订阅,生产者生产的消息将被所有订阅该 topic 的订阅者消费;
消费端的 pull 与 push
- push 方式:由消息中间件主动将消息推送给订阅者
- 优点:不需要消费者开启线程额外监听消息中间件,节省开销;
- 缺点:无法适应效率不同的消费者。消息发送的速率由 broker 决定,消费者处理消息的效率不同,这将导致一部分消费者空闲,一部分消费者堆积,从而导致缓冲区溢出;
- pull 方式:由消费者主动从消息中间件中拉取消息
- 优点:消费者可以按照处理能力按需拉取;
- 缺点:消费者需要额外开启监听线程,存在性能开销;
Kafka 吞吐量高的原因
- 顺序读写磁盘:基于磁盘的顺序读写性能却很高,一般而言要高出磁盘的随机读写三个数量级
- Page Cache:为了优化读写性能,Kafka 利用了操作系统本身的 Page Cache,就是利用操作系统自身的内存而不是 JVM 空间内存,这是因为:
- JVM中一切皆对象,对象的存储会带来额外的内存消耗;
- 使用JVM会受到GC的影响,随着数据的增多,垃圾回收也会变得复杂与缓慢,降低吞吐量;
- 零拷贝:"零拷贝"并不是说整个过程完全不发生拷贝,而是站在内核的角度来说的,避免了内核空间到用户空间的来回拷贝。
- 分区分段:Kafka 的 message 是按 topic 分类存储的,topic 中的数据又是按照 partition 存储到不同 broker 节点。每个 partition 对应操作系统上的一个文件夹,partition 实际上又是按照 segment 分段进行存储的。通过这种分区分段的设计,Kafka 的message 消息实际上是分布式存储在一个个小的 segment 中的,每次文件操作也是直接操作的 segment。