大数据面试总结-kafka

下一篇:Spark https://blog.csdn.net/Mr_Fjl/article/details/97373193

1.什么是kafka?

kafka是分布式发布-订阅消息系统,是一种分布式的消息队列工具

kafka是一个分布式的,可分区的,可复制的消息系统

kafka对消息保存的时候根据topic进行分类,发送消息者称为Producer,消息接受者称为consumer,此外kafka集群由多个kafka实例组成,每个实例称为broker

依赖zookeeper来保证系统的可用性,保存元数据信息


2.kafka主要概念

topic主题
一个topic是对一组消息的归纳

在一个Kafka集群中,可以创建多个topic主题,以topic主题为单位管理消息,kafka中多个topic主题之间是互相隔离互不影响,从而可以在一个Kafka集群中通过创建多个topic主题实现不同的使用者独立使用不同topic主题而互不影响。

partition分区
topic可以划分出多个分区,利用分区机制保证每个分区的数据量不会太大, 可以在单个服务器上保存

分区是kafka实现负载均衡和失败恢复分布式数据存储的基本单元

每个分区可以单独发布和消费,为并发操作topic提供了可能

offset序号
每个分区都由一系列有序的,不可变的消息组成,这些消息被连续追加到分区中

分区中的每个消息都由一个连续的序列号叫做offset,用来在分区中唯一的标识这个消息

在一个可配置的时间段内,Kafka集群保留所有发布的消息,不管这些消息有没有被消费。

可以设置消息的保存策略,制定保存期限,在期限到来之前,数据会一直存在,无论是否被消费国,当保存期限结束,消息会被连续的擦除,释放空间

一系列的机制保证了kafka当中数据的连续读写磁盘,保证了性能,从而使得kafka的性能与数据量无关,只和磁盘的性能是常量级的

Replication复本
每个分区拥有若干复本,这些复本存放在不同的服务器中

若干个副本中,有一个称为leader负责读写操作,而其他的作为Leader,负责同步leader中的数据,对外只提供读的能力

kafka不是以broker为单位划分leader,follwer,而是以副本为单位划分;这样,集群中的每一个broker是持有一部分分区的leader和另一部分分区的follwer,从而将写的压力分摊到不同的broken中取,利用分布式分摊写的压力,提升性能

Producer生产者
生产者将消息发布到制定的主题中,默认使用简单的负载均衡机制选择分区,如果需要可以通过特定的分区函数选择分区,制定发布到哪个分区

Consumer消费者
Consumer负责消费主题中的数据,消费时由Consumer自己来维护会话产生的数据,实际上每个consumer唯一需要维护的数据是消息在日志中的位置,也就是offset,一般情况下随着Consumer不断的读取消息,这offset的值不断增加,从而实现连续读取数据

Broker
集群汇中的一台或多台服务器统称为broker

消费者消费数据的模式
发布订阅模式:多个Consumer可以同时从服务端读取数据,Consumer之间互不影响,每个Consumer都可以读取到全量的数据。达成了多个Consumer之间共享数据的效果。

队列模式:多个Consumer可以同时从服务端读取消息,每个消息只被其中一个Consumer读到。达成多个Consumer之间竞争数据的效果。

消费者组的概念
在Kafka中可以将多个消费者组成一个消费者组。

在消费者组内,多个消费者而形成竞争状态,互相抢夺数据。同一份消息只能被一个消费者组内的消费者消费一次。

在消费者组之间,多个消费者形成共享状态,共享数据。同一份消息会同时被多个消费者组各自消费到
 

3.kafka的设计

吞吐量
数据磁盘持久化:消息不在内存中cache,直接写入到磁盘,充分利用磁盘的顺序读写性能
zero-copy:减少IO操作步骤
数据批量发送
数据压缩
Topic划分为多个partition,提高parallelism
负载均衡
producer根据用户指定的算法,将消息发送到指定的partition
存在多个partiiton,每个partition有自己的replica,每个replica分布在不同的Broker节点上
多个partition需要选取出lead partition,lead partition负责读写,并由zookeeper负责fail over
通过zookeeper管理broker与consumer的动态加入与离开
拉取系统
kafka broker会持久化数据,broker没有内存压力,因此,consumer非常适合采取pull的方式消费数据
consumer根据消费能力自主控制消息拉取速度
consumer根据自身情况自主选择消费模式,例如批量,重复消费,从尾端开始消费等
可扩展性
当需要增加broker结点时,新增的broker会向zookeeper注册,而producer及consumer会根据注册在zookeeper上的watcher感知这些变化,并及时作出调整。

4.kafka的主要特点

  1. 同时为发布和订阅提供高吞吐量。据了解,Kafka每秒可以生产约25万消息(50 MB),每秒处理55万消息(110 MB)。
  2. 可进行持久化操作。将消息持久化到磁盘,因此可用于批量消费,例如ETL,以及实时应用程序。通过将数据持久化到硬盘以及replication防止数据丢失。
  3. 分布式系统,易于向外扩展。所有的producer、broker和consumer都会有多个,均为分布式的。无需停机即可扩展机器。
  4. 消息被处理的状态是在consumer端维护,而不是由server端维护。当失败时能自动平衡。
  5. 支持online和offline的场景。

5.kafka文件存储机制

同一个topic下有多个不同的partition,每个partition为一个目录,partition命名的规则是topic的名称加上一个序号,序号从0开始。

每一个partition目录下的文件被平均切割成大小相等(默认一个文件是500兆,可以手动去设置)的数据文件,
每一个数据文件都被称为一个段(segment file),但每个段消息数量不一定相等,这种特性能够使得老的segment可以被快速清除。
默认保留7天的数据。

每个partition下都会有这些每500兆一个每500兆一个(当然在上面的测试中我们将它设置为了1G一个)的segment段。

另外每个partition只需要支持顺序读写就可以了,partition中的每一个segment端的生命周期是由我们在配置文件中指定的一个参数觉得的。
比如它在默认情况下,每满500兆就会创建新的segment段(segment file),每满7天就会清理之前的数据。
它的一个特点就是支持顺序写。如下图所示:

首先00000000000000000000.log文件是最早产生的文件,该文件达到1G(因为我们在配置文件里面指定的1G大小,默认情况下是500兆)
之后又产生了新的0000000000000672348.log文件,新的数据会往这个新的文件里面写,这个文件达到1G之后,数据就会再往下一个文件里面写,
也就是说它只会往文件的末尾追加数据,这就是顺序写的过程,生产者只会对每一个partition做数据的追加(写)的操作。
问题:如何保证消息消费的有序性呢?比如说生产者生产了0到100个商品,那么消费者在消费的时候安装0到100这个从小到大的顺序消费,
那么kafka如何保证这种有序性呢?难度就在于,生产者生产出0到100这100条数据之后,通过一定的分组策略存储到broker的partition中的时候,
比如0到10这10条消息被存到了这个partition中,10到20这10条消息被存到了那个partition中,这样的话,消息在分组存到partition中的时候就已经被分组策略搞得无序了。
那么能否做到消费者在消费消息的时候全局有序呢?遇到这个问题,我们可以回答,在大多数情况下是做不到全局有序的。但在某些情况下是可以做到的。

比如我的partition只有一个,这种情况下是可以全局有序的。那么可能有人又要问了,只有一个partition的话,哪里来的分布式呢?哪里来的负载均衡呢?
所以说,全局有序是一个伪命题!全局有序根本没有办法在kafka要实现的大数据的场景来做到。但是我们只能保证当前这个partition内部消息消费的有序性。

结论:一个partition中的数据是有序的吗?回答:间隔有序,不连续。

针对一个topic里面的数据,只能做到partition内部有序,不能做到全局有序。特别是加入消费者的场景后,如何保证消费者的消费的消息的全局有序性,
这是一个伪命题,只有在一种情况下才能保证消费的消息的全局有序性,那就是只有一个partition!
Segment file是什么?

生产者生产的消息按照一定的分组策略被发送到broker中partition中的时候,这些消息如果在内存中放不下了,就会放在文件中,
partition在磁盘上就是一个目录,该目录名是topic的名称加上一个序号,在这个partition目录下,有两类文件,一类是以log为后缀的文件,
一类是以index为后缀的文件,每一个log文件和一个index文件相对应,这一对文件就是一个segment file,也就是一个段。
其中的log文件就是数据文件,里面存放的就是消息,而index文件是索引文件,索引文件记录了元数据信息。
说到segment file的索引文件和数据文件的一一对应,我们应该能想到storm中的Ack File机制,在spout发出去的时候要发一个Ack Tuple,
在下游的bolt处理完之后,它也要发一个Ack Tuple,这两个Ack Tuple里面包含了同样一份数据,这个数据叫做MessageId,它是一个对象,
这个对象里面包含两个比较重要的字段,一个是RootId,另一个是TupleId(也叫锚点Id),这个锚点Id会在我们发送数据的时候进行异或一下,
异或的结果才会发送给Ack那个Bolt。

 

Segment文件命名的规则:partition全局的第一个segment从0(20个0)开始,后续的每一个segment文件名是上一个segment文件中最后一条消息的offset值。

那么这样命令有什么好处呢?假如我们有一个消费者已经消费到了368776(offset值为368776),那么现在我们要继续消费的话,怎么做呢?
看上图,分2个步骤,第1步是从所有文件log文件的的文件名中找到对应的log文件,第368776条数据位于上图中的“00000000000000368769.log”这个文件中,
这一步涉及到一个常用的算法叫做“二分查找法”(假如我现在给你一个offset值让你去找,你首先是将所有的log的文件名进行排序,然后通过二分查找法进行查找,
很快就能定位到某一个文件,紧接着拿着这个offset值到其索引文件中找这条数据究竟存在哪里);第2步是到index文件中去找第368776条数据所在的位置。

索引文件(index文件)中存储这大量的元数据,而数据文件(log文件)中存储这大量的消息。

索引文件(index文件)中的元数据指向对应的数据文件(log文件)中消息的物理偏移地址。

上图的左半部分是索引文件,里面存储的是一对一对的key-value,其中key是消息在数据文件(对应的log文件)中的编号,比如“1,3,6,8……”,
分别表示在log文件中的第1条消息、第3条消息、第6条消息、第8条消息……,那么为什么在index文件中这些编号不是连续的呢?
这是因为index文件中并没有为数据文件中的每条消息都建立索引,而是采用了稀疏存储的方式,每隔一定字节的数据建立一条索引。
这样避免了索引文件占用过多的空间,从而可以将索引文件保留在内存中。
但缺点是没有建立索引的Message也不能一次定位到其在数据文件的位置,从而需要做一次顺序扫描,但是这次顺序扫描的范围就很小了。

其中以索引文件中元数据3,497为例,其中3代表在右边log数据文件中从上到下第3个消息(在全局partiton表示第368772个消息),
其中497表示该消息的物理偏移地址(位置)为497。

6.kafka存储策略

kafka通过topic来分主题存放数据,主题内又有分区,分区还可以有多个副本 。

从物理结构来看,分区本身是kafka存储目录下的一个文件夹,文件夹名称是主题名加分区编号,编号从0开始

分区的内部还有segment的概念,其实就是在分区对应的文件夹下产生的文件,

一个分区会被划分为大小相等的若干个segment,一方面保证了分区的数据被划分到多个文件中(保证了文件的体积不会太大),另一方面可以基于这些segment文件进行历史数据的删除,提高效率

一个segment由一个.log和一个.index文件组成,其中.log文件为数据文件用来存储数据分段数据,.index为索引文件保存对应的.log文件的索引信息

这两个文件的命名规则:partition全局的第一个segment从0开始,后续的每个segment文件名为上一个segment文件的最后一条消息的offset值

通过查找.index文件可以获知每个存储在当前segment中的offset在.log文件中的开始位置

每条日志有固定格式:包括offset编号,日志长度,key的长度,通过这个固定格式的数据可以确定出当前offset的结束位置,从而对数据进行读取


7.kafka可靠性保障AR ISR OSR

AR
kafka分区中,维护了一个AR列表,其中包括了所有的分区的副本编号,AR分为ISR和OSR

ISR
同步列表,只有当所有的ISR内的副本都同步了leader中的数据,数据才能被提交,才能被消费者访问

OSR
非同步列表,OSR内的副本是否同步了leader的数据,不影响数据的提交,OSR内的follower只是尽力的去同步leader,数据版本可能落后。

最开始所有的副本都在ISR中,在kafka工作的过程中,如果某个副本同步速度慢于replica.lag.time.max.ms指定的阈值,则被踢出ISR 存入OSR,如果后续速度恢复可以回到ISR中

这种方案是介于leader独裁和所有民主方式之间,更加的灵活,相对于zookeeper的过半同意过半存活机制,提供了更好的可用性。牺牲了一部分的可靠性,换来的可用性对于kafka这样的消息队列来说很有意义


8.Kafka和RabbitMQ的区别

架构方面不同

RabbitMQ遵循AMQP协议,RabbitMQ的broker由Exchange,Binding,queue组成,其中exchange和binding组成了消息的路由键;客户端Producer通过连接channel和server进行通信,Consumer从queue获取消息进行消费(长连接,queue有消息会推送到consumer端,consumer循环从输入流读取数据)。rabbitMQ以broker为中心;有消息的确认机制。

kafka遵从一般的MQ结构,producer,broker,consumer,以consumer为中心,消息的消费信息保存的客户端consumer上,consumer根据消费的点,从broker上批量pull数据;无消息确认机制。

应用场景

RabbitMQ,循AMQP协议,用于实时的对可靠性要求比较高的消息传递上。

kafka主要用于处理活跃的流式数据,大数据量的数据处理上

吞吐量

kafka具有高的吞吐量,内部采用消息的批量处理,zero-copy机制,数据的存储和获取是本地磁盘顺序批量操作,具有O(1)的复杂度,消息处理的效率很高

rabbitMQ在吞吐量方面稍逊于kafka,他们的出发点不一样,rabbitMQ支持对消息的可靠的传递,支持事务,不支持批量的操作;基于存储的可靠性的要求存储可以采用内存或者硬盘。


9.kafka生产者生产数据的可靠性

生产者向leader发送数据时,可以选择需要的可靠性级别

通过request.required.acks参数设置(0:至多一次,1:至少一次,-1:刚好一次)

0(至多一次):
生产者不停向leader发送数据,而不需要leader反馈成功消息,这种模式效率最高,可靠性最低,可能在发送过程中丢失数据。可能在leader宕机时丢失数据(可能因为网络的不稳定丢失数据。Leader宕机后,宕机期间没有接受到数据,就丢失了)

1(默认,至少一次):
producer在ISR中的leader已成功收到数据并得到确认后才会发送下一条数据,如果等待响应超时,生产者自动重发数据。(不会因为网络不稳定而丢失,但可能在leader宕机而新数据未同步完成时,因新的leader选举后截断未同步数据而造成丢失数据。如果网络不稳定,在重发的过程中,可能会导致多数据)

-1(恰好一次)
producer需要等待ISR中的leader和所有follower都确认接收到数据后才算一次发送完成,才会发送下一条数据,如果等待响应超时,生产者自动重发,数据可靠性最高(效率很低)。

但是这样也不能保证数据完全不丢失,例如当ISR中只有leader时,此时,leader宕机,如果不允许OSR中的follower成为新的leader可以保障写入数据的一致性,但除非原来的leader恢复,否则集群一直无法恢复。或者可以允许OSR列表中的follower成为新的leader,但此时存在写数据不一致的风险。

kafka还提供了min.insync.replicas参数,这个参数要求ISR列表中至少要有指定数量个副本leader才可以接受数据

即使配置request.required.acks=-1,min.insync.replicas=2,也只能保证第二个层面的可靠性,即不丢数据,但仍可能多数据。如果想要实现恰好一次的语义,则需要在这个基础上进一步的加上去重机制

Kafka提供了GUID机制,能够在客户端根据算法为每条日志增加一个全局唯一标识,重发时会保持GUID一致,从而实现了标识每条数据。


10.消费者是从leader中拿数据,还是从follow中拿数据?

kafka是由follower周期性或者尝试去pull(拉)过来(其实这个过程与consumer消费过程非常相似),

写是都往leader上写,但是读并不是任意flower上读都行,读也只在leader上读,flower只是数据的一个备份,

保证leader被挂掉后顶上来,并不往外提供服务。

11.说说kafka的ISR机制?

  • kafka 为了保证数据的一致性使用了isr 机制,
  • 1. leader会维护一个与其基本保持同步的Replica列表,该列表称为ISR(in-sync Replica),每个Partition都会有一个ISR,而且是由leader动态维护
  • 2. 如果一个flower比一个leader落后太多,或者超过一定时间未发起数据复制请求,则leader将其重ISR中移除
  • 3. 当ISR中所有Replica都向Leader发送ACK时,leader才commit
  • kafka 不同,只有leader 负责读写,follower只负责备份,如果leader宕机的话,Kafaka动态维护了一个同步状态的副本的集合(a set of in-sync replicas),简称ISR,ISR中有f+1个节点,就可以允许在f个节点down掉的情况下不会丢失消息并正常提供服。ISR的成员是动态的,如果一个节点被淘汰了,当它重新达到“同步中”的状态时,他可以重新加入ISR。因此如果leader宕了,直接从ISR中选择一个follower就行。

    kafka在引入Replication之后,同一个Partition可能会有多个Replica,而这时需要在这些Replication之间选出一个Leader,Producer和Consumer只与这个Leader交互,其它Replica作为Follower从Leader中复制数据。因为需要保证同一个Partition的多个Replica之间的数据一致性(其中一个宕机后其它Replica必须要能继续服务并且即不能造成数据重复也不能造成数据丢失)。如果没有一个Leader,所有Replica都可同时读/写数据,那就需要保证多个Replica之间互相(N×N条通路)同步数据,数据的一致性和有序性非常难保证,大大增加了Replication实现的复杂性,同时也增加了出现异常的几率。而引入Leader后,只有Leader负责数据读写,Follower只向Leader顺序Fetch数据(N条通路),系统更加简单且高效。 

    Kafka:由于kafka的使用场景决定,其读取数据时更关注数据的一致性
    从leader读取和写入可以保证所有客户端都得到相同的数据,否则可能存在一些在ISR中注册的节点(replication-factor大于min.insync.replicas),因未来得及更新副本而无法提供的数据。相应的为了规避都从leader上读取带来的资源竞争,可以根据不同topic和不同partition设置不同的leader。

12.SparkStreaming连接kafka如何保证数据的不重复不丢失

sparkStreaming接收kafka数据的方式有两种: 1.利用Receiver接收数据; 2.直接从kafka读取数据(Direct 方式)

保证数据不丢失
(1)Receiver方式为确保零数据丢失,必须在Spark Streaming中另外启用预写日志(Write Ahead Logs)。这将同步保存所有收到的Kafka数据到分布式文件系统(例如HDFS)上,以便在发生故障时可以恢复所有数据。
(2)Direct方式依靠checkpoint机制来保证。每次streaming 消费了kafka的数据后,将消费的kafka offsets更新到checkpoint。当你的程序挂掉或者升级的时候,就可以接着上次的读取,实现数据的零丢失。
(Direct需要用户采用checkpoint或者第三方存储来维护offsets,而不像Receiver-based那样,通过ZooKeeper来维护Offsets,此提高了用户的开发成本)

kafka的acks参数有一个非常重要的作用。如果acks设置为0,表示Producer不会等待Broker的响应,Producer无法确定消息是否发送成功,可能会导致数据丢失,但acks值为0时,会得到最大的系统吞吐量。如果acks设置为1,表示Producer会在leader Partition收到消息并得到Broker的一个确认,这样会有更好的可靠性。如果设置为-1,Producer会在所有备份的Partition收到消息时得到Broker的确认,这个设置可以得到最高的可靠性保证。

保证数据不重复
这里业务场景被区分为两个:

幂等操作
业务代码需要自身添加事物操作
所谓幂等操作就是重复执行不会产生问题,如果是这种场景下,你不需要额外做任何工作。但如果你的应用场景是不允许数据被重复执行 的,那只能通过业务自身的逻辑代码来解决了。
这个spark给出了官方方案:

dstream.foreachRDD {(rdd, time) =
              rdd.foreachPartition { partitionIterator =>
                val partitionId = TaskContext.get.partitionId()
                val uniqueId = generateUniqueId(time.milliseconds,partitionId)
                //use this uniqueId to transationally commit the data in partitionIterator
                 }
      }

  就是说针对每个partition的数据,产生一个uniqueId,只有这个partition的所有数据被完全消费,则算成功,否则算失效,要回滚。下次重复执行这个uniqueId时,如果已经被执行成功,则skip掉。

13.kafka 是如何清理过期数据的?

kafka的日志实际上是以日志的方式默认保存在/kafka-logs文件夹中的,默认7天清理机制,

日志的真正清理时间。当删除的条件满足以后,日志将被“删除”,但是这里的删除其实只是将

该日志进行了“delete”标注,文件只是无法被索引到了而已。但是文件本身,仍然是存在的,只有当过了log.segment.delete.delay.ms 这个时间以后,文件才会被真正的从文件系统中删除。

14.一条message中包含哪些信息?

  • 包含 header,body。
  • 一个Kafka的Message由一个固定长度的header和一个变长的消息体body组成。
  • header部分由一个字节的magic(文件格式)和四个字节的CRC32(用于判断body消息体是否正常)构成。
  • 当magic的值为1的时候,会在magic和crc32之间多一个字节的数据:attributes(保存一些相关属性,比如是否压缩、
  • 压缩格式等等);
  • 如果magic的值为0,那么不存在attributes属性body是由N个字节构成的一个消息体,包含了具体的key/value消息

15.Kafka应用场景

日志收集:一个公司可以用Kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如hadoop、Hbase、Solr等。

- 消息系统:解耦和生产者和消费者、缓存消息等。

- 用户活动跟踪:Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘。

- 运营指标:Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。

- 流式处理:比如spark streaming和storm

- 事件源

16.kafka生产者-消费者

 消息系统通常都会由生产者,消费者,Broker三大部分组成,生产者会将消息写入到Broker,消费者会从Broker中读取出消息,不同的MQ实现的Broker实现会有所不同,不过Broker的本质都是要负责将消息落地到服务端的存储系统中。具体步骤如下:

  1. 生产者客户端应用程序产生消息:

    1. 客户端连接对象将消息包装到请求中发送到服务端

    2. 服务端的入口也有一个连接对象负责接收请求,并将消息以文件的形式存储起来

    3. 服务端返回响应结果给生产者客户端

  2. 消费者客户端应用程序消费消息:

    1. 客户端连接对象将消费信息也包装到请求中发送给服务端

    2. 服务端从文件存储系统中取出消息

    3. 服务端返回响应结果给消费者客户端

    4. 客户端将响应结果还原成消息并开始处理消息

5.1  Producers

Producers直接发送消息到broker上的leader partition,不需要经过任何中介或其他路由转发。为了实现这个特性,kafka集群中的每个broker都可以响应producer的请求,并返回topic的一些元信息,这些元信息包括哪些机器是存活的,topic的leader partition都在哪,现阶段哪些leader partition是可以直接被访问的。

Producer客户端自己控制着消息被推送到哪些partition。实现的方式可以是随机分配、实现一类随机负载均衡算法,或者指定一些分区算法。Kafka提供了接口供用户实现自定义的partition,用户可以为每个消息指定一个partitionKey,通过这个key来实现一些hash分区算法。比如,把userid作为partitionkey的话,相同userid的消息将会被推送到同一个partition。

以Batch的方式推送数据可以极大的提高处理效率,kafka Producer 可以将消息在内存中累计到一定数量后作为一个batch发送请求。Batch的数量大小可以通过Producer的参数控制,参数值可以设置为累计的消息的数量(如500条)、累计的时间间隔(如100ms)或者累计的数据大小(64KB)。通过增加batch的大小,可以减少网络请求和磁盘IO的次数,当然具体参数设置需要在效率和时效性方面做一个权衡。

Producers可以异步的并行的向kafka发送消息,但是通常producer在发送完消息之后会得到一个future响应,返回的是offset值或者发送过程中遇到的错误。这其中有个非常重要的参数“acks”,这个参数决定了producer要求leader partition 收到确认的副本个数,如果acks设置数量为0,表示producer不会等待broker的响应,所以,producer无法知道消息是否发送成功,这样有可能会导致数据丢失,但同时,acks值为0会得到最大的系统吞吐量。

若acks设置为1,表示producer会在leader partition收到消息时得到broker的一个确认,这样会有更好的可靠性,因为客户端会等待直到broker确认收到消息。若设置为-1,producer会在所有备份的partition收到消息时得到broker的确认,这个设置可以得到最高的可靠性保证。

Kafka 消息有一个定长的header和变长的字节数组组成。因为kafka消息支持字节数组,也就使得kafka可以支持任何用户自定义的序列号格式或者其它已有的格式如Apache Avro、protobuf等。Kafka没有限定单个消息的大小,但我们推荐消息大小不要超过1MB,通常一般消息大小都在1~10kB之前。

发布消息时,kafka client先构造一条消息,将消息加入到消息集set中(kafka支持批量发布,可以往消息集合中添加多条消息,一次行发布),send消息时,producer client需指定消息所属的topic。

5.2  Consumers

Kafka提供了两套consumer api,分为high-level api和sample-api。Sample-api 是一个底层的API,它维持了一个和单一broker的连接,并且这个API是完全无状态的,每次请求都需要指定offset值,因此,这套API也是最灵活的。

在kafka中,当前读到哪条消息的offset值是由consumer来维护的,因此,consumer可以自己决定如何读取kafka中的数据。比如,consumer可以通过重设offset值来重新消费已消费过的数据。不管有没有被消费,kafka会保存数据一段时间,这个时间周期是可配置的,只有到了过期时间,kafka才会删除这些数据。(这一点与AMQ不一样,AMQ的message一般来说都是持久化到mysql中的,消费完的message会被delete掉)

High-level API封装了对集群中一系列broker的访问,可以透明的消费一个topic。它自己维持了已消费消息的状态,即每次消费的都是下一个消息。

High-level API还支持以组的形式消费topic,如果consumers有同一个组名,那么kafka就相当于一个队列消息服务,而各个consumer均衡的消费相应partition中的数据。若consumers有不同的组名,那么此时kafka就相当与一个广播服务,会把topic中的所有消息广播到每个consumer。

High level api和Low level api是针对consumer而言的,和producer无关。

High level api是consumer读的partition的offsite是存在zookeeper上。High level api 会启动另外一个线程去每隔一段时间,offsite自动同步到zookeeper上。换句话说,如果使用了High level api, 每个message只能被读一次,一旦读了这条message之后,无论我consumer的处理是否ok。High level api的另外一个线程会自动的把offiste+1同步到zookeeper上。如果consumer读取数据出了问题,offsite也会在zookeeper上同步。因此,如果consumer处理失败了,会继续执行下一条。这往往是不对的行为。因此,Best Practice是一旦consumer处理失败,直接让整个conusmer group抛Exception终止,但是最后读的这一条数据是丢失了,因为在zookeeper里面的offsite已经+1了。等再次启动conusmer group的时候,已经从下一条开始读取处理了。

Low level api是consumer读的partition的offsite在consumer自己的程序中维护。不会同步到zookeeper上。但是为了kafka manager能够方便的监控,一般也会手动的同步到zookeeper上。这样的好处是一旦读取某个message的consumer失败了,这条message的offsite我们自己维护,我们不会+1。下次再启动的时候,还会从这个offsite开始读。这样可以做到exactly once对于数据的准确性有保证。

对于Consumer group:

1. 允许consumer group(包含多个consumer,如一个集群同时消费)对一个topic进行消费,不同的consumer group之间独立消费。

2. 为了对减小一个consumer group中不同consumer之间的分布式协调开销,指定partition为最小的并行消费单位,即一个group内的consumer只能消费不同的partition。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
rsyslog-kafka是一种将rsyslog日志服务器与Apache Kafka消息队列集成的工具。rsyslog是一个功能强大的开源日志收集器,可用于在Linux系统上收集、处理和转发日志数据。而Kafka是一个高度可扩展的分布式消息系统,用于实时处理和存储大量数据。 通过rsyslog-kafka的集成,我们可以将rsyslog收集到的日志数据发送到Kafka消息队列中,从而实现日志的实时处理和存储。这种集成的好处是可以应对流量大、实时性要求高的日志场景,提高日志的传输速度和处理能力。 使用rsyslog-kafka的过程大致分为以下几步:首先,需要配置rsyslog服务器以收集特定文件或设备的日志数据;然后,配置rsyslog-kafka模块,指定Kafka的主题(topic)和其他相关参数;接下来,rsyslog-kafka将会将收集到的日志数据传输到Kafka消息队列中;最后,消费者可以从Kafka消息队列中实时接收、处理和存储这些日志数据。 rsyslog-kafka具有一些优点。首先,通过使用Kafka作为消息队列,可以轻松地扩展和处理大量的日志数据。其次,rsyslog-kafka提供了高度可配置性,可以根据需求选择日志的格式、过滤器和其他参数。此外,rsyslog-kafka还支持故障转移和高可用性机制,确保日志数据的可靠传输和存储。 总之,rsyslog-kafka是一种强大的工具,可以将rsyslog日志服务器与Kafka消息队列集成,实现高效的日志收集、传输、处理和存储。它为大规模的日志数据场景提供了解决方案,并提供了灵活的配置选项和高可靠性的机制。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值