前言

本以为Kafka和RabbitMQ一样,只是个消息队列而已,但进行初步了解发现,它不仅仅是消息队列还是流式处理平台,一旦跟大数据挂钩,除了高级就是高级了。但是,Kafka在众多MQ之中,仍能夺得一席之地,是因为它恐怖的高吞吐率,学习学习。

所以先给自己立个Flag,要把Kafka学的跟MySQL和Zookeeper一样透!

安装

Kafka使用Scala和Java语言写的,可以从官网下载

集群配置

Kafka一般都是以集群的方式出现,并且是用Zookeeper进行管理的。体系架构图:
image.png

主要配置config/server.properties文件中的参数,核心参数介绍:

  1. # 集群中Kafka的唯一标识
  2. broker.id=0
  3. # 配置Kafka本机的ip和port,用于对外提供服务
  4. listeners=PLAINTEXT://127.0.0.1:9092
  5. # 日志目录
  6. log.dirs=/tmp/kafka-logs
  7. # zk配置,zk 集群用逗号","分隔
  8. zookeeper.connect=localhost:2181

注意:配置Kafka集群还需要安装Zookeeper和JDK环境

应用场景

  • 用户活动追踪
  • 日志聚合
  • 削峰限流

特点

在那么MQ中Kafka还能这么出众,是因为Kafka拥有非常高的高吞吐率。Kafka将所有消息写入低速大容量的硬盘,理论上写入硬盘是很慢的,但是Kafka使用了以下几种方式:

  1. 顺序读写,在MySQL的redo log中介绍了,顺序读写比随机读写速度快多了
  2. 零拷贝,数据从一个区域拷贝到另一个区域不需要CPU参与,这样生产者和消费者操作数据就快了
  3. 批量发送,可以将数据先缓存到内存中批量发送,可以配置多种策略
  4. 消息压缩,Kafka可以对数据进行压缩处理,便于网络传输,这是很多中间件都会采用的方案,比如Redis的RDB文件

Kafka使用

官网写的非常详细,建议参考。

客户端命令使用

在Kafka的bin目录下,为我们提供了很多的工具脚本,这些脚本的功能从他们的命名上就可以看出其功能。

  1. # 以守护进程方式启动
  2. ./kafka-server-start.sh -daemon ../config/server.properties
  3. # 关闭
  4. ./kafka-server-stop.sh
  5. # 在本地Kafka创建一个topic名称为test
  6. # --replication-factor 副本因子,即topic需要的副本数量
  7. # --partitions 分区数,一般和集群中的主机数量保持一致
  8. bin/kafka-topics.sh --create --bootstrap-server localhost:9092
  9. --replication-factor 1 --partitions 1 --topic test
  10. # 查看127.0.0.1:9092上Kafka的所有topic
  11. bin/kafka-topics.sh --list --bootstrap-server 127.0.0.1:9092
  12. # 删除127.0.0.1:9092上Kafka上名称为test的topic
  13. bin/kafka-topics.sh --delete --bootstrap-server 127.0.0.1:9092 --topic test
  14. # 生产者向topic名为test的发送消息
  15. # 该命令回车后,可以输入要发送的消息
  16. bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
  17. # 启动消费者接收生产者topic为test的消息
  18. bin/kafka-console-consumer.sh --bootstrap-server localhost:9092
  19. --topic test --from-beginning

Kafka相关概念

Topic

主题,在 Kafka 中,消息以topic为单位进行归类。 topic 相当于消息的分类标签,是一个逻辑概念。

Partition

分区,topic 中的消息被分割为一个或多个 partition,它是一个物理概念,对应到系统上就是一个或若干个目录(存在log.dirs)对应命令行中的--partitions

Kafka的分区可以分布在不同的broker上,以此来提供更好的性能。

分区本身是一个 FIFO 的队列,所以分区中的消息是有序的(因为segment是有序的)。但分区间的消息是没有顺序性。要想保证消息的有序性,可以只设置一个分区,这样消息就可以是有序的。一般情况下一个 topic 的分区数量是 broker 数量的整数倍。

Segment

段,当分区中的消息越来越多,将难以维护,因此 将 partition 进一步细分为了若干的 segment,每个 segment 文件的最大大小是相等的,可以通过config/server.properties中的log.segment.bytes属性来设置。(segment文件存在于分区目录下,文件 后缀是.index、.log、.timeindex )。

Broker

Kafka 集群包含一个或多个服务器,每个服务器节点称为一个 broker(一般消息中间件都叫broker,例如RabbitMQ)。
假设某 topic 中具有 N 个分区,集群中共有 M 个 broker。则分区与 broker 间的关系是:

  • 若N>M且N%M=0,则每个broker会平均存储这些分区
  • 若N>M且N%M!=0,则每个broker中的分区是不平均的
  • 若N<M,则会有N台broker中具有一个分区,另外M-N台broker中是没有分区的

image.png

Producer

生产者,即消息的发布者,其会将某 topic 的消息发布到相应的 partition 中。

生产者所生产的消息默认会平均分配到各个分区,但也可以直接指定要写入的分区,也可以根据消息的 key 来计算路由。

Consumer

消费者,可以从 broker 中读取消息。 一个消费者可以消费多个 topic 中的消息。 一个消费者也可以消费同一个 topic 中的多个 partition 中的消息,一个分区中的消息允许多个无关的消费者(指的是不在一个组的消费者)同时消费。

Consumer Group

consumer group 是 Kafka 提供的可扩展且具有容错性的消费者机制。组内可以有多个消费者,它们共享一个公共的 ID,即 group ID。组内的所有消费者会协调在一起平均消费(对分区的消费是平均的,但对于消息的消费不一定是平均的)订阅主题的所有分区。

Kafka 可以保证在稳定状态下,一条消息只能被同一个 consumer group 中的一个 consumer 消费。当然,一个消息可以同时被多个 consumer group 消费。另外,Kafka 还可以保证,在稳定状态下每一个组内 consumer 只会消费某一个或几个特定的 partition。
image.png

  1. <br />

Replicas of partition

分区副本,副本是一个分区的备份,是为了防止消息丢失而创建的分区的备份,对应命令行参数--replication-factor

Partition Leader

每个 partition 有多个副本,其中有且仅有一个作为 Leader,其它的作为备份使用,是主备关系。Leader 是当前负责消息读写 的 partition。即所有读写操作只能发生于 Leader 分区上。

Leader 宕机后,Broker Controller 会从 Follower 中选举出一个新的 Leader。

Partition Follower

所有 Follower 都需要从 Leader 中同步消息,Follower 与 Leader 始终保持消息同步,相对于Leader来说会有一点点滞后。

AR

Assigned Replicas,分区中所有副本统称为AR,AR = ISR + OSR。

ISR

In-Sync Replicas,副本同步列表。它是由所有与 Leader 副本保持一定程度的副本共同组成(包括 Leader 副本)。ISR 是 AR 集合中的一个子集。

Leader 副本复制维护和跟踪 ISR 集合中所有 follower 副本的滞后状态,当 follower 副本滞后太多或失效时,就把它从 ISR 集合汇总剔除。

作用:
当 Leader 挂了,只有在 ISR 集合中的副本才有资格被选举为新的 Leader(但这一规定也可以通过参数配置来改变)

OSR

Out-of-Sync-Replicas,由与 Leader 副本同步滞后过多的副本(不包括 Leader 副本)共同组成。OSR 也是 AR 集合中的一个子集。

OSR 中滞后的副本如果追上了 Leader 副本,那么 Leader 副本会把它从 OSR 转移到 ISR中。

HW

高水位,High Watermark。它标识了一个特定的消息偏移量 offset,消费者只能拉取到这个 offset 之前的消息。

LEO

Log Start Offset ,它标识当前日志文件中下一条待写入消息的 offset。

参考资料