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常见指令

  1. 创建主题
./kafka-topics.sh --bootstrap-server localhost:9092 --create --topic dawn--partitions 1 --replication-factor 1
  1. 查看主题
./kafka-topics.sh --list --bootstrap-server localhost:9092
  1. 开启消费生产端
./kafka-console-producer.sh  --topic dawn --bootstrap-server localhost:9092
  1. 开启消费消费端
./kafka-console-consumer.sh  --topic dawn --bootstrap-server localhost:9092
./kafka-console-consumer.sh  --topic dawn --bootstrap-server localhost:9092 --from-begining

消息是会被存储在Kafka中的文件里的,并且是顺序存储的,消息有偏移量的概念,所以我们可以指定偏移量去读取某个位置的信息。
消费者消费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机制之前,消费者消费哪个分区有三种策略

  1. range
    通过公式来计算某个消费者消费哪个分区
  2. 轮询
    大家轮流对分区进行消费
  3. 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中获取。
具体逻辑请看下一张图,

HW和LEO

高频面试题

  1. 如何防止消息丢失
    要想确保Kafka消息不丢失,Consumer、Producer以及Broker都需要做好各自所负责的部分,Producer需要确保消息成功发送到Broker端,Broker端则要确保消息的成功落盘、多副本、持久化,Consumer端则要自己对自己负责,对于已提交的offset的消息都是自己真正消费过的

  2. 如何防止消息的重复消费
    消息生成md5然后保存到MySQL或者Redis中,在处理消息之前先查MySQL或者Redis,进行判断看是否已经消费过

  3. 如何做到顺序消费
    Producer在向Broker发送消息时要保证消息只能被发送到一个Partition中,Kafka默认一个Partition只能被一个Consumer消费。其他特殊情况需要视情况而定

  4. 如何解决消息积压的问题

  • 创建新的topic并配置更多数量的分区,将积压消息的topic消费者逻辑改为直接把消息打入新的topic,将消费逻辑写在新的topic的消费者中
  • 在消费者里面使用多线程完成积压问题
  1. 如何实现延迟队列
    创建一个伪队列,然后再在自己的代码里面拉取伪队列的消息。条件不满足就暂停消费。条件满足后就发送到正确的队列里面

  2. Kafka如何做到单机上百万的高吞吐量呢?

  • 页面缓存技术
  • 磁盘顺序写
  • 零拷贝技术
    不用把数据往用户进程和Socket缓存里面copy
    非零拷贝技术
    零拷贝技术
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值