CloudSim源码分析之DatacenterBroker--processEvent()
每个CloudSim实体都继承并实现了SimEntity类的processEvent()方法,用来处理与其自身逻辑相关的事件,比如与DatacenterBroker相关的事件有:请求数据中心特征事件,虚拟机创建情况反馈事件,任务完成返回事件,仿真结束事件等。
CloudSim的事件都是在系统运行过程中不断产生的,并添加到等待队列,每个时钟要处理的事件会从等待队列(future)添加到延时队列中(deferred),在上一篇博文中详细分了runClockTick()方法,该方法实现在一个时钟心跳内处理在延时队列和等待队列中的事件,将队列中事件与相应的实体关联起来,利用该实体的processEvent()方法具体的处理事件。
DatacenterBroker是CloudSim中一个核心实体,它也有自己的事件处理方法,下面将详细分析其processEvent():
点击(此处)折叠或打开
- // 处理与DatacenterBroker相关的事件
- @Override
- public void processEvent(SimEvent ev) {
- switch (ev.getTag()) {
- // Resource characteristics request
- // 资源特征请求事件(数据中心特征)
- case CloudSimTags.RESOURCE_CHARACTERISTICS_REQUEST:
- processResourceCharacteristicsRequest(ev);
- break;
- // Resource characteristics answer
- // 资源特征反馈事件
- case CloudSimTags.RESOURCE_CHARACTERISTICS:
- processResourceCharacteristics(ev);
- break;
- // VM Creation answer
- // 虚拟机创建反馈事件
- case CloudSimTags.VM_CREATE_ACK:
- processVmCreate(ev);
- break;
- // A finished cloudlet returned
- // 任务完成返回事件
- case CloudSimTags.CLOUDLET_RETURN:
- processCloudletReturn(ev);
- break;
- // if the simulation finishes
- // 仿真结束事件
- case CloudSimTags.END_OF_SIMULATION:
- shutdownEntity();
- break;
- // other unknown tags are processed by this method
- default:
- // 处理其他未知事件,可扩展
- processOtherEvent(ev);
- break;
- }
- }
1、processResourceCharacteristicsRequest(SimEvent ev)分析
点击(此处)折叠或打开
- // 处理数据中心特征请求事件
- protected void processResourceCharacteristicsRequest(SimEvent ev) {
- // 这是数据中心ID列表,实际每个数据中心ID对应该数据中心的所有物理机列表
- setDatacenterIdsList(CloudSim.getCloudResourceList());
- // 初始化数据中心特征列表
- setDatacenterCharacteristicsList(new HashMap<Integer, DatacenterCharacteristics>());
- Log.printLine(CloudSim.clock() + ": " + getName() + ": Cloud Resource List received with "
- + getDatacenterIdsList().size() + " resource(s)");
- // 向每个数据中心发送特征请求,创建数据中心特征事件
- for (Integer datacenterId : getDatacenterIdsList()) {
- sendNow(datacenterId, CloudSimTags.RESOURCE_CHARACTERISTICS, getId());
- }
- }
2、processResourceCharacteristics(ev)分析
点击(此处)折叠或打开
- // 处理数据中心返回的数据中心特征
- protected void processResourceCharacteristics(SimEvent ev) {
- // 获取数据中心返回的数据中心特征
- DatacenterCharacteristics characteristics = (DatacenterCharacteristics) ev.getData();
- // 添加数据中心特征ID与数据中心特征的映射
- getDatacenterCharacteristicsList().put(characteristics.getId(), characteristics);
- // DatacenterBroker获取了所有数据中心的特征
- if (getDatacenterCharacteristicsList().size() == getDatacenterIdsList().size()) {
- setDatacenterRequestedIdsList(new ArrayList<Integer>());
- // DatacenterBroker了解到所有数据中心后,开始向数据中心创建虚拟机
- createVmsInDatacenter(getDatacenterIdsList().get(0));
- }
- }
DatacenterBroker获取了所有数据中心特征,开始在数据中心创建虚拟机:
点击(此处)折叠或打开
- // 在数据中心上创建虚拟机
- protected void createVmsInDatacenter(intdatacenterId) {
- // send as much vms as possible for this datacenter before trying the next one
- // 尽量在一个数据中心上创建更多的虚拟机
- int requestedVms = 0;
- String datacenterName = CloudSim.getEntityName(datacenterId);
- for (Vm vm : getVmList()) {
- if (!getVmsToDatacentersMap().containsKey(vm.getId())) {
- Log.printLine(CloudSim.clock() + ": " + getName() + ": Trying to Create VM #" + vm.getId()
- + " in " + datacenterName);
- // 向该数据中心发送虚拟机创建请求事件,等待该数据中心处理该事件
- sendNow(datacenterId,CloudSimTags.VM_CREATE_ACK, vm);
- requestedVms++;// 向某数据中心请求创建虚拟机的次数
- }
- }
- // 将该数据中心ID添加到数据中心请求列表
- getDatacenterRequestedIdsList().add(datacenterId);
- setVmsRequested(requestedVms);// 设置请求次数
- setVmsAcks(0);// 设置应答次数
- }
3、processVmCreate(ev)分析
点击(此处)折叠或打开
- // 只是返回对虚拟机创建请求的一个响应,虚拟机的实际创建在这之前就完成了。
- protected void processVmCreate(SimEvent ev){
- int[] data = (int[]) ev.getData();
- int datacenterId = data[0];
- int vmId = data[1];
- int result = data[2];
- if (result == CloudSimTags.TRUE) {
- // 添加虚拟机ID与数据中心ID的映射
- getVmsToDatacentersMap().put(vmId,datacenterId);
- // 将创建的虚拟机从vmList添加到vmCreatedList(vmList保存待创建的vm列表)
- getVmsCreatedList().add(VmList.getById(getVmList(), vmId));
- Log.printLine(CloudSim.clock() + ": " + getName() + ": VM #" + vmId
- + " has been created in Datacenter #" + datacenterId + ", Host #"
- + VmList.getById(getVmsCreatedList(), vmId).getHost().getId());
- } else {
- Log.printLine(CloudSim.clock() + ": " + getName() + ": Creation of VM #" + vmId
- + " failed in Datacenter #" + datacenterId);
- }
- incrementVmsAcks(); // 增加创建vm应答的次数
- // all the requested VMs have been created
- // 所有待创建的虚拟机都创建完毕
- if (getVmsCreatedList().size() ==getVmList().size() - getVmsDestroyed()) {
- submitCloudlets(); // 提交用户任务至特定虚拟机
- } else {
- // all the acks received, but some VMs were not created
- // 所有的ack都收到了,但是有些vm未被创建
- if (getVmsRequested() ==getVmsAcks()) {
- // find id of the next datacenter that has not been tried
- // 尝试在其他数据中心上创建虚拟机
- for (int nextDatacenterId : getDatacenterIdsList()) {
- if (!getDatacenterRequestedIdsList().contains(nextDatacenterId)) {
- createVmsInDatacenter(nextDatacenterId);
- return;
- }
- }
- // all datacenters already queried
- if (getVmsCreatedList().size() > 0) { // if some vm were created
- submitCloudlets(); // 提交用户任务至特定虚拟机
- } else { // no vms created. abort
- Log.printLine(CloudSim.clock() + ": " + getName()
- + ": none of the required VMs could be created. Aborting");
- finishExecution(); // 结束仿真
- }
- }
- }
- }
所有虚拟机创建成功后,向虚拟机分配云任务
点击(此处)折叠或打开
- // 将任务列表中的所有任务,分别提交给虚拟机
- protected void submitCloudlets() {
- int vmIndex = 0;
- for (Cloudlet cloudlet : getCloudletList()) {
- Vm vm;
- // if user didn't bind this cloudlet and it has not been executed yet
- // 如果该云任务还没有绑定虚拟机
- if (cloudlet.getVmId() == -1) {
- // 直接从已创建的虚拟机中从索引0开始找一台虚拟机,可是这台虚拟机(资源利用率、性能下降)可用吗?
- vm = getVmsCreatedList().get(vmIndex);
- } else { // submit to the specific vm // 该任务之前已经指定了虚拟
- vm = VmList.getById(getVmsCreatedList(), cloudlet.getVmId());
- if (vm == null) { // vm was not created // 指定的虚拟机创建失败,重新分配
- Log.printLine( CloudSim.clock() + ": " + getName() + ": Postponing execution of cloudlet "
- + cloudlet.getCloudletId() + ": bount VM not available");
- continue;
- }
- }
- Log.printLine(CloudSim.clock() + ": " + getName() + ": Sending cloudlet "
- + cloudlet.getCloudletId() + " to VM #" + vm.getId());
- // 任务与虚拟机绑定
- cloudlet.setVmId(vm.getId());
- // 创建任务提交事件
- sendNow(getVmsToDatacentersMap().get(vm.getId()), CloudSimTags.CLOUDLET_SUBMIT, cloudlet);
- cloudletsSubmitted++; // 记录任务提交数
- vmIndex = (vmIndex + 1) %getVmsCreatedList().size(); // vmIndex加1,多于vm数时,再从第一台vm开始
- // 将该任务添加到已任务已提交列表
- getCloudletSubmittedList().add(cloudlet);
- }
- // remove submitted cloudlets from waiting list
- // 将已经提交的任务从cloudletList中移除
- for (Cloudlet cloudlet : getCloudletSubmittedList()) {
- getCloudletList().remove(cloudlet);
- }
- }
4、processCloudletReturn(ev)分析
点击(此处)折叠或打开
- // 处理任务完成返回事件
- protected void processCloudletReturn(SimEvent ev) {
- // 获取该执行完成的用户任务
- Cloudlet cloudlet = (Cloudlet) ev.getData();
- // 将该任务添加到已完成任务列表
- getCloudletReceivedList().add(cloudlet);
- Log.printLine(CloudSim.clock() + ": " + getName() + ": Cloudlet " + cloudlet.getCloudletId()
- + " received");
- cloudletsSubmitted--; // 任务提交数减一
- // 满足下面条件,说明所有用户任务都执行完毕
- if (getCloudletList().size() == 0 &&cloudletsSubmitted == 0) { // all cloudlets executed
- Log.printLine(CloudSim.clock() + ": " + getName() + ": All Cloudlets executed. Finishing...");
- clearDatacenters(); // 清理数据中心
- finishExecution(); // 仿真结束
- } else { // some cloudlets haven't finished yet // 有些任务还没有执行结束
- // 所有任务都已经提交,但是有些任务阻塞了,可能是在等待虚拟机的创建
- if (getCloudletList().size() > 0 &&cloudletsSubmitted == 0) {
- // all the cloudlets sent finished. It means that some bount
- // cloudlet is waiting its VM be created
- clearDatacenters(); // 清理数据中心
- createVmsInDatacenter(0); // 仿真结束
- }
- }
- }
5、shutdownEntity(),接收到END_OF_SIMULATION事件,仿真结束,清除所有实体。
CloudSim源码分析之DatacenterBroker--processEvent()相关推荐
- CloudSim源码分析之虚拟机分配
CloudSim源码分析之虚拟机分配 分类: 云计算 CloudSim2011-05-15 14:32 1629人阅读 评论(10) 收藏 举报 虚拟机integerlistnulltableobje ...
- Spark源码分析 – DAGScheduler
DAGScheduler的架构其实非常简单, 1. eventQueue, 所有需要DAGScheduler处理的事情都需要往eventQueue中发送event 2. eventLoop Threa ...
- Fabric源码分析-共识模块
正好这些天要有一个需求要帮客户魔改Fabric-v0.6,把一些hyperchain的高级特性移植过去,借此机会把之前看过的源码在梳理一下. 下面就是对Fabric共识模块的源码分析和梳理,代码都是以 ...
- 【转】Spark源码分析之-scheduler模块
原文地址:http://jerryshao.me/architecture/2013/04/21/Spark%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E4%B9%8B- ...
- Brpc 服务端收包源码分析(一)
文章目录 server端使用 brpc::Server::AddService初始化各种数据 StartInternal内部其余服务也调用该函数 接收连接套接字StartAccept请求 ResetF ...
- 【akka】akka源码 Akka源码分析-FSM
1.概述 转载自己学习,建议直接看原文:Akka源码分析-FSM akka还有一个不常使用.但我觉得比较方便的一个模块,那就是FSM(有限状态机).我们知道了akka中Actor模型的具体实现之后,就 ...
- CloudSim介绍和使用,CloudSim下载,CloudSim在IDEA中配置,CloudSim源码解读
CloudSim介绍和使用 1. CloudSim简介: 2. CloudSim提供了以下新的特点: (1)支持大型云计算的基础设施的建模与仿真: (2)一个自足的支持数据中心.服务代理人.调度和分配 ...
- Spring 源码分析衍生篇十三 :事务扩展机制 TransactionSynchronization
文章目录 一.前言 二.TransactionSynchronization 1. TransactionSynchronization 1.1 TransactionSynchronization ...
- Flink Cep 源码分析
复合事件处理(Complex Event Processing,CEP)是一种基于动态环境中事件流的分析技术,事件在这里通常是有意义的状态变化,通过分析事件间的关系,利用过滤.关联.聚合等技术,根据事 ...
- 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析
目录[阅读时间:约10分钟] 一.概述 二.对比: gorilla/mux与net/http DefaultServeMux 三.简单使用 四.源码简析 1.NewRouter函数 2.HandleF ...
最新文章
- 73-递归函数1:阶乘
- Python编程语言学习:python的列表的特殊应用之一行命令实现if判断中的两类判断
- python leetcode_LeetCode刷题——第8天(python)
- log4j - 日志
- 图解java工程师学习路线
- matlab启动不了jvm,MATLAB ::在-nojvm启动选项下不再支持此功能
- 通过hook实现禁止shift+delete快捷键
- react和angualr动态插入带html标签或不带html标签的数据
- RailsCasts中文版,#15 Fun with Find Conditions 使用hash为查询条件以便生成正确语法的SQL查询...
- C语言运算符优先级列表(超详细)
- Android日志分析工具的开发介绍
- google chrome的图标成一页纸了_10 款 Chrome 扩展,让你的浏览器好用到飞起
- getinfo怎么用php,PHP curl_getinfo函数
- sudo su与su的区别
- 优化About Us页面,提高网站询盘转化
- 金山系不惧微软,前有WPS力扛Office,后有eversheet接力再战
- 前端代码为什么会有低代码及无代码
- 一篇文章带你发中文核心期刊《计算机科学》
- 北京房价当日报20141013
- 波束形成,通过matlab仿真不同参数的波束形成以及旁絆级
热门文章
- matlab 矩阵累乘,matlab,SAS iml 矩阵运算
- 国庆集训1101+1103(未完成)
- Echarts中国地图json文件,去除诸岛
- html5 live,HTML5 live streaming
- php验证码一直错误,yii2.0验证码总是错误
- 从韩春雨事件看学术成果的辨别
- 工业读写器行业解决方案
- Weighing Features of Lung and Heart Regions forThoracic Disease Classification
- 大家谈之《区块链大革命》
- **使用InkScape绘制简易字母LOGO的教程**