Kafka(一)基础知识

本文概述了Kafka的关键特性,包括高吞吐低延迟、可扩展性、持久可靠、容错机制、高并发,以及其组件(Broker、Producer、Consumer和Topic)的功能。重点介绍了持久化存储、传输效率、无状态Broker、交付保证、副本管理和分布式协调。

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

1.Kafka的特性

  • 高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒
  • 可扩展性:kafka集群支持热扩展
  • 持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失
  • 容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)
  • 高并发:支持数千个客户端同时读写

2.基本组件

  • Broker:每一台机器叫一个Broker

  • Producer:日志消息生产者,用来写数据

    • 生产者可以发布数据到它指定的topic中,并可以指定在topic里哪些消息分配到哪些分区(比如简单的轮流分发各个分区或通过指定分区语义分配key到对应分区)。

    • 生产者直接把消息发送给对应分区的broker,而不需要任何路由层。

    • 批处理发送,当message积累到一定数量或等待一定时间后进行发送。

  • Consumer:消息的消费者,用来读数据

    • 一种更抽象的消费方式:消费组(consumer group)

    • 该方式包含了传统的queue和发布订阅方式

      • 首先消费者标记自己一个消费组名。消息将投递到每个消费组中的某一个消费者实例上。

      • 如果所有的消费者实例都有相同的消费组,这样就像传统的queue方式。

      • 如果所有的消费者实例都有不同的消费组,这样就像传统的发布订阅方式。

      • 消费组就好比是个逻辑的订阅者,每个订阅者由许多消费者实例构成(用于扩展或容错)。

    • 相对于传统的消息系统,kafka拥有更强壮的顺序保证。

    • 由于topic采用了分区,可在多Consumer进程操作时保证顺序性和负载均衡。

  • Topic:不同消费者去指定的Topic中读,不同的生产者往不同的Topic中写

    • 一个Topic是一个用于发布消息的分类或feed名,kafka集群使用分区的日志,每个分区都是有顺序且不变的消息序列。

    • commit的log可以不断追加。消息在每个分区中都分配了一个叫offset的id序列来唯一识别分区中的消息。

    • 无论发布的消息是否被消费,kafka都会持久化一定时间(可配置)。

    • 在每个消费者都持久化这个offset在日志中。通常消费者读消息时会使offset值线性的增长,但实际上其位置是由消费者控制,它可以按任意顺序来消费消息。比如复位到老的offset来重新处理。

    • 每个分区代表一个并行单元。

  • Partition:新版本才支持Partition,在Topic基础上做了进一步区分分层

Kafka内部是分布式的、一个Kafka集群通常包括多个Broker

负载均衡:将Topic分成多个分区,每个Broker存储一个或多个Partition

多个Producer和Consumer同时生产和消费消息 

一个生产者可以有多个topic

3.Kafka特性

3.1.持久化

Kafka存储布局简单:Topic的每个Partition对应一个逻辑日志(一个日志为相同大小的一组分段文件)

每次生产者发布消息到一个分区,代理就将消息追加到最后一个段文件中。当发布的消息数量达到设定值或者经过一定的时间后,段文件真正flush磁盘中。写入完成后,消息公开给消费者。

与传统的消息系统不同,Kafka系统中存储的消息没有明确的消息Id。

消息通过日志中的逻辑偏移量来公开。

3.2.传输效率

        生产者提交一批消息作为一个请求。消费者虽然利用api遍历消息是一个一个的,但背后也是一次请求获取一批数据,从而减少网络请求数量。

        Kafka层采用无缓存设计,而是依赖于底层的文件系统页缓存。这有助于避免双重缓存,及即消息只缓存了一份在页缓存中。同时这在kafka重启后保持缓存warm也有额外的优势。因kafka根本不缓存消息在进程中,故gc开销也就很小。

        zero-copy:kafka为了减少字节拷贝,采用了大多数系统都会提供的sendfile系统调用。

3.3.无状态的Broker

        Kafka代理是无状态的:意味着消费者必须维护已消费的状态信息。这些信息由消费者自己维护,代理完全不管。这种设计非常微妙,它本身包含了创新

        从代理删除消息变得很棘手,因为代理并不知道消费者是否已经使用了该消息。Kafka创新性地解决了这个问题,它将一个简单的基于时间的SLA应用于保留策略。当消息在代理中超过一定时间后,将会被自动删除。

        这种创新设计有很大的好处,消费者可以故意倒回到老的偏移量再次消费数据。这违反了队列的常见约定,但被证明是许多消费者的基本特征。

3.4.交付保证(消息传送机制)

        Kafka默认采用at least once的消息投递策略。即在消费者端的处理顺序是获得消息->处理消息->保存位置。这可能导致一旦客户端挂掉,新的客户端接管时处理前面客户端已处理过的消息。

        三种保证策略:

        –At most once 消息可能会丢,但绝不会重复传输

        –At least one 消息绝不会丢,但可能会重复传输

        –Exactly once 每条消息肯定会被传输一次且仅传输一次

3.5.副本管理

        kafka将日志复制到指定多个服务器上。

        副本的单元是partition。在正常情况下,每个分区有一个leader和0到多个follower。

        leader处理对应分区上所有的读写请求。分区可以多于broker数,leader也是分布式的。

        follower的日志和leader的日志是相同的,follower被动的复制leader。如果leader挂了,其中一个follower会自动变成新的leader.

3.6.分布式协调

        由于kafka中一个topic中的不同分区只能被消费组中的一个消费者消费,就避免了多个消费者消费相同的分区时会导致额外的开销(如要协调哪个消费者消费哪个消息,还有锁及状态的开销)。kafka中消费进程只需要在代理和同组消费者有变化时时进行一次协调(这种协调不是经常性的,故可以忽略开销)。

3.6.1.kafka使用zookeeper做以下事情:

  1. 探测broker和consumer的添加或移除。
  2. 当1发生时触发每个消费者进程的重新负载。
  3. 维护消费关系和追踪消费者在分区消费的消息的offset。

4.kafka和JMS(Java Message Service)实现(activeMQ)的不同

        即使消息被消费,消息仍然不会被立即删除.日志文件将会根据broker中的配置要求,保留一定的时间之后删除;比如log文件保留2天,那么两天后,文件会被清除,无论其中的消息是否被消费.kafka通过这种简单的手段,来释放磁盘空间,以及减少消息消费之后对文件内容改动的磁盘IO开支。

        Kafka不会像其他 JMS 队列那样需要得到消费者的确认,这是Kafka的一个独特之处

5.offset与consumer

        对于consumer而言,它需要保存消费消息的offset,对于offset的保存和使用,有consumer来控制;当consumer正常消费消息时,offset将会"线性"的向前驱动,即消息将依次顺序被消费.事实上consumer可以使用任意顺序消费消息,它只需要将offset重置为任意值。

        kafka集群几乎不需要维护任何consumer和producer状态信息,这些信息有zookeeper保存;因此producer和consumer的客户端实现非常轻量级,它们可以随意离开,而不会对集群造成额外的影响。

6.partition

        每一个分区(partition)都是一个顺序的、不可变的消息队列,并且可以持续的添加。分区中的消息都被分了一个序列号,称之为偏移量(offset),在每个分区中此偏移量都是唯一的。Kafka集群保持所有的消息,直到它们过期,无论消息是否被消费了。实际上消费者所持有的仅有的元数据就是这个偏移量,也就是消费者在这个log中的位置。 这个偏移量由消费者控制:正常情况当消费者消费消息的时候,偏移量也线性的的增加。但是实际偏移量由消费者控制,消费者可以将偏移量重置为更老的一个偏移量,重新读取消息。 可以看到这种设计对消费者来说操作自如, 一个消费者的操作不会影响其它消费者对此log的处理。 再说说分区。Kafka中采用分区的设计有几个目的。一是可以处理更多的消息,不受单台服务器的限制。Topic拥有多个分区意味着它可以不受限的处理更多的数据。第二,分区可以作为并行处理的单元。

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

        每个partion(目录)相当于一个巨型文件被平均分配到多个大小相等segment(段)数据文件中。但每个段segment file消息数量不一定相等,这种特性方便old segment file快速被删除。

        每个partiton只需要支持顺序读写就行了,segment文件生命周期由服务端配置参数决定。

        这样做的好处就是能快速删除无用文件,有效提高磁盘利用率。

7.分布式高可用

        Log的分区被分布到集群中的多个服务器上。每个服务器处理它分到的分区。根据配置每个分区还可以复制到其它服务器作为备份容错。 每个分区有一个leader,零或多个follower。Leader处理此分区的所有的读写请求,而follower被动的复制数据。如果leader宕机,其它的一个follower会被推举为新的leader。 一台服务器可能同时是一个分区的leader,另一个分区的follower。 这样可以平衡负载,避免所有的请求都只让一台或者某几台服务器处理。

8.zookeeper和kafka的关系

        管理、协调:

  • leader选举
  • kafka新增,broker挂了,producer不会写到挂了的broker中
  • 元数据保存到zookeeper,具体的数据(消息)不会存储
  • consumer消费的broker挂了,从别的备份中去消费

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值