前言
本以为Kafka和RabbitMQ一样,只是个消息队列而已,但进行初步了解发现,它不仅仅是消息队列还是流式处理平台,一旦跟大数据挂钩,除了高级就是高级了。但是,Kafka在众多MQ之中,仍能夺得一席之地,是因为它恐怖的高吞吐率,学习学习。
所以先给自己立个Flag,要把Kafka学的跟MySQL和Zookeeper一样透!
安装
Kafka使用Scala和Java语言写的,可以从官网下载
集群配置
Kafka一般都是以集群的方式出现,并且是用Zookeeper进行管理的。体系架构图:
主要配置config/server.properties
文件中的参数,核心参数介绍:
# 集群中Kafka的唯一标识
broker.id=0
# 配置Kafka本机的ip和port,用于对外提供服务
listeners=PLAINTEXT://127.0.0.1:9092
# 日志目录
log.dirs=/tmp/kafka-logs
# zk配置,zk 集群用逗号","分隔
zookeeper.connect=localhost:2181
注意:配置Kafka集群还需要安装Zookeeper和JDK环境
应用场景
- 用户活动追踪
- 日志聚合
- 削峰限流
特点
在那么MQ中Kafka还能这么出众,是因为Kafka拥有非常高的高吞吐率。Kafka将所有消息写入低速大容量的硬盘,理论上写入硬盘是很慢的,但是Kafka使用了以下几种方式:
- 顺序读写,在MySQL的redo log中介绍了,顺序读写比随机读写速度快多了
- 零拷贝,数据从一个区域拷贝到另一个区域不需要CPU参与,这样生产者和消费者操作数据就快了
- 批量发送,可以将数据先缓存到内存中批量发送,可以配置多种策略
- 消息压缩,Kafka可以对数据进行压缩处理,便于网络传输,这是很多中间件都会采用的方案,比如Redis的RDB文件
Kafka使用
官网写的非常详细,建议参考。
客户端命令使用
在Kafka的bin目录下,为我们提供了很多的工具脚本,这些脚本的功能从他们的命名上就可以看出其功能。
# 以守护进程方式启动
./kafka-server-start.sh -daemon ../config/server.properties
# 关闭
./kafka-server-stop.sh
# 在本地Kafka创建一个topic名称为test
# --replication-factor 副本因子,即topic需要的副本数量
# --partitions 分区数,一般和集群中的主机数量保持一致
bin/kafka-topics.sh --create --bootstrap-server localhost:9092
--replication-factor 1 --partitions 1 --topic test
# 查看127.0.0.1:9092上Kafka的所有topic
bin/kafka-topics.sh --list --bootstrap-server 127.0.0.1:9092
# 删除127.0.0.1:9092上Kafka上名称为test的topic
bin/kafka-topics.sh --delete --bootstrap-server 127.0.0.1:9092 --topic test
# 生产者向topic名为test的发送消息
# 该命令回车后,可以输入要发送的消息
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
# 启动消费者接收生产者topic为test的消息
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092
--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中是没有分区的
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。
<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。