Parameters exploration#

This tutorial illustrates how parameters can be explored. The cornerstone here is the excellent Execo ParamSweeper. For the illustration purpose we consider the following question:

  • How the network performance is impacted by concurrent network flows and different network conditions ?

To answer this question we’ll simply measure the network throughput while varying the number of virtual machines pairs and network characteristics between them. For this purpose, we reserve 2 physical machines: one for the source (client) virtual machines and the other for the destination (server) virtual machines. Every single source virtual machine is then paired with its destination virtual machine. Different network delays will be applied between the sources and the destination.

 1import logging
 2import traceback
 3from pathlib import Path
 4from typing import Dict
 5
 6from execo_engine import ParamSweeper, sweep
 7
 8import enoslib as en
 9
10en.init_logging(level=logging.INFO)
11en.check()
12
13CLUSTER = "paranoia"
14
15
16def bench(parameter: Dict) -> None:
17    """Launch a benchmark.
18
19    1. Start the required resources.
20    2. Prepare the virtual machines
21    3. Benchmark the network
22    4. Backup
23    """
24    nb_vms = parameter["nb_vms"]
25    conf = (
26        en.VMonG5kConf.from_settings(force_deploy=True)
27        .add_machine(roles=["server"], cluster=CLUSTER, number=nb_vms, flavour="tiny")
28        .add_machine(roles=["client"], cluster=CLUSTER, number=nb_vms, flavour="tiny")
29    )
30
31    provider = en.VMonG5k(conf)
32
33    roles, networks = provider.init()
34    roles = en.sync_info(roles, networks)
35
36    servers = roles["server"]
37    clients = roles["client"]
38
39    for s, c in zip(servers, clients):
40        c.extra.update(target=s.address)
41
42    with en.actions(roles=roles) as p:
43        p.apt_repository(
44            repo="deb http://deb.debian.org/debian stretch main contrib non-free",
45            state="present",
46        )
47        p.apt(
48            name=[
49                "flent",
50                "netperf",
51                "python3-setuptools",
52                "python3-matplotlib",
53                "tmux",
54            ],
55            state="present",
56        )
57
58    with en.actions(pattern_hosts="server", roles=roles) as p:
59        p.shell("tmux new-session -d 'exec netperf'")
60
61    delay = parameter["delay"]
62    if delay is not None:
63        tc = dict(default_delay=delay, default_rate="10gbit", enabled=True)
64        netem = en.Netem(tc, roles=roles)
65        netem.deploy()
66    output = f"tcp_upload_{nb_vms}_{delay}"
67    with en.actions(pattern_hosts="client", roles=roles) as p:
68        p.shell(
69            "flent tcp_upload -p totals "
70            + "-l 60 "
71            + "-H {{ target }} "
72            + f"-t '{output}' "
73            + f"-o {output}.png",
74            display_name=f"Benchmarkings with {output}",
75        )
76        p.fetch(src=f"{output}.png", dest=f"result_{output}")
77
78
79parameters = dict(nb_vms=[1, 2, 4, 8, 16], delay=[None, "0ms", "10ms", "50ms"])
80
81
82sweeps = sweep(parameters)
83sweeper = ParamSweeper(
84    persistence_dir=str(Path("sweeps")), sweeps=sweeps, save_sweeps=True
85)
86
87parameter = sweeper.get_next()
88while parameter:
89    try:
90        print(parameter)
91        bench(parameter)
92        sweeper.done(parameter)
93    except Exception:
94        traceback.print_exc()
95        sweeper.skip(parameter)
96    finally:
97        parameter = sweeper.get_next()