kafka

1.HW,LW,LEO,AR,ISR,OSR,AR各代表什么意思?

名词解释

ACKS(Acknowledgments)确认、回执

LW(Low watermark)低水位、LSO(Log start offset)起始偏移量

HW(High watermark)高水位

LEO(Log end offset)日志末尾偏移量

AR(Assigned replica)分配的副本

ISR(In sync replica)正常同步的副本

OSR(Out sync replica)非正常同步的副本

消息生产和消费流程

以单副本为例,生产者(Producer)包装消息指明Topic后消息到达Broker中的分区(Partition),此时数据在Broker服务程序中;Broker将数据写到内核缓存页(Page cache),此时数据在物理内存;最后按照配置的刷盘策略写到磁盘中的消息日志(Log)中。

刷盘频率如果太高,会影响服务性能;如果频率太低,Broker宕机,在内存中未写到磁盘的消息会丢失。所以需要在效率和数据完整性之前做权衡(Trade off)来配置合适的策略。

消费者(Consumer)与服务器建立连接向Broker发送拉取消息请求,请求信息先到达网卡再到达Broker;Broker通过系统调用sendfile将读取到缓存页中的数据直接拷贝到网卡中,也就是零拷贝技术,最终数据返回给消费者。消费者消费完后还需要主动向Broker提交请求来更新消费进度。

image-20210918160436277

ACKS三种类型

生产者(Producer)向Broker发送消息时,可以配置等待确认ACKS(Acknowledgments)的策略0、1和-1。

0代表不等待Broker确认,在这种情况下,不能保证服务器已经收到了记录。

-1和1都需要等待Broker返回确认。

1代表这个确认是Broker将消息写到主(Leader)磁盘后返回,不用等待从(Follower)同步。

-1则代表应答需要等待所有正常同步的副本ISR(In sync replica)写到消息日志(Log)后才会返回。

AR、ISR、OSR

AR(Assigned replica)已分配的副本指主题(Topic)创建时设置的副本,所有副本包括主(Leader)和从(Follower)都归属AR。

ISR(In sync replica)正常同步的副本和OSR(Out sync replica)非正常同步的副本是指从副本的两种状态,有周期性任务将副本按这个状态进行进行划分。

判断条件有两个:(1)根据从和主同步的超时时间判断,配置参数rerplica.lag.time.max.ms=10000;(2)根据从与主消息条数差值盘,配置参数rerplica.lag.max.messages=4000。

AR = ISR + OSR

ISR机制

在ACKS策略配置为-1的时候,需要等待所有ISR(In sync replica)集合中的副本将消息写入消息日志(Log)后才会给生产者(Producer)返回确认。以3个副本(Replica)为例,开始是都是正常同步,此时ISR集合中副本为3个。在同步消息[4]的时候Broker2上的副本出现网络问题或者宕机超过设置的超时时间,周期任务扫描到后将其划分到了OSR(Out sync replica)集合,给与了生产者确认。后续消息确认不再等待这个副本。

当OSR集合中的副本恢复并与主副本同步数据追平后,又会被周期任务扫描划分回ISR集合中。

image-20210918150431039

LSO、LEO、LW、HW

LEO(Log end offset)日志末尾偏移量是新消息写入时将分配的偏移量(Offset)值,从0开始,随着消息不断写入递增。

LW(Low watermark)低水位,代表AR(Assigned replica)集合中最小的LSO(Log start offset)起始偏移量。旧日志的清理和消息删除都有可能促使LW的增长。

HW(High watermark)高水位代表ISR(In sync replica)集合中最小的LEO。

比如当ACKS(Acknowledgments)配置为1时,不需要等待从(Follower)就会给生产者(Producer)返回确认,这就可能会导致从还没来得急同步。此时ISR集合中最小的LEO没有变化,就代表HW不变,消费者还无法消费到新的数据。

消费者能消费的数据 = [LW,HW)

image-20210918153959411

2.kafka如何保证消息的顺序性?

可以通过message的key来定义,同一个key的message可以保证只发送到同一个partition,比如说key是userid,table的rowid等,所以同一个user或者同一个record消息永远都只会发送到同一个partition上。

3.kafka的集群结构

名词解释
Broker(Kafka服务)
Controller(唯一充当控制器的Kafka服务)
Topic(消息主题,一个主题包含多个)
Partition(消息分区),Replica(分区副本),Leader(主分区),Follower(从分区)
Metadata(元数据,集群结构、状态等信息)
Offset(消息偏移量),Current-offset(消费进度/消费偏移量),Log-end-offset(分区最大消息偏移量)
Producer(消息生产者,业务服务)
Consumer(消息消费者,业务服务)
Group(消费组,一个组包含多个消费者)
Kafka集群结构关系
Broker等于每一个Kafka服务,是一个JVM进程。

Topic是一个逻辑概念,生产和消费消息都需要指定Topic,不同业务的消息一般放在不同的Topic中。

一个Topic的消息可以按每条的粒度分片到不同的分区(Partition),分区分配在不同的Broker上,解决单机CPU和IO等性能瓶颈。

一个分区又分为一到多个副本(Replica),是一主(Leader)多从(Follower)的结构。主负责提供服务,从只负责同步和在主宕机的时候顶替主来实现高可用。

image-20210917174717922

Kafka和Zookeeper

Kafka集群需要依赖Zookeeper作分布式协调,保存状态和实现选主。Kafka集群中会选出一个Broker来充当控制器(Controller),控制器负责管理分区和副本的状态以及执行管理任务,例如重新分配分区。最终这些数据保存在Zookeeper中称之为元数据(Metadata)。

Zookeeper高可靠性适合做分布式协调,但是不太适合高并发的访问和大量的IO交互,以前客户端读取元数据,维护消息偏移量(Offset)都需要经过Zookeeper。而新版本Kafka为了减轻Zookeeper的负担将很多请求转移到了Broker上,客户端可以通过Broker获取所有Broker的地址、维护消息偏移量、访问其他元数据、创建Topic、分区、副本等等。

高性能磁盘IO

Kafka消息最终是要保存到磁盘上的,最终顺序写入.log日志,这是它能够保证高性能的原因之一,磁盘的顺序读写效率远高于随机读写,减轻了磁盘寻址压力。另外还需要维护索引到.index和.timeindex来对.log进行检索。

消息生产和消费生产者(Producer)

生产消息指明归属的Topic推送给Broker,消息经过哈希取模算法分配到某一个分区(Partition),各个分区副本进行同步。

消费者(Consumer)指明Topic对其中消息进行消费,并且需要指明消费者归属的消费组(Group),消费组一般用来区分不同的业务线,不同消费组之间消费进度是隔离的。

消费者通过长轮询Broker批量拉取消息到本地,这样消费者可以按照自己的消费能力按需拉取消息,消费完后向Broke提交更新消费进度(Current-offset),一次拉取可能会拉到不同分区的消息,不同分区的消费进度分开维护。

一条消息可以让多个消费组进行消费,但是在一个消费组中只能有一个消费者可以消费到这条消息。

在同一消费组中,一个分区只能由一个消费者消费,但是一个消费者可以消费多个分区的消息。假如两个消费进度不一样消费者消费同一分区,更新消费进度的时候就会产生混乱导致重复消费和消息丢失等问题。
image-20210918094918012

消费进度提交方式
消费者(Consumer)可以手动或者自动提交消费进度(Current-offset)。

自动情况下,拉取完消息,程序经过配置的间隔时间后异步自动向Broker更新消费进度,这种方式性能较高但是容易产生重复消费和消息丢失问题。假如程序消费速度慢,还未消费完就自动提交了,此时宕机重启后消费不到当时未来得及消费的消息了,因为消费进度已经更新,产生了消息丢失问题。假如程序消费速度快,消费完还未到自动提交的时间宕机了,消费进度没更新,重启后又会重复消费到之前的消息,产生了重复消费问题。

手动提交则比较灵活,可以按条、分区、拉取的粒度提交消费进度。粒度越小,可靠性越高,但是由于提交频繁性能较低;粒度越大,可靠性越低,但是提交频率较低,多条数据还可以考虑并行执行,所以性能较高。

如何保证消息顺序消费
如果不需要保证消息顺序,分区可以任意横向扩展。

如果消息需要保证顺序,就得保证消息推送给Broker时是有序的,并且消息要指定同一消息键(Key),相同键的消息会被分配的同一个分区(Partition),Broker能保证同一分区的消息按接收的顺序保存。再由一个消费者(Consumer)消费这个分区的消息,并且消费的时候也要保证顺序。

不同键的消息可能会互相穿插保存在同一个分区,但是统一分区相同键的消息是保证顺序的。image-20210918105542227

什么是长轮询
常见获取消息方式有轮询、推送、和长轮询。

轮询是指消费者(Consumer)定时向消息队列(Message queue)获取消息。优点是可以按消费者自己的消费能力控制消费进度。缺点是轮询有时间间隔,消息获取不及时;没有消息时也会不停的空轮询,无用的建立、断开连接产生性能消耗。

推送是指消息队列主动向消费者推送消息。优点是能较及时让消费者收到消息。缺点是消费者消息能力是不一定的,消费不过来的时候会产生阻塞,不太好控制。为解决这问题,消费者需要告知消息队列消费进度,消息队列保存这个状态根据情况来推送消息。Apache ActiveMQ就是使用的这种。

长轮询是一种折中方案,定时轮询消息队列来获取消息。在没有消息的时候连接会保持,直到有消息返回,或者经过设置的超时时间后再断开重新轮询。这样可以根据能力按需消费,也可以避免空轮询问题。Kafka和借鉴Kafka开发的RocketMQ就是使用的这种。
 

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值