kafka时间轮linux时间轮,关于kafka:解惑高深的Kafka时间轮原理原来也就这么回事

【摘要】 Kafka工夫轮是Kafka实现高效的延时工作的根底,它模仿了现实生活中的钟表对工夫的示意形式,同时,工夫轮的形式并不仅限于Kafka,它是一种通用的工夫示意形式,本文次要介绍Kafka中的工夫轮原理。

Kafka中存在一些定时工作(DelayedOperation),如DelayedFetch、DelayedProduce、DelayedHeartbeat等,在Kafka中,定时工作的增加、轮转、执行、沦亡等是通过工夫轮来实现的。(工夫轮并不是Kafka独有的设计,而是一种通用的实现形式,Netty中也有用到工夫轮的形式)

1. 工夫轮是什么

参考网上的两张图(摘自 https://blog.csdn.net/u013256…)

这两张图就比较清楚的阐明了Kafka工夫轮的构造了:相似事实中的钟表,由多个环形数组组成,每个环形数组蕴含20个工夫单位,示意一个工夫维度(一轮),如:第一层工夫轮,数组中的每个元素代表1ms,一圈就是20ms,当延迟时间大于20ms时,就“进位”到第二层工夫轮,第二层中,每“一格”示意20ms,依此类推…

对于一个提早工作,大体蕴含三个过程:进入工夫轮、降级和到期执行。

进入工夫轮

依据延迟时间计算对应的工夫轮“档次”(如钟表中的“小时级”还是“分钟级”还是“秒级”,实际上是一个一直“降级”的过程,直到找到适合的“档次”)

计算在该轮中的地位,并插入该地位(每个bucket是一个双向链表,可能蕴含多个提早工作,这也是工夫轮提高效率的一大起因,前面会提到)

若该bucket是首次插入,须要将该bucket退出DelayQueue中(DelayQueue的引入是为了解决“空推动”,前面会提到)

降级

当工夫“推动”到某个bucket时,阐明该bucket中的工作在以后工夫轮中的工夫曾经走完,须要进行“降级”,即进入更小粒度的工夫轮中,reinsert的过程和进入工夫轮是相似的

到期执行

在reinsert的过程中,若发现曾经到期,则执行这些工作

整体过程大抵如下:

2. 工夫的“推动”

一种直观的想法是,像事实中的钟表一样,“一格一格”地走,这样就须要有一个线程始终不停的执行,而大多数状况下,工夫轮中的bucket大部分是空的,指针的“推动”就没有本质作用,因而,为了缩小这种“空推动”,Kafka引入了DelayQueue,以bucket为单位入队,每当有bucket到期,即queue.poll能拿到后果时,才进行工夫的“推动”,缩小了 ExpiredOperationReaper 线程空转的开销。

3. 为什么要用工夫轮

用到提早工作时,比拟间接的想法是DelayQueue、ScheduledThreadPoolExecutor 这些,而工夫轮相比之下,最大的劣势是在工夫复杂度上:

工夫复杂度比照:

因而,实践上,当工作较多时,TimingWheel的工夫性能劣势会更显著

总结一下Kafka工夫轮性能高的几个次要起因:

(1)工夫轮的构造+双向列表bucket,使得插入操作能够达到O(1)的工夫复杂度

(2)Bucket的设计让多个工作“合并”,使得同一个bucket的屡次插入只须要在delayQueue中入队一次,同时缩小了delayQueue中元素数量,堆的深度也减小,delayqueue的插入和弹出操作开销也更小

点击关注,第一工夫理解华为云陈腐技术~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Spring Boot来整合Kafka时间来实现延时处理。下面是一个简单的示例: 首先,确保你已经在Spring Boot项目中添加了Kafka的依赖。可以在pom.xml文件中添加如下依赖: ```xml <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency> ``` 接下来,创建一个Kafka生产者来发送延时消息。你可以使用`KafkaTemplate`来发送消息。这是一个简单的示例: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.stereotype.Component; @Component public class KafkaProducer { @Autowired private KafkaTemplate<String, String> kafkaTemplate; public void sendDelayedMessage(String topic, String message, long delay) { kafkaTemplate.send(topic, message).get(delay, TimeUnit.MILLISECONDS); } } ``` 在这个示例中,`sendDelayedMessage`方法接受一个`topic`、消息内容`message`和延时时间`delay`(以毫秒为单位)。它使用`KafkaTemplate`发送消息,并设置了延时时间。 接下来,创建一个Kafka消费者来处理延时消息。你可以使用`@KafkaListener`注解来监听指定的topic并处理消息。这是一个简单的示例: ```java import org.springframework.kafka.annotation.KafkaListener; import org.springframework.stereotype.Component; @Component public class KafkaConsumer { @KafkaListener(topics = "your-topic") public void receiveMessage(String message) { // 处理收到的消息 System.out.println("Received message: " + message); } } ``` 在这个示例中,`receiveMessage`方法使用`@KafkaListener`注解来监听名为"your-topic"的Kafka主题,并在收到消息时进行处理。 最后,你可以在需要发送延时消息的地方调用`KafkaProducer`的`sendDelayedMessage`方法,将延时消息发送到Kafka中。 注意:这只是一个简单的示例,实际应用中可能需要更复杂的逻辑来处理延时消息。你可能需要使用时间算法来管理延时消息的触发和删除。你可以在项目中引入第三方库来实现时间的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值