diff --git a/extensions/feature-priority-core-pinning/apply-priority-core-pinning-patch.sh b/deployment/extensions/feature-priority-core-pinning/apply-priority-core-pinning-patch.sh similarity index 100% rename from extensions/feature-priority-core-pinning/apply-priority-core-pinning-patch.sh rename to deployment/extensions/feature-priority-core-pinning/apply-priority-core-pinning-patch.sh diff --git a/extensions/feature-priority-core-pinning/readme.md b/deployment/extensions/feature-priority-core-pinning/readme.md similarity index 100% rename from extensions/feature-priority-core-pinning/readme.md rename to deployment/extensions/feature-priority-core-pinning/readme.md diff --git a/extensions/gc-emulator-service/.gitignore b/deployment/extensions/gc-emulator-service/.gitignore similarity index 100% rename from extensions/gc-emulator-service/.gitignore rename to deployment/extensions/gc-emulator-service/.gitignore diff --git a/extensions/gc-emulator-service/Service.go b/deployment/extensions/gc-emulator-service/Service.go similarity index 100% rename from extensions/gc-emulator-service/Service.go rename to deployment/extensions/gc-emulator-service/Service.go diff --git a/extensions/gc-emulator-service/build-for-linux-amd64.sh b/deployment/extensions/gc-emulator-service/build-for-linux-amd64.sh similarity index 100% rename from extensions/gc-emulator-service/build-for-linux-amd64.sh rename to deployment/extensions/gc-emulator-service/build-for-linux-amd64.sh diff --git a/extensions/gc-emulator-service/go.mod b/deployment/extensions/gc-emulator-service/go.mod similarity index 100% rename from extensions/gc-emulator-service/go.mod rename to deployment/extensions/gc-emulator-service/go.mod diff --git a/extensions/gc-emulator-service/go.sum b/deployment/extensions/gc-emulator-service/go.sum similarity index 100% rename from extensions/gc-emulator-service/go.sum rename to deployment/extensions/gc-emulator-service/go.sum diff --git a/extensions/gc-emulator-service/internal/actions.go b/deployment/extensions/gc-emulator-service/internal/actions.go similarity index 100% rename from extensions/gc-emulator-service/internal/actions.go rename to deployment/extensions/gc-emulator-service/internal/actions.go diff --git a/extensions/gc-emulator-service/internal/apis.go b/deployment/extensions/gc-emulator-service/internal/apis.go similarity index 100% rename from extensions/gc-emulator-service/internal/apis.go rename to deployment/extensions/gc-emulator-service/internal/apis.go diff --git a/extensions/gc-emulator-service/internal/config-parser.go b/deployment/extensions/gc-emulator-service/internal/config-parser.go similarity index 100% rename from extensions/gc-emulator-service/internal/config-parser.go rename to deployment/extensions/gc-emulator-service/internal/config-parser.go diff --git a/extensions/gc-emulator-service/internal/external.go b/deployment/extensions/gc-emulator-service/internal/external.go similarity index 100% rename from extensions/gc-emulator-service/internal/external.go rename to deployment/extensions/gc-emulator-service/internal/external.go diff --git a/extensions/gc-emulator-service/internal/models.go b/deployment/extensions/gc-emulator-service/internal/models.go similarity index 100% rename from extensions/gc-emulator-service/internal/models.go rename to deployment/extensions/gc-emulator-service/internal/models.go diff --git a/extensions/gc-emulator-service/readme.md b/deployment/extensions/gc-emulator-service/readme.md similarity index 100% rename from extensions/gc-emulator-service/readme.md rename to deployment/extensions/gc-emulator-service/readme.md diff --git a/extensions/gc-emulator-service/scripts/gc-controller-sleep.sh b/deployment/extensions/gc-emulator-service/scripts/gc-controller-sleep.sh similarity index 100% rename from extensions/gc-emulator-service/scripts/gc-controller-sleep.sh rename to deployment/extensions/gc-emulator-service/scripts/gc-controller-sleep.sh diff --git a/extensions/gc-emulator-service/scripts/gc-controller-wake.sh b/deployment/extensions/gc-emulator-service/scripts/gc-controller-wake.sh similarity index 100% rename from extensions/gc-emulator-service/scripts/gc-controller-wake.sh rename to deployment/extensions/gc-emulator-service/scripts/gc-controller-wake.sh diff --git a/extensions/gc-emulator-service/scripts/gc-emul-envs.sh b/deployment/extensions/gc-emulator-service/scripts/gc-emul-envs.sh similarity index 100% rename from extensions/gc-emulator-service/scripts/gc-emul-envs.sh rename to deployment/extensions/gc-emulator-service/scripts/gc-emul-envs.sh diff --git a/extensions/gc-emulator-service/scripts/openstack-get-server-by-domain.sh b/deployment/extensions/gc-emulator-service/scripts/openstack-get-server-by-domain.sh similarity index 100% rename from extensions/gc-emulator-service/scripts/openstack-get-server-by-domain.sh rename to deployment/extensions/gc-emulator-service/scripts/openstack-get-server-by-domain.sh diff --git a/extensions/gc-emulator-service/scripts/openstack-shelve-offload-server.sh b/deployment/extensions/gc-emulator-service/scripts/openstack-shelve-offload-server.sh similarity index 100% rename from extensions/gc-emulator-service/scripts/openstack-shelve-offload-server.sh rename to deployment/extensions/gc-emulator-service/scripts/openstack-shelve-offload-server.sh diff --git a/extensions/gc-emulator-service/scripts/virsh-domain-get-pinned-cpu-core.sh b/deployment/extensions/gc-emulator-service/scripts/virsh-domain-get-pinned-cpu-core.sh similarity index 100% rename from extensions/gc-emulator-service/scripts/virsh-domain-get-pinned-cpu-core.sh rename to deployment/extensions/gc-emulator-service/scripts/virsh-domain-get-pinned-cpu-core.sh diff --git a/extensions/gc-emulator-service/scripts/virsh-list-domains.sh b/deployment/extensions/gc-emulator-service/scripts/virsh-list-domains.sh similarity index 100% rename from extensions/gc-emulator-service/scripts/virsh-list-domains.sh rename to deployment/extensions/gc-emulator-service/scripts/virsh-list-domains.sh diff --git a/extensions/nova-feature-diff.patch b/deployment/extensions/nova-feature-diff.patch similarity index 100% rename from extensions/nova-feature-diff.patch rename to deployment/extensions/nova-feature-diff.patch diff --git a/extensions/readme.md b/deployment/extensions/readme.md similarity index 100% rename from extensions/readme.md rename to deployment/extensions/readme.md diff --git a/extensions/restart-devstack-services.sh b/deployment/extensions/restart-devstack-services.sh similarity index 100% rename from extensions/restart-devstack-services.sh rename to deployment/extensions/restart-devstack-services.sh diff --git a/extensions/workaround-omit-sleeping-core-from-pcpu/apply-omit-sleeping-core-patch.sh b/deployment/extensions/workaround-omit-sleeping-core-from-pcpu/apply-omit-sleeping-core-patch.sh similarity index 100% rename from extensions/workaround-omit-sleeping-core-from-pcpu/apply-omit-sleeping-core-patch.sh rename to deployment/extensions/workaround-omit-sleeping-core-from-pcpu/apply-omit-sleeping-core-patch.sh diff --git a/extensions/workaround-omit-sleeping-core-from-pcpu/readme.md b/deployment/extensions/workaround-omit-sleeping-core-from-pcpu/readme.md similarity index 100% rename from extensions/workaround-omit-sleeping-core-from-pcpu/readme.md rename to deployment/extensions/workaround-omit-sleeping-core-from-pcpu/readme.md diff --git a/experiment/experiment-design.md b/experiment/experiment-design.md new file mode 100644 index 0000000..062dd37 --- /dev/null +++ b/experiment/experiment-design.md @@ -0,0 +1,61 @@ +### Experiment design + +We need to replay a production VM arrival trace on the system. We can evaluate different packing strategies +then. + +Limitation is inventory of the deployment(36 cpu cores) is smaller than of a cloud inventory (~15k+ machines). + +Solution is generating a vm trace suitable for the deployment, based on the production trace. + +We need to decide followings. + +Trace features. + +- VM arrival rate: How many VMs arrive at a given time +- VM size: vCPU count +- VM type: Evictable or Regular + +Experiment settings. + +- Total duration for the experiment +- Time period of Renewable availability + +#### Inventory + +A five node Openstack cluster with green cores enabled. + +- 16 cores: 12 Regular + 4 Green +- 8 cores: 5 Regular + 3 Green +- 4 cores: 4 Regular + 1 Green +- 4 cores: 4 Regular + 1 Green +- 4 cores: 4 Regular + 1 Green \[Physical Access\] + +One of the machine provides admin access to bios, and provides host os that runs on bare-metal. + +Physical access machine provides power stats, as well as true control over CPU core power management. All machines +provide a packing inventory. Therefore, packing metrics such as green score, density and utilization are calculated +all over the cluster and physical machine provide power consumption metrics. + +### Trace goals + +Generated trace should roughly utilize inventory around 70-80% (=production cloud inventory data) + +#### pre-process + +We select X-percentile of the workload. say 90th percentile. + +We further pick a time period, t1 and t2. ex: 0.0 - 1.0. + +Within the time period, we explore each time step. calculate number of requests in each step, to get request distribution. obtain vcpu distribution +and lifetime distribution. then for the X-th percentile, we find the max number for each (y for vcp, z for requests, etc). + +We then reduce the trace by converting each time step via the calculate max values. + +if count is too much, we omit all requests from that step. if vcpu is too much, we omit that vm request. likewise. + +result is reduced trace. + +when pre-process script ran, initially it prits max values. so percentile can be adjusted by guessing for the size of the +inventory we have. + +ex: for 26 cores inventory, maybe 4 requests max at a time suits. then 70th percentile is better. \ No newline at end of file diff --git a/vm-trace/az-trace-gen/.gitignore b/experiment/legacy-workload/az-trace-gen/.gitignore similarity index 100% rename from vm-trace/az-trace-gen/.gitignore rename to experiment/legacy-workload/az-trace-gen/.gitignore diff --git a/vm-trace/az-trace-gen/pom.xml b/experiment/legacy-workload/az-trace-gen/pom.xml similarity index 100% rename from vm-trace/az-trace-gen/pom.xml rename to experiment/legacy-workload/az-trace-gen/pom.xml diff --git a/vm-trace/az-trace-gen/remote-exec-debug.sh b/experiment/legacy-workload/az-trace-gen/remote-exec-debug.sh similarity index 100% rename from vm-trace/az-trace-gen/remote-exec-debug.sh rename to experiment/legacy-workload/az-trace-gen/remote-exec-debug.sh diff --git a/vm-trace/az-trace-gen/src/main/java/org/crunchycookie/research/tracegen/Service.java b/experiment/legacy-workload/az-trace-gen/src/main/java/org/crunchycookie/research/tracegen/Service.java similarity index 100% rename from vm-trace/az-trace-gen/src/main/java/org/crunchycookie/research/tracegen/Service.java rename to experiment/legacy-workload/az-trace-gen/src/main/java/org/crunchycookie/research/tracegen/Service.java diff --git a/vm-trace/az-trace-gen/src/main/java/org/crunchycookie/research/tracegen/clients/OpenstackComputeClient.java b/experiment/legacy-workload/az-trace-gen/src/main/java/org/crunchycookie/research/tracegen/clients/OpenstackComputeClient.java similarity index 100% rename from vm-trace/az-trace-gen/src/main/java/org/crunchycookie/research/tracegen/clients/OpenstackComputeClient.java rename to experiment/legacy-workload/az-trace-gen/src/main/java/org/crunchycookie/research/tracegen/clients/OpenstackComputeClient.java diff --git a/vm-trace/az-trace-gen/src/main/resources/configs.properties b/experiment/legacy-workload/az-trace-gen/src/main/resources/configs.properties similarity index 100% rename from vm-trace/az-trace-gen/src/main/resources/configs.properties rename to experiment/legacy-workload/az-trace-gen/src/main/resources/configs.properties diff --git a/vm-trace/az-trace-gen/src/main/resources/log4j2.xml b/experiment/legacy-workload/az-trace-gen/src/main/resources/log4j2.xml similarity index 100% rename from vm-trace/az-trace-gen/src/main/resources/log4j2.xml rename to experiment/legacy-workload/az-trace-gen/src/main/resources/log4j2.xml diff --git a/vm-trace/az-trace-gen/src/main/resources/os-client/create-vm.sh b/experiment/legacy-workload/az-trace-gen/src/main/resources/os-client/create-vm.sh similarity index 100% rename from vm-trace/az-trace-gen/src/main/resources/os-client/create-vm.sh rename to experiment/legacy-workload/az-trace-gen/src/main/resources/os-client/create-vm.sh diff --git a/vm-trace/az-trace-gen/src/main/resources/os-client/delete-vm.sh b/experiment/legacy-workload/az-trace-gen/src/main/resources/os-client/delete-vm.sh similarity index 100% rename from vm-trace/az-trace-gen/src/main/resources/os-client/delete-vm.sh rename to experiment/legacy-workload/az-trace-gen/src/main/resources/os-client/delete-vm.sh diff --git a/vm-trace/az-trace-gen/src/main/resources/os-client/image-list.sh b/experiment/legacy-workload/az-trace-gen/src/main/resources/os-client/image-list.sh similarity index 100% rename from vm-trace/az-trace-gen/src/main/resources/os-client/image-list.sh rename to experiment/legacy-workload/az-trace-gen/src/main/resources/os-client/image-list.sh diff --git a/vm-trace/vm-trace-generation.md b/experiment/legacy-workload/vm-trace-generation.md similarity index 100% rename from vm-trace/vm-trace-generation.md rename to experiment/legacy-workload/vm-trace-generation.md diff --git a/experiment/trace-generation/create_flavours.py b/experiment/trace-generation/create_flavours.py new file mode 100644 index 0000000..802cee1 --- /dev/null +++ b/experiment/trace-generation/create_flavours.py @@ -0,0 +1,3 @@ +from openstack_client import create_flavours + +create_flavours() \ No newline at end of file diff --git a/experiment/trace-generation/external.py b/experiment/trace-generation/external.py new file mode 100644 index 0000000..7bf2be4 --- /dev/null +++ b/experiment/trace-generation/external.py @@ -0,0 +1,68 @@ +import csv +from openstack_client import create_flavours, create_vm, delete_vm + + +class RequestsManager: + '''OsManager encapsulate vm lifecycle management based on the trace information. + It further provides an insight on core utilization. + ''' + + def __init__(self): + self.local_tracking_total_cores = 36 + self.local_tracking_used_cores = 0 + self.created_vms = {} + self.evictedVMs = [] + self.uninterruptedVMs = [] + + def dispatch(self, vm_rqs, clk): + self.create_vms(vm_rqs, clk) + + def handle_expired_vms(self, clk): + for vm_name, vm in self.created_vms.items(): + if vm['end-of-life'] <= clk: + resp = self.delete_vm(vm) + if not resp: + # VM does not exist. Must be evicted. + print('failed deletion. marking as evicted: ', vm['name']) + vm = self.created_vms[vm_name] + vm['is-evicted'] = True + else: + vm['is-deleted'] = True + vm['end-of-life'] = 100 # a very large value that we will never reach + + def create_vms(self, vm_rqs, clk): + for vm in vm_rqs: + resp = self.create_vm(vm, clk) + if resp: + print('marked successful vm creation of: ', vm['name']) + vm['end-of-life'] = clk + vm['lifetime'] + vm['is-evicted'] = False # assume vm is going to live a full life. + self.created_vms[vm['name']] = vm + self.local_tracking_used_cores += vm['vcpu'] + + def create_vm(self, vm, clk): + return create_vm(vm) + + def delete_vm(self, vm): + return delete_vm(vm) + + def get_utilization(self): + return self.local_tracking_used_cores / self.local_tracking_total_cores + + def dump(self, file_path): + header = ['name', 'type', 'vcpu', 'lifetime', 'is-evicted'] + + with open(file_path, 'w', encoding='UTF8') as f: + writer = csv.writer(f) + + # write the header + writer.writerow(header) + + for vm in self.created_vms.values(): + writer.writerow([ + vm['name'], + vm['type'], + vm['vcpu'], + vm['lifetime'], + vm['is-evicted'] + ]) diff --git a/experiment/trace-generation/math_utils.py b/experiment/trace-generation/math_utils.py new file mode 100644 index 0000000..342433f --- /dev/null +++ b/experiment/trace-generation/math_utils.py @@ -0,0 +1,19 @@ +import scipy.stats + + +def pick_random(dst): + is_uniform = len(set(dst)) == 1 + if is_uniform: + return dst[0] + + lower_bd = min(dst) + upper_bd = max(dst) + kde = scipy.stats.gaussian_kde(dst) + + # kde can include out of range. + sample = kde.resample(size=1) + val = sample[0][0] + while lower_bd >= val >= upper_bd: + sample = kde.resample(size=1) + val = sample[0][0] + return val diff --git a/experiment/trace-generation/openstack_client.py b/experiment/trace-generation/openstack_client.py new file mode 100644 index 0000000..185482a --- /dev/null +++ b/experiment/trace-generation/openstack_client.py @@ -0,0 +1,52 @@ +import subprocess + +cmd = "date" + +# returns output as byte string +returned_output = subprocess.check_output(cmd) + +# using decode() function to convert byte string to string +print('Current date is:', returned_output.decode("utf-8")) + + +def create_flavours(): + # flavours support upto 12 vcpu. + for i in range(1, 13): + try: + cmd = "openstack flavor create --public pinned.vcpu-" + str(i) + " --id pinned.vcpu-" + str( + i) + " --ram 256 --disk 1 --vcpus " + str(i) + print(cmd) + returned_output = subprocess.check_output(cmd, shell=True) + print('flavour creation for vcpu:', i, returned_output.decode("utf-8")) + except: + print('failed flavour creation for vcpu:', i) + try: + cmd2 = "openstack flavor set pinned.vcpu-" + str(i) + " --property hw:cpu_policy=dedicated" + print(cmd2) + returned_output = subprocess.check_output(cmd2, shell=True) + print('setting dedicated for flavour creation for vcpu:', i, returned_output.decode("utf-8")) + except: + print('failed setting dedicated for flavour creation for vcpu:', i) + + +def create_vm(vm): + print('attempting to create vm: ', vm['name']) + try: + cmd = "openstack server create --nic net-id=\"public\" --image \"cirros-0.6.2-x86_64-disk\" --flavor \"pinned.vcpu-" + str( + round(vm['vcpu'])) + "\" \"" + vm['name'] + "\" --wait " + returned_output = subprocess.check_output(cmd, shell=True) + print('vm creation for vm:', vm, returned_output.decode("utf-8")) + return True + except: + return False + + +def delete_vm(vm): + print('attempting to delete vm: ', vm['name']) + try: + cmd = "openstack server delete " + vm['name'] + " --wait --force" + returned_output = subprocess.check_output(cmd, shell=True) + print('vm deletion for vm:', vm, returned_output.decode("utf-8")) + return True + except: + return False diff --git a/experiment/trace-generation/trace-generator.py b/experiment/trace-generation/trace-generator.py new file mode 100644 index 0000000..25db2b6 --- /dev/null +++ b/experiment/trace-generation/trace-generator.py @@ -0,0 +1,88 @@ +import math +import sys +import time +import uuid + +import pandas as pd + +from external import RequestsManager +from math_utils import pick_random + +# 1 - normalized azure trace csv +# 2 - starting time +# 3 - end time +# 4 - max number of requests at a time +# 5 - max lifetime of a vm +# 6 - max vcpu of an instant + +# Example: +# python3 trace-generator.py 4-min-test/nrl_azure_packing_2020_perc_55.csv 0.819502315018326 0.8208333 5 14.93 12 +# csv file is generated for 4 minutes (0.00277778 days) between 0.819502315018326 and 0.8208333. max req. set to 5 and +# max lifetime is the duration of experiment. +# Lifetime max: +# -- 24hours: 89.6387860183604 (unscaled val. in the trace) +# -- 4 min: 14.93 (above linearly scaled down for 4) + +nrl_trace_file = sys.argv[1] +t_start = float(sys.argv[2]) +t_stop = float(sys.argv[3]) + +# max_rq_cnt = float(sys.argv[4]) +# max_lft = float(sys.argv[5]) +# max_vcpu_cnt = float(sys.argv[6]) + +print("nrl_trace_file: ", nrl_trace_file, " t_start: ", t_start, " t_stop: ", t_stop) + +df = pd.read_csv(nrl_trace_file) +df = df[t_start <= df['time']] +df = df[df['time'] <= t_stop] + +EXPERIMENT_UUID = uuid.uuid4() + + +def generate_rqs(rq_count, row, time, type, bucket): + for rq in range(rq_count): + lifetime = pick_random(dst=eval(row['lifetime_distribution'][0])) + vcpu = round(pick_random(dst=eval(row['vcpu_distribution'][0]))) + if vcpu > 0: + bucket.append({ + 'name': 'VM-' + str(EXPERIMENT_UUID) + '-' + str(time) + '-' + type + '-' + str(rq), + 'type': type, + 'lifetime': lifetime, + 'vcpu': vcpu + }) + + +t_s = df['time'].values +os_manager = RequestsManager() +for idx, t in enumerate(t_s): + row = df.loc[df['time'] == t].to_dict('list') + + vm_rqs = [] + total_rq_cnt = row['request_count'][0] + # here rounding is upto us. we favour more evictable vms, assuming fine-grain trace analysis allows us to realize + # slightly larger evictable vm types. + reg_rq_cnt = round( + math.floor(total_rq_cnt * row['regular_vm_count'][0]) + ) + evct_rq_cnt = round( + math.ceil(total_rq_cnt * row['evictable_vm_count'][0]) + ) + if reg_rq_cnt > 0: + generate_rqs(rq_count=reg_rq_cnt, row=row, time=t, type='regular', bucket=vm_rqs) + if evct_rq_cnt > 0: + generate_rqs(rq_count=evct_rq_cnt, row=row, time=t, type='evictable', bucket=vm_rqs) + + #print('row: ', row, 'rq: ', vm_rqs, 'total rq: ', total_rq_cnt, 'evct: ', evct_rq_cnt, ' reg: ', reg_rq_cnt) + + os_manager.handle_expired_vms(clk=t) + os_manager.dispatch(vm_rqs=vm_rqs, clk=t) + + if (idx + 1) < len(t_s): + t_to = t_s[idx + 1] - t + wait_for = t_to * (24 * 3600) + print("time: ", t, "total requested: ", len(vm_rqs), "waiting for: ", wait_for, "cls util: ", + os_manager.get_utilization()) + time.sleep(wait_for) + +os_manager.dump(file_path='./trace-emulation-report_' + str(time.time()) + '.csv') diff --git a/experiment/trace-pre-process/.gitignore b/experiment/trace-pre-process/.gitignore new file mode 100644 index 0000000..b4d43e3 --- /dev/null +++ b/experiment/trace-pre-process/.gitignore @@ -0,0 +1 @@ +secrets.txt \ No newline at end of file diff --git a/experiment/trace-pre-process/4-min-data/nrl_azure_packing_2020_perc_55.csv b/experiment/trace-pre-process/4-min-data/nrl_azure_packing_2020_perc_55.csv new file mode 100644 index 0000000..bb90105 --- /dev/null +++ b/experiment/trace-pre-process/4-min-data/nrl_azure_packing_2020_perc_55.csv @@ -0,0 +1,191 @@ +time,request_count,regular_vm_count,evictable_vm_count,lifetime_distribution,vcpu_distribution +0.818067129701376,0,0,0,[],[] +0.8181018517352641,1,1.0,0.0,[0.0062871878035366535],"[1, 1, 1, 1, 1]" +0.8181134257465601,2,1.0,0.0,"[0.010015648324042559, 0.010010115802288055]","[1, 1]" +0.8181250002235174,3,1.0,0.0,"[0.001332580577582121, 0.001332580577582121, 0.020778784528374672]","[1, 1, 1]" +0.8181365742348135,1,1.0,0.0,[0.029275451321154833],[1] +0.8181481482461095,3,1.0,0.0,"[0.0019051735289394855, 0.0006804629229009151, 0.011200451292097569]","[1, 1, 1]" +0.8181597222574055,2,1.0,0.0,"[0.02051708335056901, 0.040882129687815905]","[1, 1, 1]" +0.8181712962687016,1,1.0,0.0,[0.015717650298029184],[1] +0.8181828702799976,1,1.0,0.0,[0.009562985971570015],[1] +0.8181944442912936,2,1.0,0.0,"[0.010397558100521564, 0.016574780456721783]","[1, 1]" +0.8182060183025897,0,0,0,[],[] +0.818229166790843,2,1.0,0.0,"[0.006453136447817087, 0.009449837729334831]","[1, 1, 1]" +0.818240740802139,1,1.0,0.0,[0.005880381911993027],[1] +0.8182523148134351,1,1.0,0.0,[0.0022286688908934593],"[1, 1]" +0.8182638888247311,0,0,0,[],[] +0.8182754628360271,2,1.0,0.0,"[0.002769641112536192, 0.00679776631295681]","[1, 1, 1]" +0.8182870368473232,1,0.3,0.7,[0.0012681367807090282],"[1, 1, 1]" +0.8182986113242805,1,1.0,0.0,[0.0012567010708153248],"[1, 1, 1, 1, 1, 1]" +0.8183101853355765,1,1.0,0.0,[0.008086492773145437],[1] +0.8183217593468726,1,1.0,0.0,[0.02697945572435856],[1] +0.8183333333581686,0,0,0,[],[] +0.8183449073694646,0,0,0,[],[] +0.8183564813807607,0,0,0,[],[] +0.8183680553920567,2,1.0,0.0,"[0.008060301188379526, 0.03614903939887881]","[1, 1]" +0.8183796294033527,2,1.0,0.0,"[0.007695173844695091, 0.007695173844695091]","[1, 1]" +0.8183912038803101,1,1.0,0.0,[0.007891817018389702],[1] +0.8184143519029021,2,1.0,0.0,"[0.025565404910594225, 0.0196599536575377]","[1, 1]" +0.8184259259141982,0,0,0,[],[] +0.8184374999254942,1,1.0,0.0,[0.017318611033260822],[1] +0.8184490739367902,0,0,0,[],[] +0.8184606479480863,0,0,0,[],[] +0.8184722224250436,1,1.0,0.0,[0.02568538160994649],[1] +0.8184837964363396,0,0,0,[],[] +0.8184953704476357,3,1.0,0.0,"[0.0033527431078255177, 0.0018728701397776604, 0.0003331713378429413]","[1, 1, 1]" +0.8185069444589317,1,1.0,0.0,[0.0008738888427615166],[1] +0.8185185184702277,1,1.0,0.0,[0.0025079050101339817],[1] +0.8185300924815238,1,1.0,0.0,[0.0016766204498708248],[1] +0.8185416664928198,1,1.0,0.0,[0.005238079000264406],[1] +0.8185532409697771,0,0,0,[],[] +0.8185648149810731,2,1.0,0.0,"[0.00805569440126419, 0.011398552916944027]","[1, 1]" +0.8185763889923692,2,1.0,0.0,"[0.0016350578516721725, 0.0016350578516721725]","[1, 1]" +0.8185879630036652,1,1.0,0.0,[0.0012889928184449673],"[1, 1]" +0.8185995370149612,2,1.0,0.0,"[0.002859039232134819, 0.006603530142456293]","[1, 1, 1, 1, 1, 1]" +0.8186111110262573,0,0,0,[],[] +0.8186226850375533,2,1.0,0.0,"[0.0011030323803424835, 0.0011030323803424835]","[1, 1]" +0.8186342590488493,2,1.0,0.0,"[0.008513414766639471, 0.017278599552810192]","[1, 1]" +0.8186458335258067,0,0,0,[],[] +0.8186574075371027,0,0,0,[],[] +0.8186921295709908,1,1.0,0.0,[0.0017896643839776516],[1] +0.8187037035822868,1,1.0,0.0,[0.020323009230196476],[1] +0.8187152775935829,0,0,0,[],[] +0.8187268520705402,0,0,0,[],[] +0.8187384260818362,0,0,0,[],[] +0.8187500000931323,1,1.0,0.0,[0.011212361045181751],"[1, 1, 1]" +0.8187615741044283,1,1.0,0.0,[0.0017406828701496124],[1] +0.8188078701496124,0,0,0,[],[] +0.8188194446265697,0,0,0,[],[] +0.8188310186378658,2,1.0,0.0,"[0.002790509257465601, 0.0252633448690176]","[1, 1, 1, 1]" +0.8188425926491618,2,1.0,0.0,"[0.0014127660542726517, 0.0014127660542726517]","[1, 1]" +0.8188541666604578,0,0,0,[],[] +0.8188657406717539,1,1.0,0.0,[0.007980914320796728],[1] +0.8189236111938953,0,0,0,[],[] +0.8189351852051914,0,0,0,[],[] +0.8189583332277834,0,0,0,[],[] +0.8189814812503755,1,1.0,0.0,[0.0017414814792573452],[1] +0.8190046297386289,0,0,0,[],[] +0.8190162037499249,3,1.0,0.0,"[0.020798773039132357, 0.020798773039132357, 0.006818657275289297]","[1, 1, 1]" +0.8190277777612209,1,1.0,0.0,[0.024732465390115976],[1] +0.819039351772517,1,1.0,0.0,[0.021957742981612682],[1] +0.819050925783813,1,1.0,0.0,[0.005851064808666706],[1] +0.819062499795109,1,1.0,0.0,[0.004423738457262516],[1] +0.8190856482833624,0,0,0,[],[] +0.8190972222946584,1,0.25,0.75,[0.0007881480269134045],[1] +0.8191087963059545,2,1.0,0.0,"[0.007413738407194614, 0.015572569333016872]","[1, 1]" +0.8191203703172505,0,0,0,[],[] +0.8191319443285465,1,1.0,0.0,[0.006526365876197815],[1] +0.8191435183398426,0,0,0,[],[] +0.8191550928167999,2,0.6,0.4,"[0.009433865547180176, 0.007136979140341282]","[1, 1]" +0.8191666668280959,1,1.0,0.0,[0.0008425693958997726],"[1, 1, 1]" +0.819178240839392,1,1.0,0.0,[0.024160081055015326],[1] +0.819201388861984,3,1.0,0.0,"[0.00674806721508503, 0.00674806721508503, 0.007158865686506033]","[1, 1, 1]" +0.8192245368845761,1,1.0,0.0,[0.0007364004850387573],[1] +0.8192361108958721,0,0,0,[],[] +0.8192476853728294,0,0,0,[],[] +0.8192592593841255,2,1.0,0.0,"[0.005570671055465937, 0.005673854146152735]","[1, 1]" +0.8192708333954215,2,1.0,0.0,"[0.006753298453986645, 0.006753298453986645]","[1, 1]" +0.8192824074067175,0,0,0,[],[] +0.8192939814180136,1,0.5,0.5,[0.020346736069768667],[1] +0.8193055554293096,1,1.0,0.0,[0.024891192093491554],[1] +0.8193171294406056,2,1.0,0.0,"[0.002225810196250677, 0.002225810196250677]","[1, 1, 1]" +0.819328703917563,0,0,0,[],[] +0.819340277928859,0,0,0,[],[] +0.8193634259514511,0,0,0,[],[] +0.8193749999627471,0,0,0,[],[] +0.8193865739740431,0,0,0,[],[] +0.8194097219966352,0,0,0,[],[] +0.8194328704848886,0,0,0,[],[] +0.8194444444961846,0,0,0,[],[] +0.8194560185074806,0,0,0,[],[] +0.8194675925187767,0,0,0,[],[] +0.8194907405413687,0,0,0,[],[] +0.819502315018326,1,1.0,0.0,[0.007810266222804785],[1] +0.8195138890296221,0,0,0,[],[] +0.8195370370522141,2,1.0,0.0,"[0.021492164116352797, 0.021492164116352797]","[1, 1, 1]" +0.8195486110635102,0,0,0,[],[] +0.8195601850748062,1,1.0,0.0,[0.005982083268463612],[1] +0.8195717590861022,1,1.0,0.0,[0.0029517943039536476],[1] +0.8195833335630596,1,1.0,0.0,[0.0077690621837973595],[1] +0.8195949075743556,0,0,0,[],[] +0.8196064815856516,1,1.0,0.0,[0.0024832291528582573],[1] +0.8196180555969477,0,0,0,[],[] +0.8196296296082437,3,0.8333333333333334,0.16666666666666666,"[0.0007834490388631821, 0.0007834490388631821, 0.0010858564637601376]","[1, 1, 1, 1, 1]" +0.8196412036195397,0,0,0,[],[] +0.8196527776308358,0,0,0,[],[] +0.8196759261190891,0,0,0,[],[] +0.8196875001303852,1,0.6666666666666666,0.3333333333333333,[0.0013710996136069298],[1] +0.8196990741416812,1,1.0,0.0,[0.0038639004342257977],"[1, 1, 1]" +0.8197106481529772,0,0,0,[],[] +0.8197222221642733,0,0,0,[],[] +0.8197337961755693,0,0,0,[],[] +0.8197453701868653,0,0,0,[],[] +0.8197685186751187,0,0,0,[],[] +0.8197800926864147,0,0,0,[],[] +0.8197916666977108,2,1.0,0.0,"[0.00020668981596827507, 0.00020668981596827507]","[1, 1]" +0.8198032407090068,0,0,0,[],[] +0.8198148147203028,1,1.0,0.0,[0.010270428378134966],[1] +0.8198263887315989,1,1.0,0.0,[0.018203831277787685],[1] +0.8198379627428949,2,1.0,0.0,"[0.005552256945520639, 0.012014618143439293]","[1, 1]" +0.8198495372198522,1,1.0,0.0,[0.007471574004739523],[1] +0.8198611112311482,2,1.0,0.0,"[0.01432398147881031, 0.004887754563242197]","[1, 1]" +0.8198842592537403,1,1.0,0.0,[0.007360740564763546],[1] +0.8198958332650363,0,0,0,[],[] +0.8199189812876284,2,1.0,0.0,"[0.0007590628229081631, 0.0026325578801333904]","[1, 1]" +0.8199305557645857,1,1.0,0.0,[0.008728020824491978],[1] +0.8199421297758818,0,0,0,[],[] +0.8199537037871778,2,1.0,0.0,"[0.0017007174901664257, 0.014377488289028406]","[1, 1]" +0.8199999998323619,1,1.0,0.0,[0.0017814585007727146],[1] +0.8200347223319113,1,1.0,0.0,[0.0013854163698852062],[1] +0.8200462963432074,2,1.0,0.0,"[0.0019718632102012634, 0.0019718632102012634]","[1, 1]" +0.8200578703545034,1,1.0,0.0,[0.0076803588308393955],[1] +0.8200694443657994,1,1.0,0.0,[0.010701435152441263],[1] +0.8200810183770955,0,0,0,[],[] +0.8200925923883915,1,1.0,0.0,[0.025979953818023205],[1] +0.8201273148879409,0,0,0,[],[] +0.8201388888992369,0,0,0,[],[] +0.820162036921829,3,1.0,0.0,"[0.0009451969526708126, 0.0016276855021715164, 0.0016276855021715164]","[1, 1, 1]" +0.8201851854100823,0,0,0,[],[] +0.8201967594213784,2,1.0,0.0,"[0.0006878008134663105, 0.0007332060486078262]","[1, 1]" +0.8202083334326744,1,1.0,0.0,[0.015278946608304977],[1] +0.8202314814552665,1,1.0,0.0,[0.014316446613520384],[1] +0.8202430554665625,3,1.0,0.0,"[0.007541828788816929, 0.007541828788816929, 0.005435544066131115]","[1, 1, 1]" +0.8202546294778585,1,1.0,0.0,[0.0014020372182130814],[1] +0.8202662034891546,1,1.0,0.0,[0.008554270956665277],[1] +0.8202893519774079,1,1.0,0.0,[0.021144027821719646],[1] +0.8203125,1,1.0,0.0,[0.005372835788875818],[1] +0.8203356480225921,1,1.0,0.0,[0.014800451695919037],"[1, 1, 1]" +0.8203587965108454,0,0,0,[],[] +0.8203703705221415,0,0,0,[],[] +0.8203935185447335,0,0,0,[],[] +0.8204050925560296,2,1.0,0.0,"[0.004179560113698244, 0.006029363255947828]","[1, 1]" +0.8204166665673256,1,1.0,0.0,[0.017043483909219503],[1] +0.8204282405786216,2,1.0,0.0,"[0.0008078934624791145, 0.0008078934624791145]","[1, 1]" +0.8204398145899177,2,1.0,0.0,"[0.006715845316648483, 0.006715845316648483]","[1, 1]" +0.820451389066875,0,0,0,[],[] +0.820462963078171,2,1.0,0.0,"[0.014521620236337185, 0.014521620236337185]","[1, 1, 1]" +0.8205092591233552,1,1.0,0.0,[0.00856775464490056],[1] +0.8205208331346512,0,0,0,[],[] +0.8205555556342006,2,1.0,0.0,"[0.0017099305987358093, 0.0017098723910748959]","[1, 1, 1, 1]" +0.8205671296454966,0,0,0,[],[] +0.8205787036567926,0,0,0,[],[] +0.8205902776680887,3,1.0,0.0,"[0.005263229366391897, 0.005259780213236809, 0.005260624922811985]","[1, 1, 1]" +0.8206018516793847,3,1.0,0.0,"[0.0014118175022304058, 0.02254778938367963, 0.013190983794629574]","[1, 1, 1, 1, 1, 1]" +0.820613426156342,1,1.0,0.0,[0.0028753005899488926],[1] +0.8206250001676381,0,0,0,[],[] +0.8206365741789341,0,0,0,[],[] +0.8206481481902301,1,1.0,0.0,[0.015410844702273607],"[1, 1, 1, 1]" +0.8206597222015262,0,0,0,[],[] +0.8206712962128222,0,0,0,[],[] +0.8206828702241182,2,1.0,0.0,"[0.02361583337187767, 0.02361583337187767]","[1, 1]" +0.8206944442354143,2,1.0,0.0,"[0.0006894329562783241, 0.0009909379296004772]","[1, 1]" +0.8207060187123716,0,0,0,[],[] +0.8207175927236676,2,1.0,0.0,"[0.023720717523247004, 0.023720717523247004]","[1, 1]" +0.8207291667349637,1,0.5,0.5,[0.023638471961021423],[1] +0.8207407407462597,0,0,0,[],[] +0.8207523147575557,0,0,0,[],[] +0.8207638887688518,2,1.0,0.0,"[0.010429687798023224, 0.010429687798023224]","[1, 1, 1]" +0.8207754627801478,0,0,0,[],[] +0.8208101852796972,0,0,0,[],[] +0.8208217592909932,0,0,0,[],[] +0.8208333333022892,0,0,0,[],[] diff --git a/experiment/trace-pre-process/pre_process_reader.py b/experiment/trace-pre-process/pre_process_reader.py new file mode 100644 index 0000000..833b232 --- /dev/null +++ b/experiment/trace-pre-process/pre_process_reader.py @@ -0,0 +1,159 @@ +import math +import os +import sys + +import numpy as np +from mysql.connector import connect + +PERCENTILE = int(sys.argv[3]) + +USER = os.getenv("USER") +PASSWORD = os.getenv("PASSWORD") +HOST = os.getenv("HOST") +DB = os.getenv("DB") +print("user: ", USER, "password: ", PASSWORD, "host: ", HOST, "db: ", DB) + + +def get_bounds_for_percentile(time_from, time_to): + with connect( + host=HOST, + user=USER, + password=PASSWORD, + database=DB, + ) as connection: + def run_query_for_many(qry): + with connection.cursor() as cursor: + cursor.execute(qry) + result = cursor.fetchall() + rs = [] + for row in result: + rs.append(row[0]) + return rs + + # request count. + rq_count_dst_qry = "select count(*) as c from vm where starttime > " + str( + time_from) + " and starttime < " + str(time_to) + " group by starttime;" + count_max_val, count_min_val = get_min_max_for_percentile(rq_count_dst_qry, run_query_for_many) + + # vcpu count. + vcpu_dst_qry = "select vmCPUCores as c from vm inner join vmTypeToCores on vm.vmTypeId = vmTypeToCores.vmTypeId where starttime > " + str( + time_from) + " and starttime < " + str(time_to) + vcpu_max_val, vcpu_min_val = get_min_max_for_percentile(vcpu_dst_qry, run_query_for_many) + + # lifetimes count. + lifetimes_dst_qry = "select IFNULL(vm.endtime - vm.starttime, 14.0) as c from vm where starttime > " + str( + time_from) + " and starttime < " + str(time_to) + lifetimes_max_val, lifetimes_min_val = get_min_max_for_percentile(lifetimes_dst_qry, run_query_for_many) + + max_vals = { + "vcpu_max": vcpu_max_val, + "vcpu_min": vcpu_min_val, + "lifetime_max": lifetimes_max_val, + "lifetime_min": lifetimes_min_val, + "count_min": count_min_val, + "count_max": count_max_val + } + print('min-max vals for percentile: ' + str(PERCENTILE), max_vals) + + return max_vals + + +def get_min_max_for_percentile(rq_count_dst_qry, run_query_for_many): + dst = run_query_for_many(qry=rq_count_dst_qry) + sorted_dst = sorted(dst) + perc_val = np.percentile(sorted_dst, PERCENTILE) + sorted_dst = list(filter(lambda x: x < perc_val, sorted_dst)) + max_val = max(sorted_dst) + min_val = min(sorted_dst) + return max_val, min_val + + +def get_time_after(time_in_days_fraction=0.0): + with connect( + host=HOST, + user=USER, + password=PASSWORD, + database=DB, + ) as connection: + qry = "select starttime from vm where starttime > " + str( + time_in_days_fraction) + " order by starttime asc limit 1" + with connection.cursor() as cursor: + cursor.execute(qry) + result = cursor.fetchall() + for row in result: + return row[0] + + +def get_trace_at(time_in_days_fraction=0.0, max_consts={}): + with connect( + host=HOST, + user=USER, + password=PASSWORD, + database=DB, + ) as connection: + qry = "select vmCPUCores, priority, starttime, endtime from vm inner join vmTypeToCores on vm.vmTypeId = vmTypeToCores.vmTypeId where starttime = " + str( + time_in_days_fraction) + with connection.cursor() as cursor: + cursor.execute(qry) + result = cursor.fetchall() + request_count = 0 + regular_vm_count = 0 + evictable_vm_count = 0 + vcpu_dst = [] + lifetime_dst = [] + for row in result: + is_valid = True + vcpu = row[0] + is_evictable = row[1] == 1 + endtime = row[3] if row[3] else math.inf + lifetime = endtime - row[2] + + def collect(max, min, to_add, val): + if not max >= val >= min: + return False + + # nrl_val = (val - min) / (max - min) + # vcpu can be 2 max an 1 min. normalize can yield impractical numbers. + to_add.append(val) + return True + + is_valid = is_valid and collect(max=max_consts['vcpu_max'], min=max_consts['vcpu_min'], + to_add=vcpu_dst, val=vcpu) + is_valid = is_valid and collect(max=max_consts['lifetime_max'], min=max_consts['lifetime_min'], + to_add=lifetime_dst, val=lifetime) + + if is_valid: + request_count += 1 + + # We treat evictable as a characterictic and is independent of other parameters. then, say omiting an + # evictable vm because its vcpu is out of range, makes it dependent. so regardless of others, + # we count this property. + regular_vm_count += 1 if not is_evictable else 0 + evictable_vm_count += 1 if is_evictable else 0 + + bkt = [] + if collect(max=max_consts['count_max'], min=max_consts['count_min'], to_add=bkt, + val=request_count): + request_count = bkt[0] + reg_portion = regular_vm_count / (regular_vm_count + evictable_vm_count) + evict_portion = evictable_vm_count / (regular_vm_count + evictable_vm_count) + else: + request_count = 0 # outliers omitted. + reg_portion = 0 + evict_portion = 0 + lifetime_dst = [] + vcpu_dst = [] + + return { + 'time': time_in_days_fraction, + 'request_count': request_count, + 'regular_vm_count': reg_portion, + 'evictable_vm_count': evict_portion, + 'lifetime_distribution': lifetime_dst, + 'vcpu_distribution': vcpu_dst + } + + +def get_headers(): + return ['time', 'request_count', 'regular_vm_count', 'evictable_vm_count', 'lifetime_distribution', + 'vcpu_distribution'] diff --git a/experiment/trace-pre-process/run_pre_processing.py b/experiment/trace-pre-process/run_pre_processing.py new file mode 100644 index 0000000..d858d60 --- /dev/null +++ b/experiment/trace-pre-process/run_pre_processing.py @@ -0,0 +1,35 @@ +import csv +import sys +from pre_process_reader import get_trace_at, get_time_after, get_headers, get_bounds_for_percentile + +# make sure to set envs +# USER = os.getenv("USER") +# PASSWORD = os.getenv("PASSWORD") +# HOST = os.getenv("HOST") +# DB = os.getenv("DB") + +interval_start = float(sys.argv[1]) +interval_ends = float(sys.argv[2]) + +print("analyzing from: ", interval_start) +print("analyzing to: ", interval_ends) + +max_consts = get_bounds_for_percentile(time_from=interval_start, time_to=interval_ends) + +time = interval_start +records = [] +with open('4-min-data/nrl_azure_packing_2020.csv', 'w') as csvfile: + writer = csv.DictWriter(csvfile, fieldnames=get_headers()) + writer.writeheader() + while time < interval_ends: + time = get_time_after(time_in_days_fraction=time) + data = get_trace_at(time_in_days_fraction=time, max_consts=max_consts) + writer.writerow(data) + csvfile.flush() + print("analyze-- time: ", time) + +print("Done! Please check the csv file at current directory") + + + +#todo lifetime is -1 observed. fix this!