云服务器

osd处理网络请求的过程——定时器

2017-12-25 11:04:17 0

回顾:

前两篇大概分析了osd的基本启动流程,对其有了一个初步了解,然后又部署了inkscope,以便能形象地监控ceph集群的状态。接下来开始深入了解osd内部的动作,先从osd类开始。首先看它的定时器部分。

Osd定时器分析:

Osd有一些定时任务如定时触发heartbeat,定时器是必不可少的。

Osd4个定时器用于不同的场景,他们都是SafeTimer的实例。

SafeTimer的结构比较简单,如下图:

主要由SafeTimer和它的友员类SafeTimerThread构成。

SafeTimerThread:继承Thread,它只为执行SafeTimer::timer_thread函数提供运行线程。

SafeTimer:定时器的算法实现类。关键的成员变量是:schedule和events。关键的成员函数是:addeventaftert和addeventat schedule成员是一个std::multimap,以到期时间为key,回调类为value。由于它是multimap,因此会出现key重复的情况,在这里使用multimap就免去了使用map时不允许到期时间重复的烦恼。而且multimap会根据key自动排序。

events成员是一个std::map,以schedule里存在的value(也就是回调类的指针)为key,以schedule里value所对应的迭代器的为value,其实在这里它只是做schedule的唯一索引的功能。从addeventat(如下图)看出当添加定时条件,同时会向events添加一个键值对,如果添加失败就会断言。不解为何只允许一种回调类型在schedule里出现一次!

addeventafter和addeventat都是向定时器列表里添加定时条件,关键操作就是向schedule添加时间、回调类的键值对,同时用events保证回调类型只在schedule出现一次。

SafeTimerThread线程启动后会进入SafeTimer::timer_thread循环,如下图:

不断检查schedule里的定时条件,由于schedule是按key升序排序的,所以只要从第一个节点开始查找,当找到比当前时间大的节点就可以结束了。把到期的节点一个个从schedule和events中清除并调用回调类的complete函数触发事件。

回调类型是Context的子类,如下图,当定时条件满足时,SafeTimerThread线程会调用Context的子类(如C_Tick)的finish函数,最终会执行osd::tick方法。

下期预告:

osd处理网络请求的过程——FileStore

 

上一篇: 无

微信关注

获取更多技术咨询