消息队列kafka

文章目录

1.什么是消息队列

容器,在消息的传输过程中保存消息的。主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用。消息中间件最主要的作用是解耦,生产者生产消息传送到队列,消费者从队列中拿取消息并处理,生产者不用关心是谁来消费,消费者不用关心谁在生产消息,从而达到解耦的目的。
除了解耦,还有削峰、异步

2. 消息队列优缺点?

  • 解耦
    场景:A 系统通过接口调用发送数据到 BCD 三个系统,A 系统跟其它系统严重耦合,A 系统要时时刻刻考虑 BCD 系统是否可用,要不要重发,要不要把消息存起来。

    如果使用 MQ,A 系统产生一条数据,发送到 MQ 里面去,哪个系统需要数据自己去 MQ 里面消费。如果新系统需要数据,直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可。这样下来,A 系统不需要去考虑要给谁发送数据,不需要维护这个代码,也不需要考虑人家是否调用成功、失败超时等情况。

    总结:通过一个 MQ,Pub/Sub 发布订阅消息这么一个模型,A 系统就跟其它系统彻底解耦了。

  • 异步
    在高并发环境下,由于来不及同步处理,请求往往会发生堵塞,比如,大量的insert,update之类的请求同时到达MySQL,直接导致无数的行锁表锁,甚至最后请求会堆积过多,从而触发too many connections错误。通过使用消息队列,可以异步处理请求,缓解系统的压力。
    在这里插入图片描述

在不使用消息队列的情况下,用户的请求数据直接写入数据库,在高并发的情况下,会对数据库造成巨大的压力, 同时也使得响应延迟加剧。在使用消息队列后,用户请求的数据发送给消息队列后立即返回,再由消息队列的消费者进程从消息队列中获取数据, 异步写入数据库。由于消息队列服务器处理速度远快于数据库,因此用户的响应延迟可得到有效改善。

  • 削峰
    异步处理, 将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。
    比如在电子商务网站促销活动中,对系统每秒并发请求数量突然从每秒50条暴增到 5k+ 条。如果系统是直接基于 MySQL 的,大量的请求涌入 MySQL。假如MYSQL的处理上限是每秒 2k 个请求,高峰期可能导致系统崩溃。
    如果使用 MQ,把请求写入 MQ, 系统每秒钟最多处理 2k 个请求,系统从 MQ 中慢慢拉取请求,每秒钟就拉取 2k 个请求,这样下来,哪怕是高峰期的时候,系统也绝对不会挂掉。只要高峰期一过, 系统就会快速将积压的消息给解决掉。

缺点
1.系统可用性降低 系统引入的外部依赖越多,越容易挂掉。MQ 一挂,整套系统崩溃的。
2.系统复杂度提高 ,加个 MQ 进来,需要保证消息没有重复消费 、需要处理消息丢失的情况、需要保证消息传递的顺序性
3.一致性问题
一条消息由多个消费者消费,万一有一个消费者消费失败了,就会导致数据不一致。

队列的消息传递模式?

  • 点对点
    在点对点消息系统中,消息持久化到一个队列中。此时,将有一个或多个消费者消费队列中的数据。但是一条消息只能被消费一次。当一个消费者消费了队列中的某条数据之后,该条数据则从消息队列中删除。该模式即使有多个消费者同时消费数据,也能保证数据处理的顺序。

  • 发布-订阅消息传递模式
    在发布-订阅消息系统中,消息被持久化到一个topic中。与点对点消息系统不同的是,消费者可以订阅一个或多个topic,消费者可以消费该topic中所有的数据,同一条数据可以被多个消费者消费,数据被消费后不会立马删除。在发布-订阅消息系统中,消息的生产者称为发布者,消费者称为订阅者。

Kafka的特性:

  • 高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒,每个topic可以分多个partition, consumer group 对partition进行consume操作。

  • 可扩展性:kafka集群支持热扩展

  • 持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失

  • 容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)

  • 高并发:支持数千个客户端同时读写

Kafka的使用场景:

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

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

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

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

Kafka 基础架构

在这里插入图片描述
Producer:消息的产生者,是消息的入口。

Broker:broker 是消息的代理,Producers往Brokers里面的指定Topic中写消息,Consumers从Brokers里面拉取指定Topic的消息,然后进行业务处理,broker在中间起到一个代理保存消息的中转站。

Topic:消息的主题,可以理解为消息的分类,kafka的数据就保存在topic。在每个broker上都可以创建多个topic。

Partition:Topic的分区,每个topic可以有多个分区,分区的作用是做负载,提高kafka的吞吐量。同一个topic在不同的分区的数据是不重复的,partition的表现形式就是一个一个的文件夹!

Replication:每一个分区都有多个副本,副本的作用是做备胎。当主分区(Leader)故障的时候会选择一个备胎(Follower)上位,成为Leader。在kafka中默认副本的最大数量是10个,且副本的数量不能大于Broker的数量,follower和leader绝对是在不同的机器,同一机器对同一个分区也只可能存放一个副本(包括自己)。

Message:每一条发送的消息主体。

offset:偏移量offset记录消了费者在partition中消费到哪里,消费失败时可以重置offset达到重新消费的效果,kafka 的存储文件都是按照 offset.kafka 来命名,用 offset 做名字的好处是方便查找。例如你想找位于 2049 的位置,只要找到 2048.kafka 的文件即可。

Consumer:消费者,即消息的消费方,是消息的出口。

Consumer Group:是Kafka实现单播和广播两种消息模型的手段。同一个topic的数据,会广播给不同的group;同一个group中的消费者,只有一个消费者能拿到这个数据。换句话说,对于同一个topic,每个group都可以拿到同样的所有数据,但是数据进入group后只能被其中的一个消费者消费。group内的消费者可以使用多线程或多进程来实现,也可以将进程分散在多台机器上,消费者的数量通常不超过partition的数量,且二者最好保持整数倍关系,因为Kafka在设计时假定了一个partition只能被一个消费者消费(同一group内)

Zookeeper:zookeeper 是一个分布式的协调组件,早期版本的kafka用zk做meta信息存储,consumer的消费状态,group的管理以及 offset的值。新版本中逐渐弱化了zookeeper的作用,但是broker依然依赖于ZK,zookeeper 在kafka中还用来选举controller 和 检测broker是否存活等等。

5.kafka follower如何与leader同步数据?

Kafka的复制机制既不是完全的同步复制,也不是单纯的异步复制。完全同步复制要求All Alive Follower都复制完,这条消息才会被认为commit,这种复制方式极大的影响了吞吐率。而异步复制方式下,Follower异步的从Leader复制数据,数据只要被Leader写入log就被认为已经commit,这种情况下,如果leader挂掉,会丢失数据, kafka使用ISR(副本同步队列)的方式很好的均衡了确保数据不丢失以及吞吐率。
kafka的broker端每个partition都会有多个副本(replica),至少有一个leader领导者副本以及多个follower追随者副本(可配置),分区接收消息以及消费消息都会在leader中进行,而follower副本的作用就是备份leader中的消息,它们会定时的从leader中拉取最新数据,从而尽可能的保证和leader的同步。

分区中的所有副本统称为AR(Assigned Replicas)。所有与leader副本保持一定程度同步的副本(包括leader)组成ISR(in-sync replicas)。而与leader副本同步滞后过多的副本(不包括leader),组成OSR(out-sync replicas),所以,AR = ISR + OSR。在正常情况下,所有的follower副本都应该与leader副本保持一定程度的同步,即AR = ISR,OSR集合为空。

leader副本负责维护和跟踪ISR中所有follower的滞后状态,当follower落后太多或者长时间没有向leader发起同步请求,leader副本就会认为它出问题了,会把它从ISR中移除,这时候这个follower就会放入OSR集合中,直到某个时候这个follower同步跟上了leader,然后这个副本又会被加入到ISR中。此外,当leader副本挂了,只有ISR中的follower副本才有资格成为leader,OSR中的则没有资格。(可以通过修改对应的参数配置)。

参考
参考

分区中的HW、LW、LEO

HW(High Watermark),俗称“高水位”,它表示了一个特定消息的偏移量(offset),消费只能拉取到这个offset之前的消息。
LW(Low Watermark),俗称“低水位”,代表AR集合中最小的logStartOffset值,副本的拉取请求和删除请求都可能促使LW的增长。
LEO(Log End Offset),它表示当前日志文件中下一条待写入消息的offset,LEO的大小相当于当前日志分区中最后一条消息的offset值+1。分区ISR集合中每个副本都会维护自身的LEO,而ISR集合中最小的LEO即为分区的HW,对于消费者而言,只能消费HW之前的消息。

kafka中leader挂掉后重新选举leader过程简介

新leader的选举是由controller来监控管理。
当旧leader挂掉后,controller在zk中的监视器将消息发送给controller,controller开始执行新leader的选举工作。
1.首先确认挂掉的节点上有哪些分区,然后到相应的路径中获得分区所对应的已经同步的副本分区(ISR),在controller监控下,多个已经同步的副本分区同时竞争leader。竞争过程:原先的leader节点挂掉后在zk中被注销了,其他follow同时在zk中重新创建该节点,谁先成功了创建了,谁就是leader。不会多个follow都创建成功,zk只认一个作为创建成功的节点。这样的优点是新leader的数据和挂掉的分区数据一致,不存在丢失。
2-1.如果已经同步副本分区中没有相应的分区,可以等待一定时间,等待分区复活。
2-2.如果已经同步副本分区中没有相应的分区,也可以不等待,退而求其次,在ISR外,在存活的副本分区中找一个作为新leader。由于存活的副本分区不属于已经同步副本分区,所以数据和原先的leader相比有缺失。
3.如果ISR和非同步分区数据副本分区都挂了,那么将新leader设置为-1.

ISR、AR又代表什么?ISR的伸缩又指什么

ISR:In-Sync Replicas 副本同步队列

AR:Assigned Replicas 所有副本

ISR是由leader维护,follower从leader同步数据有一些延迟(包括延迟时间replica.lag.time.max.ms和延迟条数replica.lag.max.messages两个维度, 当前最新的版本0.10.x中只支持replica.lag.time.max.ms这个维度),任意一个超过阈值都会把follower剔除出ISR, 存入OSR(Outof-Sync Replicas)列表,新加入的follower也会先存放在OSR中。AR=ISR+OSR。

HW、LEO、LSO、LW等分别代表什么?

HW:High Watermark 高水位,取一个partition对应的ISR中最小的LEO作为HW,consumer最多只能消费到HW所在的位置上一条信息。

LEO:LogEndOffset 当前日志文件中下一条待写信息的offset

HW/LEO这两个都是指最后一条的下一条的位置而不是指最后一条的位置。

LSO:Last Stable Offset 对未完成的事务而言,LSO 的值等于事务中第一条消息的位置(firstUnstableOffset),对已完成的事务而言,它的值同 HW 相同

LW:Low Watermark 低水位, 代表 AR 集合中最小的 logStartOffset 值

有哪些情形会造成重复消费?

消费者消费后没有commit offset(程序崩溃/强行kill/消费耗时/自动提交偏移情况下unscrible)

那些情景下会造成消息漏消费?

消费者没有处理完消息 提交offset(自动提交偏移 未处理情况下程序异常结束)

流程

  • 发送数据流程
    在这里插入图片描述
    1.Producer在写入数据的时候先从集群中获取分区的leader
    2.producter 将消息发送给leader
    3.leader 将消息写入本地文件
    4.followers 从leader 拉取消息
    5.followers将消息写入本地后向leder发送ACK
    6.leader接受到所有副本的ACK后向producer发送ACK

每条消息追加到分区中,顺序写入磁盘,所以保证同一分区内的数据是有序的!

如何保存数据

kafka将数据保存在磁盘 ,Kafka初始会单独开辟一块磁盘空间,顺序写入数据(效率比随机写入高)
Partition 结构 ,Partition在服务器上的表现形式就是一个一个的文件夹,每个partition的文件夹下面会有多组segment文件,每组segment文件又包含.index文件、.log文件、.timeindex文件三个文件, log文件就实际是存储message的地方,而index和timeindex文件为索引文件,用于检索消息。 每个log文件的大小是一样的,但是存储的message数量是不一定相等的(每条的message大小不一致)。文件的命名是以该segment最小offset来命名的,如000.index存储offset为0~368795的消息,kafka就是利用分段+索引的方式来解决查找效率的问题。

消息的结构

消息由一个固定长度的头部和可变长度的字节数组组成。头部包含了一个版本号和 CRC32校验码。

消息长度: 4 bytes (value: 1+4+n)

版本号: 1 byte

CRC 校验码: 4 bytes

具体的消息: n bytes

对于旧数据的删除策略

1、 基于时间,默认配置是168小时(7天)。

2、 基于大小,默认配置是1073741824。需要注意的是,kafka读取特定消息的时间复杂度是O(1),所以这里删除过期的文件并不会提高kafka的性能!

如何消费数据

消费者主动的去kafka集群的leader去拉取(pull)消息。
同一Topic的一条消息只能被同一个Consumer Group内的一个Consumer消费,但多个Consumer Group可同时消费这一消息。
这是Kafka用来实现一个Topic消息的广播(发给所有的Consumer)和单播(发给某一个Consumer)的手段。一个Topic可以对应多个Consumer Group。如果需要实现广播,只要每个Consumer有一个独立的Group就可以了。要实现单播只要所有的Consumer在同一个Group里。用Consumer Group还可以将Consumer进行自由的分组而不需要多次发送消息到不同的Topic。

14.Kafka中的消息是否会丢失和重复消费?

两个方面:消息发送和消息消费。

1)消息发送
Kafka消息发送有两种方式:同步(sync)和异步(async),默认是同步方式,可通过producer.type属性进行配置。Kafka通过配置request.required.acks属性来确认消息的生产:
0—表示不进行消息接收是否成功的确认;
1—表示当Leader接收成功时确认;
-1—表示Leader和Follower都接收成功时确认;
分析消息丢失的场景:

(1)acks=0,不和Kafka集群进行消息接收确认,则当网络异常、缓冲区满了等情况时,消息可能丢失;

(2)acks=1、同步模式下,只有Leader确认接收成功后但挂掉了,副本没有同步,数据可能丢失;

2)消息消费

Kafka消息消费有两个consumer接口,Low-level API和High-level API:

Low-level API:消费者自己维护offset等值,可以实现对Kafka的完全控制;

High-level API:封装了对parition和offset的管理,使用简单;

如果使用高级接口High-level API,可能存在一个问题就是当消息消费者从集群中把消息取出来、并提交了新的消息offset值后,还没来得及消费就挂掉了,那么下次再消费时之前没消费成功的消息就“诡异”的消失了;

3)解决办法

针对消息丢失:同步模式下,确认机制设置为-1,即让消息写入Leader和Follower之后再确认消息发送成功;异步模式下,为防止缓冲区满,可以在配置文件设置不限制阻塞超时时间,当缓冲区满时让生产者一直处于阻塞状态;
针对消息重复:将消息的唯一标识保存到外部介质中,每次消费时判断是否处理过即可。

kafka的ack的三种机制

  • request.required.acks有三个值0 1 -1(all)

  • 0:生产者不会等待broker的ack,这个延迟最低但是存储的保证最弱当server挂掉的时候就会丢数据。

  • 1:服务端会等待ack值leader副本确认接收到消息后发送ack但是如果leader挂掉后他不确保是否复制完成新leader也会导致数据丢失。

  • -1(all):服务端会等所有的follower的副本受到数据后才会受到leader发出的ack,这样数据不会丢失。

如何避免重复消费

就是每个消息写进去,都有一个 offset,代表消息的序号,然后 consumer 消费了数据之后,每隔一段时间(定时定期),会把自己消费过的消息的 offset 提交一下,表示“我已经消费过了,下次要是重启啥的,就继续从上次消费到的 offset 来继续消费”。

怎么保证消息队列消费的幂等性?

结合业务来思考:

  • 如数据要写库,先根据主键查一下,如果这数据都有了,就别插入了,update 一下。
  • 比如你是写 Redis,那每次都是 set,天然幂等性。
  • 让生产者发送每条数据的时候,里面加一个全局唯一的 id,然后你这里消费到了之后,先根据这个 id 去比如 Redis 里查一下,之前消费过吗?如果没有消费过,就处理,然后这个 id 写 Redis。如果消费过了,就别处理了,保证别重复处理相同的消息即可。

Kafka 的分区策略有哪些?

给定了分区号,直接将数据发送到指定的分区里面去没有给定分区号,给定数据的key值,通过key取上hashCode进行分区既没有给定分区号,也没有给定key值,直接轮循进行分区自定义分区

kafka中是怎么体现消息顺序性的?

kafka每个partition中的消息在写入时都是有序的,消费时,每个partition只能被每一个group中的一个消费者消费,保证了消费时也是有序的。
整个topic不保证有序。如果为了保证topic整个有序,那么将partition调整为1.

kafka分布式下,如何保证消息的顺序消费

Kafka中发送1条消息的时候,可以指定(topic, partition, key) 3个参数。partiton和key是可选的。如果你指定了partition,那就是所有消息发往同1个partition,就是有序的。

并且在消费端,Kafka保证,1个partition只能被1个consumer消费。如果消费端时单线程的话,取出来的数据也是有序的,但如果是多线程,就会乱,解决方法是,写 N 个内存 队列,具有相同 key (这里用到了hash)的数据都到同一个内存 队列;然后对于 N 个线程,每个线程分别消费一个内存 queue 即可,这样就能保证顺序性。

kafka的高可用机制是什么?

你对Kafka事务了解多少

Kafka是在0.11 版本开始引入了事务支持。事务可以保证 Kafka 在 Exactly Once 语义的基 础上,生产和消费可以跨分区和会话,要么全部成功,要么全部失败。

  1. Producer 事务:

为了实现跨分区跨会话的事务,需要引入一个全局唯一的 Transaction ID,并将 Producer 获得的 PID 和 Transaction ID 绑定。这样当 Producer 重启后就可以通过正在进行的 Transaction ID 获得原来的 PID。

为了管理 Transaction,Kafka 引入了一个新的组件 Transaction Coordinator。Producer 就 是通过和 Transaction Coordinator 交互获得 Transaction ID 对应的任务状态。Transaction Coordinator 还负责将事务所有写入 Kafka 的一个内部 Topic,这样即使整个服务重启,由于 事务状态得到保存,进行中的事务状态可以得到恢复,从而继续进行。

  1. Consumer 事务:

上述事务机制主要是从Producer方面考虑,对于 Consumer 而言,事务的保证就会相对较弱,尤其时无法保证 Commit 的信息被精确消费。这是由于 Consumer 可以通过offset访问任意信息,而且不同的 Segment File生命周期不同,同一事务的消息可能会出现重启后被删除的情况。

指定了一个offset,Kafka怎么查找到对应的消息?

1.通过文件名前缀数字x找到该绝对offset 对应消息所在文件

2.offset-x为在文件中的相对偏移

3.通过index文件中记录的索引找到最近的消息的位置

4.从最近位置开始逐条寻找

简述Kafka的日志目录结构

每个partition一个文件夹,包含四类文件.index .log .timeindex leader-epoch-checkpoint
.index .log .timeindex 三个文件成对出现 前缀为上一个segment的最后一个消息的偏移 log文件中保存了所有的消息 index文件中保存了稀疏的相对偏移的索引 timeindex保存的则是时间索引
leader-epoch-checkpoint中保存了每一任leader开始写入消息时的offset 会定时更新
follower被选为leader时会根据这个确定哪些消息可用

producer 是否直接将数据发送到 broker 的 leader(主节点)

producer 直接将数据发送到 broker 的 leader(主节点),不需要在多个节点进行分发,为了帮助 producer 做到这点,所有的 Kafka 节点都可以及时的告知:哪些节点是活动的,目标topic 目标分区的 leader 在哪。这样 producer 就可以直接将消息发送到目的地了

consumer 是否可以消费指定分区消息?

consumer 消费消息时,向 broker 发出"fetch"请求去消费特定分区的消息,consumer指定消息在日志中的偏移量(offset),就可以消费从这个位置开始的消息,customer 拥有了 offset 的控制权,可以向后回滚去重新消费之前的消息。

Kafka 消息是采用 Pull 模式,还是 Push 模式?

pull 模式

Pull 模式的好处是 consumer 可以自主决定是否批量的从 broker 拉取数据。Push模式必须在不知道下游 consumer 消费能力和消费策略的情况下决定是立即推送每条消息还是缓存之后批量推送。如果为了避免 consumer 崩溃而采用较低的推送速率,将可能导致一次只推送较少的消息而造成浪费。Pull 模式下,consumer 就可以根据自己的消费能力去消费。

Pull 有个缺点是,如果 broker 没有可供消费的消息,将导致 consumer 不断在循环中轮询,直到新消息到 达。为了避免这点,Kafka 有个参数可以让 consumer 阻塞直到新消息到达

Kafka 存储在硬盘上的消息格式是什么?

消息由一个固定长度的头部和可变长度的字节数组组成。头部包含了一个版本号和 CRC32校验码。

消息长度: 4 bytes (value: 1+4+n)

版本号: 1 byte

CRC 校验码: 4 bytes

具体的消息: n bytes

Kafka 高效文件存储设计特点

(1).Kafka 把 topic 中一个 parition 大文件分成多个小文件段,通过多个小文件段,就容易定期清除或删除已经消费完文件,减少磁盘占用。

(2).通过索引信息可以快速定位 message 和确定 response 的最大大小。

(3).通过 index 元数据全部映射到 memory,可以避免 segment file 的 IO 磁盘操作。

(4).通过索引文件稀疏存储,可以大幅降低 index 文件元数据占用空间大小。

Kafka 与传统消息系统之间有三个关键区别

(1).Kafka 持久化日志,这些日志可以被重复读取和无限期保留

(2).Kafka 是一个分布式系统:它以集群的方式运行,可以灵活伸缩,在内部通过复制数据提升容错能力和高可用性

(3).Kafka 支持实时的流式处理

Kafka 创建 Topic 时如何将分区放置到不同的 Broker 中

副本因子不能大于 Broker 的个数;

第一个分区(编号为 0)的第一个副本放置位置是随机从 brokerList 选择的;

其他分区的第一个副本放置位置相对于第 0 个分区依次往后移。也就是如果我们有 5 个Broker,5 个分区,假设第一个分区放在第四个 Broker 上,那么第二个分区将会放在第五个 Broker 上;第三个分区将会放在第一个 Broker 上;第四个分区将会放在第二个Broker 上,依次类推;
剩余的副本相对于第一个副本放置位置其实是由 nextReplicaShift 决定的,而这个数也是随机产生的

Kafka 新建的分区会在哪个目录下创建

在启动 Kafka 集群之前,我们需要配置好 log.dirs 参数,其值是 Kafka 数据的存放目录,这个参数可以配置多个目录,目录之间使用逗号分隔,通常这些目录是分布在不同的磁盘上用于提高读写性能。当然我们也可以配置 log.dir 参数,含义一样。只需要设置其中一个即可。
如果 log.dirs 参数只配置了一个目录,那么分配到各个 Broker 上的分区肯定只能在这个目录下创建文件夹用于存放数据。

但是如果 log.dirs 参数配置了多个目录,那么 Kafka 会在哪个文件夹中创建分区目录呢?

答案是:Kafka 会在含有分区目录最少的文件夹中创建新的分区目录,分区目录名为 Topic名+分区 ID。注意,是分区文件夹总数最少的目录,而不是磁盘使用量最少的目录!也就是说,如果你给 log.dirs 参数新增了一个新的磁盘,新的分区目录肯定是先在这个新的磁盘上创建直到这个新的磁盘目录拥有的分区目录不是最少为止。

partition 的数据如何保存到硬盘

topic 中的多个 partition 以文件夹的形式保存到 broker,每个分区序号从 0 递增,且消息有序Partition 文件下有多个 segment(xxx.index,xxx.log)segment 文件里的 大小和配置文件大小一致可以根据要求修改 默认为 1g如果大小大于 1g 时,会滚动一个新的 segment 并且以上一个 segment 最后一条消息的偏移量命名

kafka 的 ack 机制

request.required.acks 有三个值 0 1 -1

  • 0:生产者不会等待 broker 的 ack,这个延迟最低但是存储的保证最弱当 server 挂掉的时候就会丢数据
  • 1:服务端会等待 ack 值 leader 副本确认接收到消息后发送 ack 但是如果 leader 挂掉后他- 不确保是否复制完成新 leader 也会导致数据丢失
  • -1:同样在 1 的基础上 服务端会等所有的 follower 的副本受到数据后才会受到 leader 发出的 ack,这样数据不会丢失

Kafka 的消费者如何消费数据

消费者每次消费数据的时候,消费者都会记录消费的物理偏移量(offset)的位置等到下次消费时,他会接着上次位置继续消费

消费者负载均衡策略

一个消费者组中的一个分片对应一个消费者成员,他能保证每个消费者成员都能访问,如果组中成员太多会有空闲的成员

kafaka 生产数据时数据的分组策略

生产者决定数据产生到集群的哪个 partition 中,每一条消息都是以(key,value)格式,Key 是由生产者发送数据传入,所以生产者(key)决定了数据产生到集群的哪个 partition

33.Java Consumer 为什么采用单线程来获取消息?

在回答之前,如果先把这句话说出来,一定会加分:Java Consumer 是双线程的设计。一 个线程是用户主线程,负责获取消息;另一个线程是心跳线程,负责向 Kafka 汇报消费者 存活情况。将心跳单独放入专属的线程,能够有效地规避因消息处理速度慢而被视为下线 的“假死”情况。

单线程获取消息的设计能够避免阻塞式的消息获取方式。单线程轮询方式容易实现异步非阻塞式,这样便于将消费者扩展成支持实时流处理的操作算子。因为很多实时流处理操作算子都不能是阻塞式的。另外一个可能的好处是,可以简化代码的开发。多线程交互的代码是非常容易出错的。

34.简述 Follower 副本消息同步的完整流程。

首先,Follower 发送 FETCH 请求给 Leader。接着,Leader 会读取底层日志文件中的消 息数据,再更新它内存中的 Follower 副本的 LEO 值,更新为 FETCH 请求中的 fetchOffset 值。最后,尝试更新分区高水位值。Follower 接收到 FETCH 响应之后,会把 消息写入到底层日志,接着更新 LEO 和 HW 值。

Leader 和 Follower 的 HW 值更新时机是不同的,Follower 的 HW 更新永远落后于 Leader 的 HW。这种时间上的错配是造成各种不一致的原因。

领导者副本(Leader Replica)和追随者副本 (Follower Replica)的区别。

Kafka 副本当前分为领导者副本和追随者副本。只有 Leader 副本才能 对外提供读写服务,响应 Clients 端的请求。Follower 副本只是采用拉(PULL)的方 式,被动地同步 Leader 副本中的数据,并且在 Leader 副本所在的 Broker 宕机后,随时 准备应聘 Leader 副本。

参考
参考
参考

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值