最近几日在学习CloudSim3.0.3的源码,看着看着就意图弄清example的模拟过程,即从startSimulation()到stopSimulation()之间主要发生了什么。
CloudSim是目前应用最广泛的云计算环境模拟工具,采用Java编写。我们知道云数据中心的运转是连续的,各个实体(Vm,Host等)每一秒钟(当然可以说每一ms)都在变化,那么CloudSim是以什么样的方式进行模拟的?
答案是:基于事件的机制
下面我这几日对CloudSim模拟机制的关键见解:
1. CloudSim时间轴
云数据中心的运转是连续的,CloudSim也有全局变量CloudSim.clock用于记录时间,但与我最初设想不同,clock并不是步进的(并没有在某个函数中clock++什么的),而是基于“事件”的发生演进的。例如,当前正在处理的事件是event_0,它由实体DataCenter于clock=0发出,delay=0.1,那么处理该事件的函数(先由CloudSim.processEvent()处理)中,会将全局clock置为0.1,也即可以理解为event_0的发生使得时间轴前进了0.1s。举一个更具体的例子,在org.cloudbus.cloudsim.examples.CloudSimExample1.java中,DC实体(关于事件怎么传递给DC的,在下一个问题中讨论)处理CLOUDLET_SUBMIT事件时clock是0.1,处理过程中会产生VM_DC_EVENT(clock=0.1+400,发给自己)、CLOUDLET_RETURN事件(clock也是400.1,发给Broker)等等。当这两个event被处理时,时间轴自然就被推进到400.1这个时间点上了,即逻辑上代表某个VM执行完毕,在example1这个仅一个cloudlet的简单例子中,即代表所有云任务执行完毕。
2. CloudSim事件机制
在上一个话题中,我们可以总结出时间轴(clock)由事件驱动,那么CloudSim的事件处理机制如何?其中它采用了一个常见方案,事件队列——名为future并定义在CloudSim.java中。有事件,就必然有处理事件的主体——SimEntity,查看代码发现,CIS(CloudInformationSystem)对象、DC对象和DCBroker对象是三种最典型的实体,他们继承SimEntity类。简单来说,事件的处理机制是:事件被存放在future中,模拟程序开始(CloudSim.startSimulation)后,不断地检查future队列,取出事件并处理(往往伴随新事件的入队),直到future为空就可以开始进行结束模拟的相关动作。
源码中的调用逻辑:
CloudSim.startSimulation() -> CloudSim.run(){while(true){...runClockTick() -> processEvent()...}}
这个CloudSim.processEvent()自己能处理ENULL(无效的)、CREATE和HOLD_DONE事件,但其实我发现这几个事件寥寥无几(实例化事件也不是CREATE)。该函数真正的作用在于将SEND类型的事件转交给相应的SimEntity(比如DC、Broker)去处理,即调用event.getDestination().processEvent()。DC、Broker类重载了父类SimEntity的processEvent()方法,它们就是destination(事件的目标),所以SEND事件都是被转交给DC、Broker等实体来执行的。
那么最初的(几个)事件是什么呢?毕竟后面的事件均由前面的触发。
运行example1是一个好方法:我通过在事件(SimEvent)的构造函数中输出构造的事件信息和时间,发现前几个event大概是实例化事件,包括:CIS实例化事件、DC实例化事件、Broker实例化事件(SimEntity对象的构造函数中会产生事件);接下来的事件是:REGISTER_RESOURCE(由DC.startEntity()产生)以及RESOURCE_CHARACTERISTICS_REQUEST(由Broker.startEntity()产生)。
探究代码发现:RESOURCE_CHARACTERISTICS_REQUEST是一系列后续事件的源头,因此模拟流程的大致逻辑是:DC和Broker之间往来事件以确认DataCenterCharacteristic创建完成 -> Broker产生事件VM_CREATE_ACK要求DC创建VM -> DC完成VM创建并产生ACK事件 -> Broker收到后接着产生CLOUDLET_SUBMIT事件要求DC处理分配执行云任务 -> DC调用相关函数更新集群状态(相当于执行任务)、产生相关事件(发给自己,事件clock已推进)、产生任务完成事件(事件的clock已推进)等 -> Broker处理CLOUDLET_RETURN等事件,模拟过程基本结束。