0%

iFogSim实验环境

  • https://github.com/Cloudslab/iFogSim
  • iFogSim 基于 CloudSim,扩展了基本的 CloudSim 类的抽象,提供了模拟具有大量雾节点和物联网设备(如传感器、执行器)的定制雾计算环境。iFogSim 的核心执行思想:**Sense - Process - Actuate**
  • iFogSim 可以实现对端到端延迟、网络拥塞、能耗、执行成本和 QoS 的评估
  • iFogSim 主要有三个基本组件构成:physical componentslogical componentsmanagement components

iFogSim实验环境简介

  • iFogSim 和 WorkflowSim 一样,都是基于 CloudSim 的。iFogSim 扩展了基本的 CloudSim 类的抽象,提供了模拟具有大量雾节点和物联网设备(如传感器、执行器)的定制雾计算环境。
  • iFogSim 的核心执行思想:**Sense - Process - Actuate**,亦即 感知 - 处理 - 执行
  • iFogSim 可以实现对端到端延迟、网络拥塞、能耗、执行成本和 QoS 的评估

Components

  • iFogSim 主要有三个基本组件构成:
    • physical components
      • 物理组件包含雾设备(雾节点)Fog devices,雾设备按分层顺序排列,低等级的雾设备与传感器和执行器直接连接。在边缘云环境中,雾设备起到提供内存、CPU、网络等资源的作用,类似于云环境中数据中心的作用。
    • logical components
      • 逻辑组件包含应用程序模块 Application modules 和应用程序 “边” Application Edges应用程序就是由互相依赖的一系列应用程序模块构成。
      • 应用程序模块用来执行传感器传输过来的任务(处理传感器传输过来的数据),应用程序模块之间的数据传输关系由应用程序 “边” 来描述。
    • management components
      • 管理组件包含控制器 Controller 和模块映射对象 Module Mapping模块映射对象根据应用程序模块的要求,识别雾设备中的可用资源,并将其放置在其中。控制器对象根据模块映射对象提供的放置信息,在其指定的雾设备上启动应用程序模块,并定期管理雾设备的资源。
        • 简单地说,模块映射对象 Module Mapping 用于确定应用程序模块和雾设备之间的放置关系(如果设计了一个放置算法,那这里就是放置算法发生作用的地方),控制器对象 Controller 基于该放置关系,对应用程序模块进行执行(执行后的结果就是从控制器对象这里得到的)。

hierarchical order

  • 在 iFogSim 中,FogDevice 被划分为不同的层级
    • End Device 和 IoT 传感器、执行器直接进行连接
    • Gateway Device 作为 End Device 和云端之间的桥接

Simulation Steps

  1. 首先要创建物理组件,根据指定的配置创建雾设备,包括内存 ram、计算处理能力(mips)、执行开销 cost、上行和下行带宽、能耗。

    • 在 iFogSim 中对应 SensorActuatorFogDevice
      • Sensor 上传的要处理的任务在 iFogSim 中用 tuple 类来描述,上传任务的频率在 Sensor 中定义
  2. 然后要创建逻辑组件,即要执行的应用程序模块 Application modules 和表示应用程序模块之间依赖关系的 “边” Application Edges。这里要指定的配置包括任务的类型、数据传输方向、任务数据量、要传输的数据量等。

    • 在 iFogSim 中对应 Application

    • 逻辑组件可以被创建为不同的类型:

      • 主 - 从类型:

      • 顺序单向类型:

  3. 最后要创建管理组件,在管理组件中定义要执行的放置策略,并根据放置策略对应用程序进行执行。

    • 在 iFogSim 中对应 ControllerModulePlacement

QA

  • Q:在 iFogSim 中,雾设备之间的层级关系是什么样的?

    A:以 VRGameFog 为例,雾设备之间的层级关系见下图:

    • 更具体地来说,以 VRGameFog 为例,在 iFogSim 中有以下 SimEntity

  • Q:应用程序模块放置在雾设备上的策略是如何确定的?

    A:应用程序模块放置在雾设备上的策略是在 ModuleMapping 确定的,通过在 ModuleMapping 中根据自己设计的算法确定 Map<雾设备,放置在雾设备上的应用程序模块的集合>,即应用程序模块和雾设备的放置关系。

    然后根据这个放置关系,在 ModulePlacement 中进行实际的应用模块在雾设备上的放置(真正地为应用模块分配计算资源),这个过程会确定 Map<模块名称, 放置了该类模块的雾设备id集合>Map<雾设备的id, 在该雾设备上放置的AppModule集合>

    然后在 Controller 中,通过 ModulePlacement 中已有的放置关系(已经真正地为应用模块分配计算资源了),将应用程序模块都启动起来。

    所以总体流程是:

    ​ 在 ModuleMapping 中根据设计的算法确定放置关系(放置关系存放在 Map<雾设备,放置在雾设备上的应用程序模块的集合> 中) —>

    ​ 在 ModulePlacement 中根据 ModuleMapping 的放置关系进行实际的应用模块在雾设备上的放置(实际放置以后,放置关系存放在 Map<模块名称, 放置了该类模块的雾设备id集合>Map<雾设备的id, 在该雾设备上放置的AppModule集合> 中) —>

    ​ 在 Controller 中根据实际的放置关系对任务进行执行

    • ModuleMapping 中的放置关系可以理解为 “蓝图”,是概念上的放置关系
    • ModulePlacement 中的放置关系可以理解为 “实际场景”,是真正地进行了放置
  • Q:iFogSim 的核心事件执行流程是什么样的?

    A:接下来将以 类名::事件Tag::{事件函数} 的方式描述 iFogSim 核心事件的执行流程。

    • 注册应用和资源阶段

      • FogDevice::FogEvents.SENSOR_JOINED::processSensorJoining(ev); 将传感器和对应的雾设备联系起来
      • FogDevice::FogEvents.ACTUATOR_JOINED::processActuatorJoined(ev); 将执行器和对应的雾设备联系起来
      • FogDevice::FogEvents.ACTIVE_APP_UPDATE::updateActiveApplications(ev); 告诉雾设备活跃的应用程序有哪些
      • FogDevice::FogEvents.APP_SUBMIT::processAppSubmit(ev); 告诉雾设备应用程序有哪些
    • 启动阶段

      • FogDevice::FogEvents.LAUNCH_MODULE::processModuleArrival(ev); 将雾设备上的应用程序模块都启动起来,如果这个应用程序模块是 periodicTuple 的 sourceModule,则该雾设备还会让该应用模块不断地周期性发送任务(通过周期性地发送 FogEvents.SEND_PERIODIC_TUPLE 信号来实现,即在 FogEvents.SEND_PERIODIC_TUPLE 对应的处理方法中又发送该信号给自己)
      • FogDevice::FogEvents.RESOURCE_MGMT::manageResources(ev); 定期的对能耗结果进行更新,实现定期的方式和上面的方法类似,通过在对应的处理方法中又发送该信号给自己实现
      • Sensor::FogEvents.EMIT_TUPLE::transmit(); 传感器周期性地发送要处理的任务
    • 处理任务阶段

      • Sensor::FogEvents.TUPLE_ACK::{} 如果传感器收到这个信号,就表示它已经成功地把任务发送给关联的雾设备
      • FogDevice::FogEvents.TUPLE_ARRIVAL::processTupleArrival(ev) 雾设备处理发送给它的任务
  • Q:iFogSim 是怎么得到最终执行后的结果的?

    A:最终执行后的结果都保存在 Controller 中,iFogSim 是直接在 Controller 中输出结果了。具体而言,是在 Controller 类的 processEvent 方法中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    // Controller.processEvent(SimEvent ev)
    @Override
    public void processEvent(SimEvent ev) {
    switch (ev.getTag()) {
    case FogEvents.APP_SUBMIT:
    processAppSubmit(ev);
    break;
    case FogEvents.TUPLE_FINISHED:
    processTupleFinished(ev);
    break;
    case FogEvents.CONTROLLER_RESOURCE_MANAGE:
    manageResources();
    break;
    case FogEvents.STOP_SIMULATION: // 在这个事件中将结果输出了, 然后系统直接退出
    CloudSim.stopSimulation();
    printTimeDetails();
    printPowerDetails();
    printCostDetails();
    printNetworkUsageDetails();
    System.exit(0);
    break;
    }
    }
  • Q:iFogSim 是怎么计算时间、能耗、开销等一系列相关参数的?

    A:这其实是在 iFogSim 执行过程中不断更新的。具体而言,在 iFogSim 模拟的过程中,Entities 会不断地处理事件 Event,而在处理事件的具体方法中,就有可能会更新相关的时间、能耗、开销等参数,例如在 FogDeviceprocessOtherEvent 方法中,有一些事件就会涉及到更新相关参数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    @Override
    protected void processOtherEvent(SimEvent ev) {
    switch (ev.getTag()) {
    case FogEvents.TUPLE_ARRIVAL:
    // 处理任务到达事件
    processTupleArrival(ev);
    break;
    case FogEvents.LAUNCH_MODULE:
    // 处理模块启动事件,在这个事件中拥有PeriodicTuples的模块会开始周期性地发送任务
    processModuleArrival(ev);
    break;
    case FogEvents.RELEASE_OPERATOR:
    processOperatorRelease(ev);
    break;
    case FogEvents.SENSOR_JOINED:
    // 该事件会向 sensor 发送一个 ACK 信号
    processSensorJoining(ev);
    break;
    case FogEvents.SEND_PERIODIC_TUPLE:
    // 该事件会创建一个tuple发送给entity自己
    // 然后继续send(getId(), edge.getPeriodicity(), FogEvents.SEND_PERIODIC_TUPLE, edge);
    // 用来周期性地发送任务
    sendPeriodicTuple(ev);
    break;
    case FogEvents.APP_SUBMIT:
    // 将应用程序加入applicationMap
    processAppSubmit(ev);
    break;
    case FogEvents.UPDATE_NORTH_TUPLE_QUEUE:
    updateNorthTupleQueue();
    break;
    case FogEvents.UPDATE_SOUTH_TUPLE_QUEUE:
    updateSouthTupleQueue();
    break;
    case FogEvents.ACTIVE_APP_UPDATE:
    // 将活跃的App的名称加入activeApplications
    updateActiveApplications(ev);
    break;
    case FogEvents.ACTUATOR_JOINED:
    // 将和当前entity相关的actuatorId加入到associatedActuatorIds
    processActuatorJoined(ev);
    break;
    case FogEvents.LAUNCH_MODULE_INSTANCE:
    updateModuleInstanceCount(ev);
    break;
    case FogEvents.MODULE_SEND:
    moduleSend(ev);
    break;
    case FogEvents.MODULE_RECEIVE:
    moduleReceive(ev);
    break;
    case FogEvents.RELEASE_MODULE:
    processModuleTermination(ev);
    break;
    case FogEvents.RESOURCE_MGMT:
    // 这个事件会定期的对能耗结果进行更新
    manageResources(ev);
    break;
    case FogEvents.UPDATE_CLUSTER_TUPLE_QUEUE:
    updateClusterTupleQueue();
    break;
    case FogEvents.START_DYNAMIC_CLUSTERING:
    //This message is received by the devices to start their clustering
    processClustering(this.getParentId(), this.getId(), ev);
    break;
    default:
    break;
    }
    }
---------------The End---------------