分布式流处理组件 您所在的位置:网站首页 kafka数据延迟如何处理 分布式流处理组件

分布式流处理组件

2023-05-26 04:21| 来源: 网络整理| 查看: 265

💯 作者:谢先生。 2014年入行的程序猿。多年开发和架构经验。专注于Java、云原生、大数据等技术。从CRUD入行,负责过亿级流量架构的设计和落地,解决了千万级数据治理问题。

📖 微信公众号、B站:搜索「谢先生说技术」不定时更新 ~

📂 清单: goku-framework、【定期开源】享阅读II

前言

经过上一章的介绍,我们从配置参数方面了解到一部分生产调优的方式。当然:

参数需要我们通过实际配置进行适当的调整,这是不可避免的~

而本章内容我们从数据可靠性下功夫,当然本文内容理论居多,稍微略显枯燥~

数据可靠性

关于数据可靠与否如何操作,我们在前面已经介绍的多次,主要就是通过配置acks来保证。

这里我不会重复介绍acks的配置参数之类的,但是其中某一个配置项必须单拎出来,需要用它来引出一批非常重要的概念。这就是acks=all。

acks=all: 当消息在Leader接收记录,并且等待副本数据同步完成之后,才会返回ack

那这时我们就需要考虑一个问题:如果Follower挂掉怎么办?这不影响执行效率么~ 别急,Kafka引入了如下方式来解决这个问题

ISR、OSR、AR

topic isr

Kafka的分布式模型为主从架构,Leader负责数据的读写操作,Follower仅仅处理数据同步与备份。在这种模式下,如果Leader由于种种原因出现异常情况,其他Follower将会选举推出新的Leader进而保证整个集群的健康运行。

可是啊,如何保证重新推举出来的Leader的数据是最完善的呢?如果由于种种原因导致同步异常,而选举出来的Leader却是一台数据最烂的节点,对整个集群来讲,多闹心啊~

能有多闹心呢? 往⬇️看,就知道了。 同时,Kafka也为我们解决了这一问题,这就是接下来我们要强行插入的内容

HW、LEO

一个桶能装多少水,从来都是最低的那个木板决定的

在Kafka中,为了解决Leader和Follower之间消息同步的问题,引入了HW、LEO的机制。如图: 2023-04-09-16-52-21

LEO表示当前日志文件中下一条待写入消息的位置,也可以说是当前日志文件最后一条消息再加一的位置。同时分区ISR集合中的每一个副本都会维护自身的LEO。

HW俗称高水位。表示一个特定消费的偏移量,消费者在消费的时候只能消费到HW之前的数据。而HW的最高位置是ISR集合节点中LEO最小的值

image.png

-- 这是一条分割线

继续介绍ISR

在Kafka中,所有分区副本组成的集合可以成为AR。 而在AR集合中,与Leader保持正常通信,并且同步数据正常的Follower副本,再加上Leader本身能够组成ISR集合。如果Leader不幸挂掉,那么只有ISR集合内的Follower副本能够竞争上岗~

在ISR集合中,如果Follower长时间内【默认30s】不能向Leader发送通信数据或同步数据,那么就会将该Follower从ISR集合中剔除。被ISR剔除的副本将会进入到OSR集合中

我们可以通过replica.lag.time.max.ms来设置副本通信时间

如何确保数据不丢失

前面介绍了acks=all的同步机制,如果我们想要保证数据可靠性,acks=all这个配置时必不可少的

我们做过多次实验

同时数据有备份,ISR集合>1也是需要滴~~ 所以,记住这句话: - (acks=all) + (分区副 本>= 2) + (ISR >= 2)是保证数据可靠性的重要指标

数据重复

在生产端,acks=all出现最大的问题:数据重复 其实数据重复属于一种正常现象,非正常波动现象造成的数据重试是造成数据重复的主要原因。而出现数据重试的大概率能有如下场景:

Leader分区宕机,Kafka进入Leader选举阶段~ Controller所在Broker宕机,集群进入Controller选举阶段~ 网络分区等因素影响~

消费端处理消息,offset维护过程中宕机,重启消费端之后如果再次消费也将造成数据重复。 而关于消费端如何处理消息重复消费我们在后面介绍,本章只介绍Producer的解决方案。 敬请期待~

消息投递

消息在投递的时候可以按照这三种方式来投递:

最多一次: 消息最多只会被发送一次,不会重复发送,数据有可能会被丢失。

acks=0属于典型场景

至少一次: 消息最少会被发送一次,消息不会丢失,有可能重复发送。 精确一次: 消息只发一次,消息不会丢失并且消息不会重复发送。

幂等/事务 + 至少一次 = 精确一次

精确一次的投递方式可以靠如下方案来解决:

幂等 事务

幂等和事务都是在kafka 0.11之后的版本引入的,通过这两种方式可以解决Producer端消息重复的问题。当然这两种方案在处理过程中都是有一定的限制,接下来我们具体来看

幂等

同样运算逻辑下,每次执行的结果都是一样的。这就是幂等性。很多情况下我们开发的接口都需要保证幂等性。

而kafka是这么判断的:

当三者组成的主键唯一时,提交到broker的消息才会被持久化

那么到底是什么东西呢?

Producer每次在启动的时候,会申请到一个全局唯一的PID,且Producer或者Kafka每次重启之后都会进行重新分配 Partition就是对应的分区号 SeqNumber是分区内单调递增的序号 image.png

所以其实从这里我们就能明白,如果想要通过幂等来解决数据重复的话,有一个必要的条件

单分区单会话

想要在程序中开启幂等,需要这样做

config.setProperty(ProducerConfig.ACKS_CONFIG, "all"); config.setProperty(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true"); config.setProperty(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "5");

这样我们就能在Producer开启幂等,同时我们需要注意:

acks必须配置为all 开启幂等时配置的max.in.flight.requests.per.connection


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有