Basic Concepts¶
For running a simulation, you must define the following elements (we have used a basic example to explain them tutorial/main1.py) :
Network Topology¶
Firstly, the definition of a topology. A topology consists of a set of nodes and links. The nodes are elements of the network that serve as a link between other elements and have the ability to execute or host the application.
That is, a node has associated computing characteristics:
- IPT Instructions per simulation time. It is equivalent to IPS but it is the user how fix the unit time (i.e. seconds, milliseconds, etc.). Time simulation units is set by the user.
- RAM Memory available
- COST Cost per unit time
A link has associated these performance characteristics:
- BW Channel Bandwidth: in Bytes
- PR Channel Propagation speed
- The Latency is dynamically computed using: (Message.size.bits / BW) + PR)
A network can be created using a dictionary structure (or json file) or through some implemented algorithms from specific libraries compatibles with Networkx (see architecture details).
In the definition of your devices, nodes, you can include your custom tags.
from yafs.topology import Topology
topology_json = {}
topology_json["entity"] = []
topology_json["link"] = []
cloud_dev = {"id": 0, "model": "cloud","mytag":"cloud", "IPT": 5000 * 10 ^ 6, "RAM": 40000,"COST": 3,"WATT":20.0}
sensor_dev = {"id": 1, "model": "sensor-device", "IPT": 100* 10 ^ 6, "RAM": 4000,"COST": 3,"WATT":40.0}
actuator_dev = {"id": 2, "model": "actuator-device", "IPT": 100 * 10 ^ 6, "RAM": 4000,"COST": 3, "WATT": 40.0}
link1 = {"s": 0, "d": 1, "BW": 1, "PR": 10}
link2 = {"s": 0, "d": 2, "BW": 1, "PR": 1}
topology_json["entity"].append(cloud_dev)
topology_json["entity"].append(sensor_dev)
topology_json["entity"].append(actuator_dev)
topology_json["link"].append(link1)
topology_json["link"].append(link2)
t = Topology()
t.load(topology_json)
Application¶
Secondly, the application follows the DDF model, in which an application is modeled as directed graph. The vertices of the directed acyclic graph (DAG) representing modules that perform processing on incoming data and edge denoting data dependencies among modules.
An application is set by a group of modules. A module can create messages (a pure source / sensor), a modul can consume messages (a pure sink / actuator ) and other modules can do both tasks.
The dependencies among modules are defined through messages.
A message is the representation of a request between two modules. A message is set by an unique ID in the same application. It has a source and destiny module, a length of instructions, and a number of bytes. If the message arrive a pure sink this message does not require the last two attributes. In YAFS, it is possible to define broadcast messages.
m_a = Message("M.A", "Sensor", "ServiceA", instructions=20*10^6, bytes=1000)
m_b = Message("M.B", "ServiceA", "Actuator", instructions=30*10^6, bytes=500)
We illustrate this example using EEG_GAME application [1] following the idea used in CloudSim [2] and other similar cloud simulators.
Note
User defines the distribution functions that modules use to create and send the different messages. In this example, the user defines: fractional_selectivity and next_time_periodic.
Note
In sim.utils package there are defined several distributions
import random
from yafs.application import Application
from yafs.application import Message
def create_application():
# APLICATION
a = Application(name="SimpleCase")
# (S) --> (ServiceA) --> (A)
a.set_modules([{"Sensor":{"Type":Application.TYPE_SOURCE}},
{"ServiceA": {"RAM": 10, "Type": Application.TYPE_MODULE}},
{"Actuator": {"Type": Application.TYPE_SINK}}
])
"""
Messages among MODULES (AppEdge in iFogSim)
"""
m_a = Message("M.A", "Sensor", "ServiceA", instructions=20*10^6, bytes=1000)
m_b = Message("M.B", "ServiceA", "Actuator", instructions=30*10^6, bytes=500)
"""
Defining which messages will be dynamically generated # the generation is controlled by Population algorithm
"""
a.add_source_messages(m_a)
"""
MODULES/SERVICES: Definition of Generators and Consumers (AppEdges and TupleMappings in iFogSim)
"""
# MODULE SERVICES
a.add_service_module("ServiceA", m_a, m_b, fractional_selectivity, threshold=1.0)
return a
app1 = create_aplication("Tutorial1")
Population model¶
In real scenarios, sensors can move in the IoT ecosystem which it means, they can invoke services for several access points. For that reason, each population model is associated to one application and it runs according to a set of events or time distribution.
The association of controls to a node can be dynamic and this process is executed every certain time to change the creation policies associated with the nodes. The population model can be so complex as you wish. More advanced details in architecture details.
The most simple case, it is a statical creation of requests. For each message of a pure service source (or sensor), it will have a generation control associated to it.
from yafs.population import Statical
pop = Statical("Statical")
pop.set_src_control({"model": "sensor-device", "number":1,"message": app.get_message("M.A"), "distribution": deterministicDistribution,"param": {"time_shift": 100}})#5.1}})
pop.set_sink_control({"model": "actuator-device","number":1,"module":app.get_sink_modules()})
Selector model¶
This module is the “service orchestration”. It is the coordination and arrangement of multiple services exposed as a single aggregate service.
The most simple case is one to one module using the shortest path between both modules.
selectorPath = MinimunPath()
where internally this function is customized by the user. Mandatory returns are two arrays ( bestpath and bestdes). The first one is an array among id-nodes of the topology. The second one is also a sequence of id-process who are deployed in that nodes.
class MinimunPath(Selection):
def get_path(self, sim, app_name, message, topology_src, alloc_DES, alloc_module, traffic):
"""
Computes the minimun path among the source elemento of the topology and the localizations of the module
Return the path and the identifier of the module deployed in the last element of that path
"""
node_src = topology_src
DES_dst = alloc_module[app_name][message.dst]
print "GET PATH"
print "\tNode _ src (id_topology): %i" %node_src
print "\tRequest service: %s " %message.dst
print "\tProcess serving that service: %s " %DES_dst
bestPath = []
bestDES = []
for des in DES_dst: ## In this case, there are only one deployment
dst_node = alloc_DES[des]
print "\t\t Looking the path to id_node: %i" %dst_node
path = list(nx.shortest_path(sim.topology.G, source=node_src, target=dst_node))
bestPath = [path]
bestDES = [des]
return bestPath, bestDES
Placement algorithm¶
In this module is implemented the algorithm to allocation resources. Placement module has two public methods: initial_allocation and run. The first is used in the first deployment of the application, the second one is used to move this modules in the topological entities according with some multi-objetive allocation algorithm or whatever idea.
The most usual case is a deployment in the cluster. In this case, sink nodes (actuators) are fixed in the topology.
placement = CloudPlacement("onCloud") # it defines the deployed rules: module-device
placement.scaleService({"ServiceA": 1})
where: .. code-block:: python
from yafs.placement import Placement
class CloudPlacement(Placement):
- def initial_allocation(self, sim, app_name):
#We find the ID-nodo/resource value = {“mytag”: “cloud”} # or whatever tag
id_cluster = sim.topology.find_IDs(value) app = sim.apps[app_name] services = app.services
- for module in services:
- if module in self.scaleServices:
- for rep in range(0, self.scaleServices[module]):
- idDES = sim.deploy_module(app_name,module,services[module],id_cluster)
Running the simulator¶
Once defined the previous elements, we can associate them to the simulator. To do this, you have to deploy the application with its respective topology policies. Once this is done, we can launch the simulation.
s = Sim(t) # t is the topology
simulation_time = 100000
s.deploy_app(app, placement, pop, selectorPath)
s.run(simulation_time,show_progress_monitor=False)
Results¶
The results are stored in a csv format in two files. One of the main events is the registration of each message in each entity of the topology that manages it. In these types of events, the following attributes are recorded:
- type It represent the entity who run the taks: a module (COMP_M) or an actuator (SINK_M)
- app application name
- module Module or service who manages it
- service service time
- message message name
- DES.src DES process who send this message
- DES.dst DES process who receive this message (the previous module(
- TOPO.src ID node topology where the DES.src module is deployed
- TOPO.dst ID node topology where the DES.dst module is deployed
- module.src the module or service who send this message
- service service time
- time_in time when the module accepts it
- time_out time when the module finishes its process
- time_emit time when the message was sent
- time_reception time when the message is accepted by the module
Note
The units of time have the scale defined by the user in the respective distribution units. It means, the results of time are the times of the simulator.
type,app,module,message,DES.src,DES.dst,TOPO.src,TOPO.dst,module.src,service,time_in,time_out,time_emit,time_reception
COMP_M,SimpleCase,ServiceA,M.A,0,2,1,0,Sensor,0.004119505659320882,110.008,110.01211950565931,100.0,110.008
SINK_M,SimpleCase,Actuator,M.B,2,1,0,2,ServiceA,0,111.01611950565932,111.01611950565932,110.01211950565931,111.01611950565932
COMP_M,SimpleCase,ServiceA,M.A,0,2,1,0,Sensor,0.004119505659320882,210.008,210.01211950565934,200.0,210.008
SINK_M,SimpleCase,Actuator,M.B,2,1,0,2,ServiceA,0,211.01611950565933,211.01611950565933,210.01211950565934,211.01611950565933
COMP_M,SimpleCase,ServiceA,M.A,0,2,1,0,Sensor,0.004119505659320882,310.008,310.0121195056593,300.0,310.008
SINK_M,SimpleCase,Actuator,M.B,2,1,0,2,ServiceA,0,311.01611950565933,311.01611950565933,310.0121195056593,311.01611950565933
COMP_M,SimpleCase,ServiceA,M.A,0,2,1,0,Sensor,0.004119505659320882,410.008,410.0121195056593,400.0,410.008
The other file storages the transmission process in the network
type,src,dst,app,latency,message,ctime,size,buffer
LINK,1,0,SimpleCase,10.008,M.A,100,1000,0
LINK,0,2,SimpleCase,1.004,M.B,110.01211950565931,500,0
LINK,1,0,SimpleCase,10.008,M.A,200,1000,0
LINK,0,2,SimpleCase,1.004,M.B,210.01211950565934,500,0
LINK,1,0,SimpleCase,10.008,M.A,300,1000,0
LINK,0,2,SimpleCase,1.004,M.B,310.0121195056593,500,0
In these types of events, the following attributes are recorded:
- type Link type
- src Source of the message - ID node topology
- dst Destination of the message - ID node topology
- app application name
- latency the time taken to transmit the message between both nodes.
- message message name
- ctime simulation time
- size size of the message
- buffer This variable represents the number of waiting messages in all the links.
How to obtain statistics of these results depends on the user, although there are a good number of processes implemented to obtain the main stats such as: average response time, average service time, average wait time, node utilization, average link latency, costs, and so on.
You can find this example in the following subsection: basic example.
So far, we have explained the main parts of the simulator. Maybe it takes more than 5 minutes to understand this modelling, but the title of the section was attractive with that number. If you want to go deeper, you have to look at the rest of the sections: architecture details explaining key concepts, a number of examples and the API reference.
[1] | Gupta, H., Vahid Dastjerdi, A., Ghosh, S. K., & Buyya, R. (2017). iFogSim: A toolkit for modeling and simulation of resource management techniques in the Internet of Things, Edge and Fog computing environments. Software: Practice and Experience, 47(9), 1275-1296. |
[2] | Calheiros, R. N., Ranjan, R., Beloglazov, A., De Rose, C. A., & Buyya, R. (2011). CloudSim: a toolkit for modeling and simulation of cloud computing environments and evaluation of resource provisioning algorithms. Software: Practice and experience, 41(1), 23-50. |