文章目录
0 前置
需要了解zookeeper:Kafka使用ZooKeeper管理自己的元数据配置。
需要了解消息队列:Kafka是一个消息队列
1 Kafka入门
首先我们得去官网看看是怎么介绍Kafka的:
https://kafka.apache.org/intro
下面是中文翻译和总结:
https://scala.cool/2018/03/learning-kafka-1/
2 什么是生产者、消费者
Kafka是一个消息队列,把消息放到队列里边的叫 生产者 ,从队列里边消费的叫 消费者 。
3 什么是topic
一个消息中间件,队列不单单只有一个,我们往往会有多个队列,而我们生产者和消费者就得知道:把数据丢给哪个队列,从哪个队列消费。我们需要给队列取名字,叫做 topic (相当于数据库里边 表 的概念)
给队列取名字,专业名词叫topic
现在我们给队列取了名字以后,生产者就知道往哪个队列丢数据了,消费者也知道往哪个队列拿数据了。我们可以有多个生产者 往同一个队列(topic) 丢数据,多个消费者 往同一个队列(topic) 拿数据
4 什么是partition
为了提高一个队列(topic)的 吞吐量 ,Kafka会把topic进行分区( Partition )
Kafka分区
所以,生产者实际上是往一个topic名为Java3y中的分区( Partition )丢数据,消费者实际上是往一个topic名为Java3y的分区( Partition )取数据
5 什么是Broker
生产者和消费者实际上操作的是分区
一台Kafka服务器叫做 Broker ,Kafka集群就是多台Kafka服务器
一个topic会分为多个partition,实际上partition会 分布 在不同的broker中,举个例子:
由此得知:Kafka是天然分布式的
6 Kafka如何保证高可用
现在我们已经知道了往topic里边丢数据,实际上这些数据会分到不同的partition上,这些partition存在不同的broker上。分布式肯定会带来问题:“万一其中一台broker(Kafka服务器)出现网络抖动或者挂了,怎么办?”
Kafka是这样做的:我们数据存在不同的partition上,那kafka就把这些partition做 备份 。比如,现在我们有三个partition,分别存在三台broker上。每个partition都会备份,这些备份散落在 不同的broker上。
红色块的partition代表的是主分区,紫色的partition块代表的是备份分区。生产者往topic丢数据,是与主分区交互,消费者消费topic的数据,也是与主分区交互。
备份分区仅仅用作于备份,不做读写。如果某个Broker挂了,那就会选举出其他Broker的partition来作为主分区,这就实现了高可用。
7 Kafka持久化是存在哪里,读写有什么亮点
当生产者把数据丢进topic时,我们知道是写在partition上的,那partition是怎么将其持久化的呢?(不持久化如果Broker中途挂了,那肯定会丢数据嘛)。
Kafka是将partition的数据写在磁盘的(消息日志),不过Kafka只允许追加写入(顺序访问),避免缓慢的随机 I/O 操作。
Kafka也不是partition一有数据就立马将数据写到磁盘上,它会先缓存一部分,等到足够多数据量或等待一定的时间再批量写入(flush)。
8 Kafka的消费者组
既然数据是保存在partition中的,那么消费者实际上也是从partition中取数据。
生产者可以有多个,消费者也可以有多个。像上面图的情况,是一个消费者消费三个分区的数据。多个消费者可以组成一个消费者组。
本来是一个消费者消费三个分区的,现在我们有消费者组,就可以每个消费者去消费一个分区(也是为了提高吞吐量)
一些说明:
- 如果消费者组中的某个消费者挂了,那么其中一个消费者可能就要消费两个partition了
- 如果只有三个partition,而消费者组有4个消费者,那么一个消费者会空闲
- 如果多加入一个消费者组,无论是新增的消费者组还是原本的消费者组,都能消费topic的全部数据。(消费者组之间从逻辑上它们是独立的)
9 offset是什么,有什么用,保存在哪里
生产者往topic里丢数据是存在partition上的,而partition持久化到磁盘是IO顺序访问的,并且是先写缓存,隔一段时间或者数据量足够大的时候才批量写入磁盘的。
消费者在读的时候也很有讲究:正常的读磁盘数据是需要将内核态数据拷贝到用户态的,而Kafka 通过调用sendfile()直接从内核空间(DMA的)到内核空间(Socket的),少做了一步拷贝的操作。
如果一个消费者组中的某个消费者挂了,那挂掉的消费者所消费的分区可能就由存活的消费者消费。那存活的消费者是需要知道挂掉的消费者消费到哪了,不然怎么玩。
这里要引出offset了,Kafka就是用offset来表示消费者的消费进度到哪了,每个消费者会都有自己的offset。说白了offset就是表示消费者的消费进度。
在以前版本的Kafka,这个offset是由Zookeeper来管理的,后来Kafka开发者认为Zookeeper不合适大量的删改操作,于是把offset在broker以内部topic(__consumer_offsets)的方式来保存起来。
每次消费者消费的时候,都会提交这个offset,Kafka可以让你选择是自动提交还是手动提交。
既然提到了Zookeeper,那就多说一句。Zookeeper虽然在新版的Kafka中没有用作于保存客户端的offset,但是Zookeeper是Kafka一个重要的依赖。
- 探测broker和consumer的添加或移除。
- 负责维护所有partition的领导者/从属者关系(主分区和备份分区),如果主分区挂了,需要选举出备份分区作为主分区。
- 维护topic、partition等元配置信息
参考:https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247486160&idx=1&sn=95b961002664e54ca33bf22997594d1d&chksm=ebd74bd1dca0c2c7494c9184e013cb4171743bc7e1b2ee6ddda01ed4eb3291a3eedfed908022&token=711412693&lang=zh_CN#rd