带你快速了解Kafka

📅 发布时间:2026/7/8 9:50:42 👁️ 浏览次数:
带你快速了解Kafka
提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档带你快速了解Kafka概念生产者往kafka中写数据的流程生产者往不存在的topic里写入数据会发生什么kafka会把消息持久化到硬盘中在硬盘上是如何组织的kafka的存储策略旧的数据何时被删除查找数据的底层流程消费者获取数据的两种模式消息队列的两种通信模式概念kafka中存的是消息message/事件消息是一种通知机制关键点引入消息队列平衡了生产者与消费者的速度差有延迟但是可以保命-可用性削峰填谷1、削峰把峰值流量用消息中间件缓存下来后面可以慢慢处理有延迟但可以报名2、填谷在流量的低谷期提前处理一些任务或者说处理哪些峰值流量kafka -------消息队列管理软件broker-------》kafka集群中的一个kafka节点/实例topic主题----》kafka中创建出的消息队列逻辑层面实际队列底层用的分区每个broker可以创建多个partition分区实际的队列--------》数据分片多个分区来负载压力提高该topic的吞吐率性能提升但是不是越大越好元数据维护压力变大每个分区都是多副本----------》高可用一个分区的副本分成两类角色主从leader读写都与leader打交道多个follower主动与leader同步数据一旦leader挂掉kafka会选出一个follower成新的leaderfollower和leader绝对是在不同的机器每个副本会分布在不同的broker不能在同一个broker所以副本数 broker数生产者与消费者都是操作topictopic是逻辑层的队列而底层实际的队列是分区partition架构如下图所示生产者基于某种编程语言编写程序负责生产消息然后丢给broker中的topic消费者可以一个单独一个消费者也可以把多个消费者归纳到一个消费组同一个组内的消费者可以消费同一个topic下不同分区的消息同一个组内的多个消费者不能同时消费一个分区内的消息当我的topic下有5分区时一个消费组中应该放5个消费者如果只放1个消费者消费能力太低如果放了3个消费者消费能力不高如果放了7个消费者有两个消费处于空闲状态zookeeper存储kafka的集群源数据库集群中的每个broker节点都要注册到zookeeper中生产者往kafka中写数据的流程生产者-----》topic主题逻辑层面的队列----》多个分区partition逻辑层面的队列写入流程先从多个分区中选出一个分区有三种选择策略程序自己明确指定要写到哪个分区中就以指定的为准程序没有明确指定要写到那个分区中但是设置了数据的key那kafka会根据key算出 一个hash值来对应到具体的partition程序没有明确指定要写到那个分区中也没有设置数据的key则会轮询出一个partition从分区的多个副本中找出leader生产发送消息给分区中的leaderleader收到消息之后将消息存入本地硬盘所有follower从leader拉取pull数据到自己本地完成数据同步然后返回ack确认信息给leaderleader收到所有follower的ack确认之后就会发送ack确认信息给生产者完成写入流程生产者写数据的三种ack策略acks0写入性能的极端生产者提交完写请求后则结束不需要等任何的ack异步写写速度最快但数据最不安全acks1兼顾性能与数据安全生产者要等到leader写完即可不需等follower同步完毕acksall数据安全的极端生产者写入流程的完成要一直等到所有follower都完成同步并回复ack之后才算结束写速度最慢但是数据最安全生产者往不存在的topic里写入数据会发生什么如果auto.create.topics.enable设置为true默认值当生产者发送消息至不存在的主题时Kafka将自动创建该主题并接收消息分区和副本的数量根据默认配置都是1。如果auto.create.topics.enable设置为false当生产者发送消息至不存在的主题时Kafka将不会创建该主题而是会返回错误此时生产者通常会捕捉到此错误并作出相应处理。kafka会把消息持久化到硬盘中在硬盘上是如何组织的mysql管理软件--------》库----------------分库分表------------------》 文件夹组织了文件kafka管理软件--------》topic主题------》包含了多个分区-------------》一个分区对应一个文件夹组织了文件文件的组织方式把整体一份大数据切成多段去存每一段称之为一个segment每一个segment都会以自己存放的message消息的初始offset号-1来命名每一个segment包含三个关键文件index和timeindex文件为索引文件用于检索消息。----------》稀疏索引log文件就实际是存储message的地方每条消息都有自己的编号称之为offset对一个message来说关键的构成offset 逻辑顺序占用的到第几个字节物理位置如下图这个 partition 有三组 segment 文件每个 log 文件的大小是一样的但是存储的 message 数量是不一定相等的每条的 message 大小不一致。文件的命名是以该 segment 最小 offset 来命名的如000.index存储 offset 为 0368795 的消息。因为下一个 segment2 是从 368796 开始的可以看出数据是按序依次写入的。kafka 就是利用分段索引的方式来解决查找效率的问题。kafka写磁盘采用的是顺序写而不是随机写topic中的数据是有序还是无序站在所有partition的角度去看数据是无序的具体指的是消息不是按照分区的编号去存的而是会根据分区的三种选择策略来选择分区写入单某一个partition中的数据是有序的kafka的存储策略旧的数据何时被删除基于时间默认配置是168小时7天。基于大小默认配置是1073741824。查找数据的底层流程假如现在需要查找一个offset为368801的message先找到offset为368801的message所在的segment文件利用二分法查找快速缩小查找范围这里找到的就是在第二个segment文件。打开要找的segment中的.index文件也就是368796.index文件该文件起始偏移量为3687961我们要查找的是相对offset为368801的message在该index内的偏移量为368801 - 368796 - 1 5所以这里要查找的相对offset为5。由于该文件采用的是稀疏索引的方式存储着相对offset及对应message物理偏移量的关系如上图稀疏的意思指的是不是每个message都在xxx.index而是每隔一定数量的message才对应一个索引这样稀疏的记录方式大大减少了索引文件的大小适合高效查找如上稀疏索引4对应物理位置256字节这256字节存的是offset为368800的message你要找下一条数据那据此往下偏移1即可稀疏索引会直接寻找小于或等于目标相对偏移量的最大条目而不是先尝试精确匹配目标相对偏移量。即找相对偏移量 5 的最大条目即相对偏移量 4用二分查找假设根据二分查找找到的相对offset为4的索引对应的message存储的物理偏移位置为256。那就会打开数据文件从位置为256的那个地方开始顺序扫描直到找到offset为368801的那条Message。假如现在需要查找一个offset为368801的message简洁版根据待查找的368801、以及segment的文件名来确定查找范文处于那个segment快速缩小查找范围假设确定在segment2中计算出待查找的offset的相对位置368801 - 368796 - 1 5索引的结构是稀疏索引稀疏索引每隔几条才会创建一个索引采用二分法来确定待查找索引所处的稀疏索引的区间然后根据后面的物理位置快速定位log文件的中起始位置然后向后查找你的offset就能找到具体的某一条数据关键点—》缩小查找范围总结这套机制是建立在offset为有序的基础上利用segment有序offset稀疏索引二分查找顺序查找等多种手段来高效的查找数据核心思路减少io次数消费者获取数据的两种模式先说结论push消费模式只适合于消费速度远大于生产速度的场景如果是大流量并发场景基本还是以Pull消费为主。消费者主动拉取—》pull1、消费者主动拉取—》pull优点消费者可能综合自身处理能力来主动获取消息避免消息过载缺点会牺牲掉实时性需要消费者定期轮询查询队列2、消息队列推送消息给消费者----》push优点实时性强有消息则立即推送缺点只适用于消费能力远远超过消息的产生速度的场景kafka采用的是拉取的方式大流量并发场景基本还是以Pull消费为主消息队列的两种通信模式点对点模式消息在消息队列中存储并且每条消息只有一个消费者来消费发布订阅模式消息被发送到主题topic中然后被所有订阅该主题的消费者共享和消费总结kafka采用的模式kafka其实融合了点对点发布订阅的优点且采用拉取的方式点对点一个消费中的多个线程不能同时消费一个partition意味着一条消息同一时间只能被一个消费者处理发布订阅生产者将消息发布到特定的主题消费者订阅他们感兴趣的主题并消费消息一旦有消息来则会收到通知然后采用pull方式拉取消息