Kafka的学习笔记

本文详细介绍了Kafka,包括它的核心组件如Topic、Producer、Consumer和Broker,以及Kafka的工作方式,如消息分发、Consumer与topic的关系、消息的顺序性和存储机制。Kafka作为分布式消息队列,提供高吞吐量、低延迟的数据处理平台,常用于流式计算中的数据缓存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、Kafka是什么

在流式计算中,Kafka一般用来缓存数据,Storm通过消费Kafka的数据进行计算。

KAFKA + STORM +REDIS

1.Apache Kafka是一个开源消息系统,由Scala写成。是由Apache软件基金会开发的一个开源消息系统项目。
2.Kafka最初是由LinkedIn开发,并于2011年初开源。2012年10月从Apache Incubator毕业。该项目的目标是为处理实时数据提供一个统一、高吞吐量、低等待的平台。
3.Kafka是一个分布式消息队列:生产者、消费者的功能。它提供了类似于JMS的特性,但是在设计实现上完全不同,此外它并不是JMS规范的实现。

  1. Kafka对消息保存时根据Topic进行归类,发送消息者称为Producer,消息接受者称为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)称为broker。
  2. 无论是kafka集群,还是producer和consumer都依赖于zookeeper集群保存一些meta信息,来保证系统可用性。

2.Kafka核心组件

  1. Topic :消息根据Topic进行归类
  2. Producer:发送消息者
  3. Consumer:消息接受者
  4. broker:每个kafka实例(server)
  5. Zookeeper:依赖集群保存meta信息

Kafka整体结构图在这里插入图片描述

3.Kafka名词解释和工作方式

  1. Producer :消息生产者,就是向kafka broker发消息的客户端。
  2. Consumer :消息消费者,向kafka broker取消息的客户端
  3. Topic :我们可以理解为一个队列(queue)。
  4. Consumer Group(CG):这是kafka用来实现一个topic消息的广播(发给所有的consumer)和单播(发给任意一个consumer)的手段。一个topic可以有多个CG。topic的消息会复制(不是真的复制,是概念上的)到所有的CG,但每个partition只会把消息发给该CG中的一个consumer。如果需要实现广播,只要每个consumer有一个独立的CG就可以了。要实现单播只要所有的consumer在同一个CG。用CG还可以将consumer进行自由的分组而不需要多次发送消息到不同的topic。
  5. Broker :一台kafka服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic。
  6. Partition:为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)。kafka只保证按一个partition中的顺序将消息发给consumer,不保证一个topic的整体(多个partition间)的顺序。
  7. Offset:kafka的存储文件都是按照offset.kafka来命名,用offset做名字的好处是方便查找。例如你想找位于2049的位置,只要找到2048.kafka的文件即可。当然the
    first offset就是00000000000.kafka。

4.Consumer与topic关系

本质上kafka只支持Topic;

  1. 每个group中可以有多个consumer,每个consumer属于一个consumer group;
    通常情况下,一个group中会包含多个consumer,这样不仅可以提高topic中消息的并发消费能力,而且还能提高"故障容错"性,如果group中的某个consumer失效那么其消费的partitions将会有其他consumer自动接管。

  2. 对于Topic中的一条特定的消息,只会被订阅此Topic的每个group中的其中一个consumer消费,此消息不会发送给一个group的多个consumer, 那么一个group中所有的consumer将会交错的消费整个Topic,每个group中consumer消息消费互相独立,我们可以认为一个group是一个"订阅者"。

  3. 在kafka中,一个partition中的消息只会被group中的一个consumer消费(同一时刻);一个Topic中的每个partition,只会被一个"订阅者"(group)中的一个consumer消费,不过一个consumer可以同时消费多个partition中的消息。

  4. kafka的设计原理决定,对于一个topic,同一个group中不能有多于partition个数的consumer同时消费,否则将意味着某些consumer将无法得到消息。

  5. kafka只能保证一个partition中的消息被某个consumer消费时是顺序的;事实上,从Topic角度来说,当有多个partitions时,消息仍不是全局有序的。

5.Kafka消息的分发

Producer客户端负责消息的分发

  1. kafka集群中的任何一个broker都可以向producer提供metadata信息,这些metadata中包含"集群中存活的servers列表"/"partitions,leader列表"等信息;
  2. 当producer获取到metadata信息之后, producer将会和Topic下所有partition
    leader保持socket连接;
  3. 消息由producer直接通过socket发送到broker,中间不会经过任何"路由层",事实上,消息被路由到哪个partition上由producer客户端决定;
    比如可以采用"random"“key-hash”"轮询"等,如果一个topic中有多个partitions,那么在producer端实现"消息均衡分发"是必要的。
  4. 在producer端的配置文件中,开发者可以指定partition路由的方式。

Producer消息发送的应答机制
设置发送数据是否需要服务端的反馈,有三个值0,1,-1

0: producer不会等待broker发送ack (Kafka的ack机制,指的是producer的消息发送确认机制)

1: 当leader接收到消息之后发送ack

-1: 当所有的follower都同步消息成功后发送ack
request.required.acks=0

6.Consumer的负载均衡

当一个group中,有consumer加入或者离开时,会触发partitions负载均衡.负载均衡的最终目的,是提升topic的并发消费能力,步骤如下:

  1. 假如topic1,具有如下partitions: P0,P1,P2,P3
  2. 加入group中,有如下consumer: C1,C2
  3. 首先根据partition索引号对partitions排序: P0,P1,P2,P3
  4. 根据consumer.id排序: C1=0,C2=1,即0,1
  5. 计算倍数: M = [P0,P1,P2,P3].size / [C1,C2].size,本例值M=2(向上取整)
  6. 然后依次分配partitions: C1 = [P0,P1],C2=[P2,P3],即Ci = [P(i * M),P((i + 1)
    • M -1)],其中i为consumerID

在这里插入图片描述

7.kafka文件存储机制

7.1、Kafka文件存储基本结构

  1. 在Kafka文件存储中,同一个topic下有多个不同partition,每个partition为一个分区,partiton命名规则为topic名称+有序序号,第一个partiton序号从0开始,序号最大值为partitions数量减1。

  2. 每个partition(分区)相当于一个巨型文件被平均分配到多个大小相等segment(段)数据文件中。但每个段segment file消息数量不一定相等,这种特性方便old segment file快速被删除。默认保留7天的数据。
    . 在这里插入图片描述

  3. 每个partiton只需要支持顺序读写就行了,segment文件生命周期由服务端配置参数决定。(什么时候创建,什么时候删除)
    在这里插入图片描述
    数据有序的讨论?
    一个partition的数据是否是有序的?
    间隔性有序,不连续
    针对一个topic里面的数据,只能做到partition内部有序,不能做到全局有序。

    特别加入消费者的场景后,如何保证消费者消费的数据全局有序的?伪命题。
    只有一种情况下才能保证全局有序?就是只有一个partition。

7.2、Kafka Partition Segment

  1. Segment file组成:由2大部分组成,分别为index file和data
    file,此2个文件一一对应,成对出现,后缀".index"和“.log”分别表示为segment索引文件、数据文件。

  2. Segment文件命名规则:partition全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值。数值最大为64位long大小,19位数字字符长度,没有数字用0填充。

  3. 索引文件存储大量元数据,数据文件存储大量消息,索引文件中元数据指向对应数据文件中message的物理偏移地址。

在这里插入图片描述
3,497:当前log文件中的第几条信息,存放在磁盘上的那个地方
上述图中索引文件存储大量元数据,数据文件存储大量消息,索引文件中元数据指向对应数据文件中message的物理偏移地址。
其中以索引文件中元数据3,497为例,依次在数据文件中表示第3个message(在全局partiton表示第368772个message)、以及该消息的物理偏移地址为497。

segment data file由许多message组成, 物理结构如下

关键字解释说明
8 byte offset在parition(分区)内的每条消息都有一个有序的id号,这个id号被称为偏移(offset),它可以唯一确定每条消息在parition(分区)内的位置。即offset表示partiion的第多少message
4 byte message sizemessage大小
4 byte CRC32用crc32校验message
1 byte “magic"表示本次发布Kafka服务程序协议版本号
1 byte “attributes"表示为独立版本、或标识压缩类型、或编码类型
4 byte key length表示key的长度,当key为-1时,K byte key字段不填
K byte key可选
value bytes payload表示实际消息数据

7.3、Kafka 查找message
读取offset=368776的message,需要通过下面2个步骤查找。

在这里插入图片描述

1.查找segment file

00000000000000000000.index表示最开始的文件,起始偏移量(offset)为1
00000000000000368769.index的消息量起始偏移量为368770 = 368769 + 1
00000000000000737337.index的起始偏移量为737338=737337 + 1
其他后续文件依次类推。
以起始偏移量命名并排序这些文件,只要根据offset 二分查找文件列表,就可以快速定位到具体文件。当offset=368776时定位到00000000000000368769.index和对应log文件。

2.通过segment file查找message

当offset=368776时,依次定位到00000000000000368769.index的元数据物理位置和00000000000000368769.log的物理偏移地址
然后再通过00000000000000368769.log顺序查找直到offset=368776为止。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值