Kafka
Kafka常见概念
名词 | 解释 |
---|---|
Broker | 【节点】一个Kafka节点就是一个Broker,一个和多个Broker可以组成一个Kafka集群 |
Topic | 【主题】Kafka根据Topic对消息进行归类,发布到Kafka集群的每套消息都需要指定一个topic, topic是一个逻辑概念,物理上是不存在的 |
Producer | 【生产者】用于向Kafka中发送消息 |
Consumer | 【消费者】从Kafka中获取消息 |
Consumer Group | 【消费组】每个Consumer都会归属于一个消费组,一条消息可以同时被多个不同的消费组消费,但是只能被一个消费组中的消费者消费 |
Partition | 【分片】物理上的概念,可以将一个topic上的数据拆分成多份放到Partition中,每个Partition内部的消息是有序的 |
Kafka常见指令
- 创建主题
./kafka-topics.sh --bootstrap-server localhost:9092 --create --topic dawn--partitions 1 --replication-factor 1
- 查看主题
./kafka-topics.sh --list --bootstrap-server localhost:9092
- 开启消费生产端
./kafka-console-producer.sh --topic dawn --bootstrap-server localhost:9092
- 开启消费消费端
./kafka-console-consumer.sh --topic dawn --bootstrap-server localhost:9092
./kafka-console-consumer.sh --topic dawn --bootstrap-server localhost:9092 --from-begining
消息是会被存储在Kafka中的文件里的,并且是顺序存储的,消息有偏移量的概念,所以我们可以指定偏移量去读取某个位置的信息。
单播消息
group.id相同
一个消费者组中,只会有一个消费者能够消费到某个Topic的消息。
首先,打开两个窗口,分别执行如下语句开启消费端,那么就在“museGroup1″消费组里创建了两个Consumer
./kafka-console-consumer.sh --topic dawn --bootstrap-server localhost:9092 --consumer-property group.id=museGroup1
然后,Producer端发送三条消息,我们发现,只有一个Consumer收到了消息
### 多播消息
group.id相同
当业务场景中,需要同一个Topic下的消息被多个消费者消费,那么我们可以采用创建多个消费组的方式,那么这种方式就是多播消息
打开两个窗口,分别执行如下指令:
./kafka-console-consumer.sh --topic muse --bootstrap-server localhost:9092 --consumer-property
group.id=museGroup1
./kafka-console-consumer.sh --topic muse --bootstrap-server localhost:9092 --consumer-property
group.id=museGroup2
最后,Producer端发送三条消息,我们发现,两个Consumer都收到了消息。如下所示:
消费组
查看当前主题下有哪些消费组
./kafka-consumer-groups.sh –bootstrap-server localhost:9092 –list
查看消费组中的具体信息
./kafka-consumer-groups.sh –bootstrap-server localhost:9092 –group museGroup1 –describe
其中,展示出的信息有如下含义:
CURRENT-OFFSET: 当前消费组已消费消息的偏移量
LOG-END-OFFSET: 主题对应分区消息的结束偏移量(水位–HW)
LAG: 当前消费组堆积未消费的消息数量
__conusmer_offsets_N
Kafka默认创建了一个拥有50个分区的主题,名称为: “__consumer_offsets”。
Consumer会将消费分区的Offset提交给Kafka内部Topic: __consumer_offsets,提交过去的时候,[key] = consumerGroupID+topic+分区号,[value]=当前offset的值。
Kafka会定期清理Topic里的信息,最后就保留最新的那条数据。可以通过如下公式确定Consumer消费的Offset要提交到哪个__Consumer_offsets
hash(consumerGroupID)%主题”__Consumer_offsets”的分区数量
稀疏索引
分区
一个主题中的消息量是非常大的,因此可以通过分区的设置,来分布式存储这些消息。并且分区也可以提供消息并发存储的能力。
副本
如果分片挂掉了,数据就丢失了。那么为了提高系统的可用性,我们可以把分片复制多个,这就是副本了。但是,副本的产生,也会随之带来数据一致性的问题,即: 有的副本写数据成功,但是有的副本写数据失败。
-
Leader
Kafka的读写操作都发生在Leader上,Leader负责把数据同步给follower
当Leader挂掉了,那么经过主从选举,从多个follower中选举产生一个新的Leader -
Follower
follower接收Leader同步过来的数据,它不提供读写(主要是为了保证多副本数据与消费的一致性)
多分区 & 多副本
为名称为muse-rp的Topic创建
两个分区 (–partitions)
三个副本 (–replication-factor)
多分区消费组
一个partition只能被一个消费组中的一个消费者消费,这样设计的目的是保证消息的有序性,但是在多个partition的多个消费者消费的总顺序性是无法得到保证的
partition的数量决定了消费组中Consumer的数量,建议同一个消费组中的Consumer数量不要超过partition的数量,否则多余的Consumer就无法消费消息了。
但是,如果消费者挂掉了,那么就会出发rebalance机制,会由其他消费者来消费该分区
Controller
Kafka集群中的Broker在ZK中创建临时序号节点,序号最小的节点也就是最先创建的那个节点,将作为集群的Controller, 负责管理整个集群中的所有分区和副本的状态。
Controller控制器的作用如下:
当某个分区的leader副本出现故障时,有控制器负责为该分区选举出新的Leader副本。
当检测到某个分区的ISR集合发生变化时,由控制器负责通知所有Broker更新其元数据信息。
当使用kafka-topics.sh脚本为某个topic增加分区数量时,同样还是由控制器负责让新分区被其他节点感知到
Rebalance机制
当消费者没有指明分区消费时,消费组里的消费者和分区关系发生了变化,那么就会出发rebalance机制。这个机制会重新调整消费者消费哪个分区
在出发rebalance机制之前,消费者消费哪个分区有三种策略
- range
通过公式来计算某个消费者消费哪个分区 - 轮询
大家轮流对分区进行消费 - sticky
在触发rebalance之后,在消费者消费的原分区不变的基础上进行调整j’j’j’j’h’h’h’h’h’h’h’j’g’g
HW和LEO
HW 俗称高水位,取一个partition对应的ISR中最小的LEO作为HW
Consumer最多只能消费到HW所在的位置,每个副本都有HW,Leader和Follower各自负责自己的HW的状态
对于Leader新写入的信息,Consumer不能立刻消费,Leader会等待该消息被所有ISR 中的副本同步后更新HW,此时消息才能被Consumer所消费,这样就能保证如果Leader所在的Broker失效,该消息仍然可以从新选举的Leader中获取。
具体逻辑请看下一张图,
高频面试题
-
如何防止消息的重复消费
消息生成md5然后保存到MySQL或者Redis中,在处理消息之前先查MySQL或者Redis,进行判断看是否已经消费过 -
如何做到顺序消费
Producer在向Broker发送消息时要保证消息只能被发送到一个Partition中,Kafka默认一个Partition只能被一个Consumer消费。其他特殊情况需要视情况而定 -
如何解决消息积压的问题
- 创建新的topic并配置更多数量的分区,将积压消息的topic消费者逻辑改为直接把消息打入新的topic,将消费逻辑写在新的topic的消费者中
- 在消费者里面使用多线程完成积压问题
-
如何实现延迟队列
创建一个伪队列,然后再在自己的代码里面拉取伪队列的消息。条件不满足就暂停消费。条件满足后就发送到正确的队列里面 -
Kafka如何做到单机上百万的高吞吐量呢?
- 页面缓存技术
- 磁盘顺序写
- 零拷贝技术
不用把数据往用户进程和Socket缓存里面copy
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/202474.html