客户端的一个请求包括多个分区,服务端为每个请求都会创建一个延迟操作对象,而不是为每个分区创建一个延迟操作对象。服务端的“延迟操作缓存”管理了所有的“延迟操作对象”,缓存的键是每一个分区,缓存的值是分区对应的延迟操作列表。

  1. 分区与延迟操作的映射关系
    如图6-56所示,假设第一个延迟操作包含的分区有[Pl,P2,P3,P4,P5],第二个延迟操作包含的分区有[Pl,P3,P5,P6,P7]。在延迟缓存中,从分区的角度来看,分区Pl上有两个延迟的操作,分区P2上只有一个延迟的操作,分区P3上有两个延迟的操作。

下面的代码模拟了延迟缓存(Purgatory)添加或删除延迟操作(Operation)的方法。延迟操作有多个分区,延迟缓存保存了分区到延迟操作的映射关系。延迟缓存的watch()方法会将延迟操作对象加入到每个分区的值列表中。比如第一个延迟操作对象有[凹,凹,月,问,PS]这5个分区,那么延迟缓存中对应有5个映射关系,分别是[Pl->Operationl,P2->0perationl,P3->0perationl,P4->0perationl,PS->Operationl]。第二个延迟操作对象有[Pl,月,町,问,P7]这5个分区,延迟缓存会更新为7个元素:[Pl->List(Operationl,Operation2),P2->0perationl,P3->List(Operationl,Operation2),P4->0perationl,PS->List(Operationl,Operation2),P6->0peration2,P7->0peration2]。

每个延迟操作对象都是一个带有超时的线程类。当延迟操作完成时,延迟缓存会调用remove()方法将延迟操作从延迟缓存中移除。比如,从延迟缓存中移除第二个延迟操作(Operation2)后,延迟缓存会从每个分区的值列表中删除第二个延迟操作。最后延迟缓存会更新为[Pl->Operation2,P3->0peration2,PS->Operation2,P6->0peration2,P7->0peration2]。相关代码如下:

注意:延迟缓存watch()和remove()方法的参数都是延迟操作对象,两者分别表示监控延迟的操作,或者移除延迟操作的监控。

一个客户端请求对应一个延迟的操作,一个延迟操作对应多个分区。在延迟缓存中,一个分区对应多个延迟操作。因为延迟操作的外部事件以分区为粒度,所以延迟缓存保存了分区到延迟操作的映射关系。延迟操作加入到延迟缓存,以分区作为缓存的键。外部事件也是从分区的角度,尝试完成延迟的操作。

  1. 根据分区尝试完成延迟的操作
    不同的延迟操作可能会有相同的分区,比如主题的副本数等于4,就会有3个备份副本向主副本同步数据。邢么主副本所在的服务端针对3个备份副本的拉取请求,就会存在3个延迟的拉取操作。但对于消费者而育,不同消费者的拉取请求,它们的分区一定不会相同。如图6-57所示,分区Pl和凹的主副本在消息代理节点l上,有3个角色都和主副本有关:生产者、消费者、备份副本。
(1)生产者向主副本追加消息,生产请求包含2个分区。
(2)2个消费者向主副本发送拉取请求,每个拉取请求都只拥有不同的分区。
(3)3个备份副本所在的悄息代理节点向主副本发送拉取请求,每个拉取请求都包含2个相同的分区。

图6-57中黑色的民条表示延迟的操作对象,服务端一共创建了6个延迟的操作对象。在延迟缓存中,只有2个键,分别是分区Pl和l分区P2,这2个分区在延迟缓存中对应的值如下。

  • 分区Pl对应:延迟的生产、消费者l的延迟拉取、3个备份副本的延迟拉取,总共有5个延迟操作。
  • 分区P2对应:延迟的生产、消费者2的延迟拉取、3个备份副本的延迟拉取,总共有5个延迟操作。

外部事件以指定的键尝试完成延迟操作,图6-58是图6-57的简化版本。消息代理节点l上仍然有2个分区,消费者和备份副本拉取主副本的方式保持不变,但生产者只写消息到分区Pl。图6-58中分区Pl相关的延迟操作用实线箭头表示,分区P2相关的延迟操作用虚线箭头表示。3个备份副本的延迟拉取除了拉取分区Pl,也会拉取分区凹,具体步骤如下。

(1)生产者追加消息集到分区Pl的主副本,由于ISR的备份副本还没有发送应答,服务端创建延迟的生产。延迟缓存的内容为P1->DelayedProduce。
(2)消费者拉取分区凹的主副本消息,由于读取的字节数不够,服务端创建延迟的拉取(DelayedFetch1)。延迟缓存为P1->List(DelayedProduce,DelayedFetch1)。
(3)分区凹的第一个备份副本(第二个消息代理节点)发送拉取请求,拉取请求包括2个分区。由于读取的字节数不够,服务端创建延迟的拉取(DelayedFetch2),延迟缓存为P1->List(DelayedProduce,DelayedFetch1,DelayedFetch2),P2->DelayedFetch2o
(4)分区Pl的第二个备份副本(第三个消息代理节点)发送拉取请求,拉取请求包括2个分区。由于读取的字节数不够,服务端创建延迟的拉取(DelayedFetch3),延迟缓存为P1->List(DelayedProduce,DelayedFetch1,DelayedFetch2,DelayedFetch3),P2->List(DelayedFetch2,DelayedFetch3)。
(5)分区凹的第三个备份副本(第四个消息代理节点)发送拉取请求,拉取请求包括2个分区。由于读取的字节数不够,服务端创建延迟的拉取(DelayedFetch4),延迟缓存为P1->List(DelayedProduce,DelayedFetch1,DelayedFetch2,DelayedFetch3,DelayedFetch4),P2->List(DelayedFetch2,DelayedFetch3,DelayedFetch4)。
(6)服务端处理分区Pl前2个副本的拉取请求,尝试完成延迟的生产不能完成。服务端在处理第三个备份副本的拉取请求时,可以完成延迟的生产操作,返回分区Pl的生产结果给生产者。延迟的生产完成后,延迟缓存为:P1->List(DelayedFetch1,DelayedFetch2,DelayedFetch3,DelayedFetch4),P2->List(DelayedFetch2,DelayedFetch3,DelayedFetch4)。,
(7)在步骤(6)之后,分区Pl的主副本增加了最高水位。但因为最高水位和拉取偏移蓝的差距,仍然不满足拉取请求的最少字节数,服务端尝试完成消费者的延迟拉取也不能完成。
(8)生产者再次追加消息到分区凹,如果追加新的消息后,主副本的偏移量减去备份副本拉取请求的偏移量,满足拉取请求的最少字节数,服务端就可以完成3个备份副本的延迟拉取。虽然备份副本的拉取请求包含2个分区,但只要读取的总大小满足最少字节数,服务端就可以返回拉取结果给备份副本。3个备份副本的延迟拉取完成后,延迟缓存为P1->DelayedFetch1。
(9)当增加主副本的最高水位,并且最高水位减去消费者的拉取偏移量大于最少字节数,服务端才可以完成消费者的延迟拉取,并返回拉取结果给消费者。消费者的延迟拉取也完成后,延迟缓存为空。

总结下服务端处理生产请求、拉取请求过程中与延迟操作相关的几个重要知识点。

(1)服务端在读取或写入本地日志后,因为生产请求要等待ISR集合的所有副本发送应答,拉取请求要等待收集足够的消息,所以服务端会创建延迟的生产和延迟的拉取,并放入延迟缓存中。加入到延迟缓存的延迟操作,在外部事件发生时,会尝试完成延迟的操作。
(2)一个延迟操作有多个分区,加入到延迟缓存中,键是每个分区,值是分区对应的延迟操作列表。外部事件发生时,服务端会以分区为粒度,尝试完成这个分区中的所有延迟操作。如果指定分区对应的某个延迟操作可以被完成,那么延迟操作会从这个分区的延迟操作列表中移除。但这个延迟操作还有其他分区,其他分区中已经被完成的延迟操作也需要从延迟缓存中删除。
(3)仍然以前面的示例为例,3个备份副本的延迟拉取都有2个分区Pl和凹,延迟缓存为[P1->L"ist(DelayedOperat"io『12,Delayed0perat"ion3,Delayed0perat"ion4),P2->L"ist(Delayed0perat"ion2,Delayed0perat"ion3,DelayedOperat"ion4)]。如果分区Pl的主副本新追加了一批消息,3个延迟拉取都收集到足够的消息,延迟缓存会删除分区Pl的所有延迟操作,只留下[P2->L"ist(Delayed0perat"ion2,Delayed0perat"ion3,DelayedOperat"ion4)]。最后,分区P2中的延迟操作也应该删除,因为这3个延迟操作实际上都已经完成了。

在具体实现上,外部事件通过指定分区尝试完成延迟的操作,如果延迟操作可以完成,其他分区中的延迟操作并不会被立即删除。这是因为分区作为延迟缓存的键,在服务端的数量会很多,如果一个个检查所有的分区,再从延迟缓存中删除已经完成的延迟操作,速度就会很慢。另外,如果采用这种方式,只要分区对应的延迟操作完成了一个,就要立即检查所有分区,对服务端的性能影响比较大。以上面的示例为例,外部事件根据分区Pl尝试完成延迟的操作,最多只会删除分区Pl中可以完成的延迟操作,并不会删除其他分区中已经完成的延迟操作。Kafka的延迟缓存还有一个清理器,会负责定时地清理所有分区中已经完成的延迟操作。下面再以延迟拉取和延迟生产为例,分析这两种延迟操作的工作过程。

  1. 延迟拉取的示例
    如图6-59所示,3个分区的主副本在消息代理节点1,其他3个消息代理节点分别保存2个分区的备份副本。分区Pl有2条消息,分区P2有l条消息,分区P3有2条消息。3个消息代理节点向主剧本同步数据时,都不满足最少的5字节,服务端创建3个延迟的拉取操作。

如图6-60所示,生产者往分区Pl新追加了一条消息(深灰色方块),服务知会尝试完成分区Pl对应的延迟拉取。由于消息代理节点2对应的延迟拉取,它的数据仍然不足5字节,服务端不会完成延迟拉取;消息代理节点4对应的延迟拉取,它的数据满足5字节,服务端可以完成这个延迟拉取。

如图6-61所示,生产者继续往分区Pl追加2条消息,消息代理节点2和消息、代理节点4继续同步分区Pl的主副本数据,如果它们对应延迟拉取对象的数据都已经足够了服务端就都可以完成这两个延迟的拉取。

如图6-62所示,从延迟缓存保存的数据来看,生产者追加消息到分区Pl,第一种场景完成了消息代理节点4对应的延迟拉取,第二种场景完成了消息代理节点2对应的延迟拉取,第三种场景则完成了消息代理节点2和消息代理节点4对应的延迟拉取。图6-60对应了第一种场景,医16-61对应了第三种场景。

注意:图6-62中外部事件根据指定分区尝试完成的延迟操作,用删除线和浅色字体表示。其他分区中完成的延迟操作用浅色字体表示,它们并不会立即从延迟缓存中删除,而是通过延迟缓存的清理器被定时清理掉。

延迟拉取共有两种:备份副本和消费者的拉取。备份副本或消费者的拉取请求都可以有多个分区,但服务端完成延迟的拉取操作并不需要等待所有分区都收集够最少字节数,它只需要所有分区加起来的大小满足最少字节数,就可以返回拉取结果给备份副本或消费者。与拉取请求相反,生产请求如果有多个分区,服务端完成延迟的生产操作,必须等待所有分区都被ISR所有剧本同步后,才会返回生产结果给生产者。下面以服务端处理延迟生产的过程为例展开讲解。

  1. 延迟生产的示例
    如图6-63所示,服务端处理多个分区的生产请求,并将延迟操作加入延迟缓存。假设拉取请求的最少字节数等于l字节,这样服务端就可以不考虑备份副本的延迟拉取,具体步骤如下。
(2)服务端为生产请求创建一个延迟的生产,延迟缓存中3个分区都对应了同一个延迟的生产。
(3)消息代理节点2上分区Pl的备份副本同步了消息代理节点l上主副本的消息,但服务端还不能
完成延迟的生产,因为所有分区的主副本并没有全部收到应答。
(4)分区凹的备份副本同步了主副本的消息,服务端仍然不能完成延迟的生产。
(5)分区凹的备份副本同步了主副本的消息,服务端可以完成延迟的生产,因为所有分区的主剧本都收到了备份副本的应答。延迟缓存会删除分区P3的延迟生产,但不会立即删除其他分区中的延迟生产。分区Pl和分区P2中已经完成的延迟生产,会通过延迟缓存的清理器删除。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210422213511304.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1dBTlRBV0FZMzE0,size_16,color_FFFFFF,t_70)上面几节通过多个示例分析了延迟缓存如何管理延迟操作,下面接着分析延迟缓存的具体实现。

6.3.2 延迟操作与延迟缓存相关推荐

  1. 6.3.1 延迟操作接口

    6.3 延迟操作 Kafka的服务端处理客户端的请求,针对不同的请求,可能不会立即返回响应结果给客户端.比如,生产者设置的应答值等于-I,服务端必须等待ISR所有副本都同步完消息,才会发送生产结果给生 ...

  2. swift5主线程延迟操作的几种写法

    swift5主线程延迟操作的几种写法 swift写法 @objc func delayExecution(){debugPrint("delayExecution")}func t ...

  3. kafka的延迟操作-pull操作详解

    kafka的延迟操作和正常我们服务端处理事件的方式不一样,我们服务器正常情况下处理数据都是尽可能快的返回当前的结果,但是kafka的延迟操作不一样: 比如生产者发送ack=-1的数据到服务端leade ...

  4. linux内核时间管理(一) : 时间概念和延迟操作

    内核中的时间概念 HZ: Linux 核心每隔固定周期会发出timer interrupt (IRQ 0),HZ是用来定义每一秒有几次timer interrupts.举例来说,HZ为1000,代表每 ...

  5. GCD全解-dispatch_after/dispatch_time-t延迟操作

    文章目录 1.延后执行:dispatch_after 2.延长时间:dispatch_time_t 3.拓展 1.延后执行:dispatch_after 延时操作的API,通常Queue会在主线程,但 ...

  6. LDD3源码分析之时间与延迟操作

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz 编译环境:Ubuntu 10.10 内核版本:2.6.32-38-generic-pae LDD3源码路径:exam ...

  7. redis mysql主从延迟_MySQL主从延迟问题解决

    今天我们就来看看为什么会产生主从延迟以及主从延迟如何处理等相关问题. 坐好了,准备发车! 主从常见架构 随着日益增长的访问量,单台数据库的应接能力已经捉襟见肘.因此采用主库写数据,从库读数据这种将读写 ...

  8. (99)FPGA最大延迟与最小延迟基础

    (99)FPGA最大延迟与最小延迟基础 1 文章目录 1)文章目录 2)时序约束引言 3)FPGA时序约束课程介绍 4)FPGA最大延迟与最小延迟基础 5)技术交流 6)参考资料 2 时序约束引言 1 ...

  9. 相位延迟和群延迟的区别

    其实已经是期末考试的前两天了,但是为了彻底了解相位延迟与群延迟的区别,我硬是把专业相关书籍过了个遍,因为网上相关解释非常少或者不清楚.当然这也是我现在写这篇文章的原因之一.接下来请听我详细道来: (注 ...

最新文章

  1. java与数据结构(4)---java实现双向循环链表
  2. ElasticSearch搜索引擎:常用的存储mapping配置项 与 doc_values详细介绍
  3. exchange2010使用通配符造成的不停的需要输入密码却访问不了
  4. 古登堡是垂直搜索引擎吗_网站排名,提高内容输出频率,就一定要对排名好吗?-SEO...
  5. Java 9幕后花絮:新功能从何而来?
  6. java学习(72):GUL流式布局管理器
  7. 基于JSP的数据库增删改查实现
  8. 阿里云服务器ECS和腾讯云服务器如何安装宝塔面板?
  9. 支持蓝牙的模拟器_横竖都能玩的小鸡G6,蓝牙连接尽情享受手游乐趣
  10. stm32h743单片机嵌入式学习笔记2-单片机获取电容触摸屏原理
  11. jsDoc的使用文档
  12. 网络投票专家投票计算_安全专家说在线投票是一个坏主意。 这就是为什么。
  13. php网页无法显示图片,XP系统中,网页图片无法显示怎么解决?
  14. 利用Pygame制作跳跃的小球游戏
  15. uPDF:免费功能强大的 PDF 全能工具箱, PDF 文件处理利器
  16. 7-1 统计字符串中不同种类的字符个数 (10 分)
  17. 我是如何防止老公变成渣男的
  18. 用python把视频分解成图片
  19. 借助CSS Shapes实现元素滚动自动环绕iPhone X的刘海 #精选JAVASCRIPTCSSCHROMECSS3APPLE
  20. 发网易emil 报错javax.mail.AuthenticationFailedException: 550

热门文章

  1. 堆栈溢出:Stack overflow (参数: 0x0000000000000001, 0x0000005410A03FF8)
  2. ROS入门、ROS完整教程
  3. UltraEdit v14.00注册码
  4. 舒伯特小夜曲(钢琴版)
  5. weblogic BEA-000362问题
  6. PS笔刷:150个天气套装
  7. 拿板砖的老股民说股市
  8. c语言错误c1010怎么办,fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include stdafx.h...
  9. Opencv4.0学习记录(Day21 视频文件摄像头使用)
  10. [BUG 记录] Unable to determine the device handle for GPU 0000:05:00.0: GPU is lost. Reboot the system