Kafka

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。Kafka,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

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
    非零拷贝技术
    零拷贝技术

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/202474.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!