DelayedOperationPurgatory之DelayedOperation pool
purgatory就是炼狱的意思。
当一个DelayedOperation需要被delay时,它就被放到DelayedOperationPurgatory,相当于进行一个等待池。上一篇blog提到过,DelayedOperation想要摆脱delay状态,需要由事件来触发对它状态的检查,或者是超时时间到了。
这个逻辑看起来挺简单,但高效实现却挺复杂。0.9.0版本的Kafka重新设计了这个purgatory(相比0.8版本),设计思路在Kafka的这篇文档Purgatory Redesign Proposa。我翻译并注释了一下,放在Kafka之Purgatory Redesign Proposal (翻译)
purgatory的实现使用了两个缓存,这里先讲第一个。
直观的,我们需要一个key绑定到DelayedOperation上,来说明这个DelayedOperation会由哪些事件触发,而且一个DelayedOperation可以绑定到多个key, 一个key也可能跟多个DelayedOperation有关。所以这是一个多对多的映射,一边是事件,一边是DelayedOperation。
DelayedOperation pool
DelayedOperationPurgatory就提供了这种功能。它把这种映射保存到一个Pool里。这个Pool实际上是对一个ConcurrentHashMap的封装.
private val watchersForKey = new Pool[Any, Watchers](Some((key: Any) => new Watchers(key)))
Pool构造器的参数是一个value factory,即当这个pool里一个key没有value时,就用这个函数生成一个value。所以,对于value为空的key,这个pool就会构造一个watch这个key的Watchers.
Watchers
这个Pool的key是Any类型,也就是Scala里所有对象的基类,value是Watchers。注释里这么描述Watchers的
A linked list of watched delayed operations based on some key
Watchers把这些DelayedOperation保存在自己的一个instance field里
private[this] val operations = new LinkedList[T]()
由于Watchers是DelayedOperationPurgatory的内部类,T就源于DelayedOperationPurgatory的签名
class DelayedOperationPurgatory[T <: DelayedOperation](purgatoryName: String, brokerId: Int = 0, purgeInterval: Int = 1000)
extends Logging with KafkaMetricsGroup
所以operations这个域里保存的就是一个DelayedOperation的列表。
所以,DelayedOperationPurgatory用来保存DelayedOperation的数据结构是一个Map[Any, List[DelayedOpertion]]的结构。
对于Watchers来说,有两件事要做
- 当它关注的key有事件发生时,需要调用它的方法来遍历operations,找出其中可以被complete(即不再被delay)的operation。这个方法就是tryCompleteWatched
- 由于一个DelayedOperation可以对应多个key,所以当这个Watchers对应的key没有被触发,它保存的operations里的元素仍然可能由于其它的key触发而而被complete。所以外界需要能主动地检测这个Watchers里的哪些operation已经被complete了,并且移除这些元素。这个方法就是purgeCompleted。
做这两件事情的实机很重要,下面来分析一下
- 第一件事,在产生事件的地方进行检测就好。比如fetch线程处理fetch请求的过程,以及produce request的处理过程中,可以调用tryCompleteWatched。
- 第二件事的处理实机比较不好确定。因为当把一个request从某个key的watchers中移除以后,它可能还在另一个key的watchers里。而每次移除一个request,都要调用purgeCompleted显然不现实。但是0.9.0的实现中引用了新的数据结构来对request的超时进行检测,通过它可以准确获得某个时刻在purgatory中的请求数量(但并不是server中的DelayedOperation的数量,因为超时的DelayedOperation会被放入一个线程池执行它的回调,所以总的数量还需要加上线程池中的Operation数量, 而且这个线程池是一个FixedThreadPool,它使用一个无界的queue)。具体的作法请参照Kafka之Purgatory Redesign Proposal (翻译)
DelayedOperationPurgatory之DelayedOperation pool的更多相关文章
- DelayedOperationPurgatory之purgatory的实现
purgatory的超时检测 当一个DelayedOpeartion超时(timeout)时,它需要被检测出来,然后调用它的回调方法.这个事情看起来很简单,但做好也并不容易. 0.8.x的Kafka的 ...
- 添加 Pool Member - 每天5分钟玩转 OpenStack(123)
我们已经有了 Load Balance Pool "web servers"和 VIP,接下来需要往 Pool 里添加 member 并学习如何使用 cloud image. 先准 ...
- 创建 Pool & VIP - 每天5分钟玩转 OpenStack(122)
上节完成了 LBaaS 配置,今天我们开始实现如下 LBaaS 环境. 环境描述如下: 1. 创建一个 Pool “web servers”. 2. 两个 pool member “WEB1” 和 “ ...
- [转载】——故障排除:Shared Pool优化和Library Cache Latch冲突优化 (文档 ID 1523934.1)
原文链接:https://support.oracle.com/epmos/faces/DocumentDisplay?_adf.ctrlstate=23w4l35u5_4&id=152393 ...
- Ceph RGW 创建默认的pool
使用Ceph-deploy完成RGW服务部署后(最好是在部署RGW服务前建立如下这些pool),使用sudo ceph osd lspools 命令,会发现RGW自动以默认参数创建了N个rgw相关的p ...
- golang 裸写一个pool池控制协程的大小
这几天深入的研究了一下golang 的协程,读了一个好文 http://mp.weixin.qq.com/s?__biz=MjM5OTcxMzE0MQ==&mid=2653369770& ...
- 如何在Windows 2003+IIS6的环境下找回应用程序池(application pool)中的服务账号密码
上一篇文章说了说如何在Win2008+iis7中取出SharePoint管理账号密码的方法. 整个过程简单的讲,就是通过使用要找回密码的账号用来在SharePoint中创建一个临时的Web Appli ...
- 备忘-Sql server Timeout expired 超时时间已到. 达到了最大池大小 错误及Max Pool Size设置
select * from sysprocesses where dbid= db_id('数据库名') 通过此语句可查看目前所有的连接进程 不够了就必须设置Max Pool Size,理论最大值为3 ...
- SQL Server 2014新特性探秘(2)-SSD Buffer Pool Extension
简介 SQL Server 2014中另一个非常好的功能是,可以将SSD虚拟成内存的一部分,来供SQL Server数据页缓冲区使用.通过使用SSD来扩展Buffer-Pool,可以使得大量随 ...
随机推荐
- eclipse如何修改dynamic web module version;——eclipse操作备忘
1.eclipse如何修改dynamic web module version 一.修改工程属性: 右键eclipse的工程,选择属性,再选择Project Facets里面中选择Dynamic We ...
- javascript之面向对象程序设计(对象和继承)
总结的文章略长,慎点. 知识点预热 引用类型:引用类型的值(对象)是引用类型的一个实例.在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起.在其他面向对象语言中被称为类,虽然 ...
- js中的继承1--类继承
继承:function Animal(name){ this.name = name; this.showName = function(){ alert(this.name); } } functi ...
- Codevs 1078 ==Poj 1258 Agri-Net
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 53270 Accepted: 22140 Description D ...
- DataGrid3
a标签,DataGrid的数据绑定 1.function aa(id, url) { //alert(id); window.open(url + '&am ...
- mfc110ud.dll not found
mfc110ud.dll not found while debugging vs2012 MFC application. Possible Solutions: 1) >>>&g ...
- WP开发笔记——程序的退出方法
Windows Phone程序中,并没有之前的类似于“App.Exit()”之类的函数用来让你退出程序.这是怎么回事儿呢? 很简单,在Windows Phone 7中系统要求配备了硬件的“Back”键 ...
- centos下安装图像化界面
前面我们安装的centos系统多为没有图像化界面的命令行界面,为了安装oracle等工具,我们先为我们的centos安装图像化界面 使用命令为 yum groupinstall "Deskt ...
- jQuery EasyUI 数据网格 - 启用行内编辑(转自http://www.runoob.com/jeasyui/jeasyui-datagrid-datagrid12.html)
可编辑的功能是最近添加到数据网格(datagrid)的.它可以使用户添加一个新行到数据网格(datagrid).用户也可以更新一个或多个行.本教程向您展示如何创建一个数据网格(datagrid)和内联 ...
- 生成动态前缀且自增号码的Oracle函数
create or replace Function GetInvitationNO(prev varchar2, num1 varchar2, num2 varchar2, sessionSetti ...