Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6319671
  • 博文数量: 2759
  • 博客积分: 1021
  • 博客等级: 中士
  • 技术积分: 4091
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-11 14:14
文章分类

全部博文(2759)

文章存档

2019年(1)

2017年(84)

2016年(196)

2015年(204)

2014年(636)

2013年(1176)

2012年(463)

分类: 云计算

2013-09-26 10:08:38

 

                                              CloudSim源码分析之DatacenterBroker--processEvent()(一) 

 

每个CloudSim实体都继承并实现了SimEntity类的processEvent()方法,用来处理与其自身逻辑相关的事件,比如与DatacenterBroker相关的事件有:请求数据中心特征事件,虚拟机创建情况反馈事件,任务完成返回事件,仿真结束事件等。


CloudSim的事件都是在系统运行过程中不断产生的,并添加到等待队列,每个时钟要处理的事件会从等待队列(future)添加到延时队列中(deferred),在上一篇博文中详细分了runClockTick()方法,该方法实现在一个时钟心跳内处理在延时队列和等待队列中的事件,将队列中事件与相应的实体关联起来,利用该实体的processEvent()方法具体的处理事件。

DatacenterBrokerCloudSim中一个核心实体,它也有自己的事件处理方法,下面将详细分析其processEvent():

点击(此处)折叠或打开

  1. // 处理与DatacenterBroker相关的事件

  2.     @Override
  3.     public void processEvent(SimEvent ev) {
  4.         switch (ev.getTag()) {
  5.             // Resource characteristics request

  6.             // 资源特征请求事件(数据中心特征)

  7.             case CloudSimTags.RESOURCE_CHARACTERISTICS_REQUEST:
  8.                 processResourceCharacteristicsRequest(ev);
  9.                 break;
  10.             // Resource characteristics answer

  11.             // 资源特征反馈事件

  12.             case CloudSimTags.RESOURCE_CHARACTERISTICS:
  13.                 processResourceCharacteristics(ev);
  14.                 break;
  15.             // VM Creation answer

  16.             // 虚拟机创建反馈事件

  17.             case CloudSimTags.VM_CREATE_ACK:
  18.                 processVmCreate(ev);
  19.                 break;
  20.             // A finished cloudlet returned

  21.             // 任务完成返回事件

  22.             case CloudSimTags.CLOUDLET_RETURN:
  23.                 processCloudletReturn(ev);
  24.                 break;
  25.             // if the simulation finishes

  26.             // 仿真结束事件

  27.             case CloudSimTags.END_OF_SIMULATION:
  28.                 shutdownEntity();
  29.                 break;
  30.             // other unknown tags are processed by this method

  31.             default:
  32.                 // 处理其他未知事件,可扩展

  33.                 processOtherEvent(ev);
  34.                 break;
  35.         }
  36.     }

      1、processResourceCharacteristicsRequest(SimEvent ev)分析

点击(此处)折叠或打开

  1. // 处理数据中心特征请求事件

  2.     protected void processResourceCharacteristicsRequest(SimEvent ev) {
  3.         // 这是数据中心ID列表,实际每个数据中心ID对应该数据中心的所有物理机列表
  4.         setDatacenterIdsList(CloudSim.getCloudResourceList());
  5.         // 初始化数据中心特征列表
  6.         setDatacenterCharacteristicsList(new HashMap<Integer, DatacenterCharacteristics>());

  7.         Log.printLine(CloudSim.clock() + ": " + getName() + ": Cloud Resource List received with "
  8.                 + getDatacenterIdsList().size() + " resource(s)");
  9.         // 向每个数据中心发送特征请求,创建数据中心特征事件
  10.         for (Integer datacenterId : getDatacenterIdsList()) {
  11.             sendNow(datacenterId, CloudSimTags.RESOURCE_CHARACTERISTICS, getId());
  12.         }
  13.     }
  2、processResourceCharacteristics(ev)分析

点击(此处)折叠或打开

  1. // 处理数据中心返回的数据中心特征

  2.     protected void processResourceCharacteristics(SimEvent ev) {
  3.         // 获取数据中心返回的数据中心特征
  4.         DatacenterCharacteristics characteristics = (DatacenterCharacteristics) ev.getData();
  5.         // 添加数据中心特征ID与数据中心特征的映射
  6.         getDatacenterCharacteristicsList().put(characteristics.getId(), characteristics);

  7.         // DatacenterBroker获取了所有数据中心的特征
  8.         if (getDatacenterCharacteristicsList().size() == getDatacenterIdsList().size()) {
  9.             setDatacenterRequestedIdsList(new ArrayList<Integer>());
  10.             // DatacenterBroker了解到所有数据中心后,开始向数据中心创建虚拟机
  11.             createVmsInDatacenter(getDatacenterIdsList().get(0));
  12.         }
  13.     }

DatacenterBroker获取了所有数据中心特征,开始在数据中心创建虚拟机:

点击(此处)折叠或打开

  1. // 在数据中心上创建虚拟机

  2.     protected void createVmsInDatacenter(int datacenterId) {
  3.         // send as much vms as possible for this datacenter before trying the next one
  4.         // 尽量在一个数据中心上创建更多的虚拟机
  5.         int requestedVms = 0;
  6.         String datacenterName = CloudSim.getEntityName(datacenterId);
  7.         for (Vm vm : getVmList()) {
  8.             if (!getVmsToDatacentersMap().containsKey(vm.getId())) {
  9.                 Log.printLine(CloudSim.clock() + ": " + getName() + ": Trying to Create VM #" + vm.getId()
  10.                         + " in " + datacenterName);
  11.                 // 向该数据中心发送虚拟机创建请求事件,等待该数据中心处理该事件
  12.                 sendNow(datacenterId, CloudSimTags.VM_CREATE_ACK, vm);
  13.                 requestedVms++;// 向某数据中心请求创建虚拟机的次数

  14.             }
  15.         }
  16.         // 将该数据中心ID添加到数据中心请求列表
  17.         getDatacenterRequestedIdsList().add(datacenterId);

  18.         setVmsRequested(requestedVms);// 设置请求次数

  19.         setVmsAcks(0);// 设置应答次数

  20.     }
3、processVmCreate(ev)分析


点击(此处)折叠或打开

  1. // 只是返回对虚拟机创建请求的一个响应,虚拟机的实际创建在这之前就完成了。

  2.     protected void processVmCreate(SimEvent ev) {
  3.         int[] data = (int[]) ev.getData();
  4.         int datacenterId = data[0];
  5.         int vmId = data[1];
  6.         int result = data[2];

  7.         if (result == CloudSimTags.TRUE) {
  8.             // 添加虚拟机ID与数据中心ID的映射
  9.             getVmsToDatacentersMap().put(vmId, datacenterId);
  10.             // 将创建的虚拟机从vmList添加到vmCreatedList(vmList保存待创建的vm列表)
  11.             getVmsCreatedList().add(VmList.getById(getVmList(), vmId));

  12.             Log.printLine(CloudSim.clock() + ": " + getName() + ": VM #" + vmId
  13.                     + " has been created in Datacenter #" + datacenterId + ", Host #"
  14.                     + VmList.getById(getVmsCreatedList(), vmId).getHost().getId());
  15.         } else {
  16.             Log.printLine(CloudSim.clock() + ": " + getName() + ": Creation of VM #" + vmId
  17.                     + " failed in Datacenter #" + datacenterId);
  18.         }

  19.         incrementVmsAcks(); // 增加创建vm应答的次数

  20.         // all the requested VMs have been created
  21.         // 所有待创建的虚拟机都创建完毕
  22.         if (getVmsCreatedList().size() == getVmList().size() - getVmsDestroyed()) {
  23.             submitCloudlets(); // 提交用户任务至特定虚拟机

  24.         } else {
  25.             // all the acks received, but some VMs were not created
  26.             // 所有的ack都收到了,但是有些vm未被创建
  27.             if (getVmsRequested() == getVmsAcks()) {
  28.                 // find id of the next datacenter that has not been tried
  29.                 // 尝试在其他数据中心上创建虚拟机
  30.                 for (int nextDatacenterId : getDatacenterIdsList()) {
  31.                     if (!getDatacenterRequestedIdsList().contains(nextDatacenterId)) {
  32.                         createVmsInDatacenter(nextDatacenterId);
  33.                         return;
  34.                     }
  35.                 }

  36.                 // all datacenters already queried
  37.                 if (getVmsCreatedList().size() > 0) { // if some vm were created

  38.                     submitCloudlets(); // 提交用户任务至特定虚拟机

  39.                 } else { // no vms created. abort

  40.                     Log.printLine(CloudSim.clock() + ": " + getName()
  41.                             + ": none of the required VMs could be created. Aborting");
  42.                     finishExecution(); // 结束仿真

  43.                 }
  44.             }
  45.         }
  46.     }

所有虚拟机创建成功后,向虚拟机分配云任务

点击(此处)折叠或打开

  1. // 将任务列表中的所有任务,分别提交给虚拟机

  2.     protected void submitCloudlets() {
  3.         int vmIndex = 0;
  4.         for (Cloudlet cloudlet : getCloudletList()) {
  5.             Vm vm;
  6.             // if user didn't bind this cloudlet and it has not been executed yet
  7.             // 如果该云任务还没有绑定虚拟机
  8.             if (cloudlet.getVmId() == -1) {
  9.                 // 直接从已创建的虚拟机中从索引0开始找一台虚拟机,可是这台虚拟机(资源利用率、性能下降)可用吗?

  10.                 vm = getVmsCreatedList().get(vmIndex);
  11.             } else { // submit to the specific vm // 该任务之前已经指定了虚拟

  12.                 vm = VmList.getById(getVmsCreatedList(), cloudlet.getVmId());
  13.                 if (vm == null) { // vm was not created // 指定的虚拟机创建失败,重新分配

  14.                     Log.printLine( CloudSim.clock() + ": " + getName() + ": Postponing execution of cloudlet "
  15.                             + cloudlet.getCloudletId() + ": bount VM not available");
  16.                     continue;
  17.                 }
  18.             }

  19.             Log.printLine(CloudSim.clock() + ": " + getName() + ": Sending cloudlet "
  20.                     + cloudlet.getCloudletId() + " to VM #" + vm.getId());
  21.             // 任务与虚拟机绑定

  22.             cloudlet.setVmId(vm.getId());
  23.             // 创建任务提交事件

  24.             sendNow(getVmsToDatacentersMap().get(vm.getId()), CloudSimTags.CLOUDLET_SUBMIT, cloudlet);
  25.             cloudletsSubmitted++; // 记录任务提交数

  26.             vmIndex = (vmIndex + 1) % getVmsCreatedList().size(); // vmIndex加1,多于vm数时,再从第一台vm开始

  27.             // 将该任务添加到已任务已提交列表
  28.             getCloudletSubmittedList().add(cloudlet);
  29.         }

  30.         // remove submitted cloudlets from waiting list
  31.         // 将已经提交的任务从cloudletList中移除
  32.         for (Cloudlet cloudlet : getCloudletSubmittedList()) {
  33.             getCloudletList().remove(cloudlet);
  34.         }
  35.     }


      4、processCloudletReturn(ev)分析

点击(此处)折叠或打开

  1. // 处理任务完成返回事件

  2.     protected void processCloudletReturn(SimEvent ev) {
  3.         // 获取该执行完成的用户任务
  4.         Cloudlet cloudlet = (Cloudlet) ev.getData();
  5.         // 将该任务添加到已完成任务列表
  6.         getCloudletReceivedList().add(cloudlet);
  7.         Log.printLine(CloudSim.clock() + ": " + getName() + ": Cloudlet " + cloudlet.getCloudletId()
  8.                 + " received");
  9.         cloudletsSubmitted--; // 任务提交数减一

  10.         // 满足下面条件,说明所有用户任务都执行完毕
  11.         if (getCloudletList().size() == 0 && cloudletsSubmitted == 0) { // all cloudlets executed

  12.             Log.printLine(CloudSim.clock() + ": " + getName() + ": All Cloudlets executed. Finishing...");
  13.             clearDatacenters(); // 清理数据中心

  14.             finishExecution(); // 仿真结束

  15.         } else { // some cloudlets haven't finished yet // 有些任务还没有执行结束
  16.             // 所有任务都已经提交,但是有些任务阻塞了,可能是在等待虚拟机的创建
  17.             if (getCloudletList().size() > 0 && cloudletsSubmitted == 0) {
  18.                 // all the cloudlets sent finished. It means that some bount
  19.                 // cloudlet is waiting its VM be created
  20.                 clearDatacenters(); // 清理数据中心

  21.                 createVmsInDatacenter(0); // 仿真结束
  22.             }
  23.         }
  24.     }


      5、shutdownEntity(),接收到END_OF_SIMULATION事件,仿真结束,清除所有实体。


 

阅读(940) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~