Bexhoma Python Package
Benchmark Experiment Host Manager for Orchestration of DBMS Benchmarking Experiments in Clouds
{include} ../README.md
Example: TPC-H
This example shows how to benchmark 22 reading queries Q1-Q22 derived from TPC-H in MonetDB and PostgreSQL.
The query file is derived from the TPC-H and as such is not comparable to published TPC-H results, as the query file results do not comply with the TPC-H Specification.
Official TPC-H benchmark - http://www.tpc.org/tpch
Prerequisites
For basic execution of benchmarking we need
a Kubernetes (K8s) cluster
a namespace
my_namespace
in the clusterkubectl
usable, i.e. access token stored in a default vault like~/.kube
a persistent volume named
vol-benchmarking
containing the raw TPC-H data in/data/tpch/SF1/
JDBC driver
./monetdb-jdbc-2.29.jar
and./postgresql-42.2.5.jar
We need configuration files containing the following informations in a predefined format, c.f. demo file. The demo also includes the necessary settings for some DBMS: MariaDB, MonetDB, MySQL, OmniSci and PostgreSQL.
We may adjust the configuration to match the actual environment.
This in particular holds for imagePullSecrets
, tolerations
and nodeSelector
in the YAML files.
For also enabling monitoring we need
a monitoring instance Prometheus / Grafana that scrapes metrics from
localhost:9300
an access token and URL for asking Grafana for metrics
https://grafana.com/docs/grafana/latest/http_api/auth/#create-api-token
Perform Benchmark
For performing the experiment we can run the tpch file.
The actual configurations to benchmark are added by
config = configurations.default(experiment=experiment, docker='MonetDB', configuration='MonetDB-{}'.format(cluster_name), alias='DBMS 1')
config = configurations.default(experiment=experiment, docker='PostgreSQL', configuration='PostgreSQL-{}'.format(cluster_name), alias='DBMS 2')
Adjust Parameter
You maybe want to adjust some of the parameters that are set in the file: python tpch.py -h
usage: tpch.py [-h] [-db] [-c CONNECTION] [-cx CONTEXT] [-e EXPERIMENT] [-d] [-m] [-ms MAX_SUT] [-dt]
[-md MONITORING_DELAY] [-nr NUM_RUN] [-nc NUM_CONFIG] [-ne NUM_QUERY_EXECUTORS] [-sf SCALING_FACTOR]
[-t TIMEOUT] [-rr REQUEST_RAM] [-rc REQUEST_CPU] [-rct REQUEST_CPU_TYPE] [-rg REQUEST_GPU]
[-rgt REQUEST_GPU_TYPE] [-rst {None,,local-hdd,shared}] [-rss REQUEST_STORAGE_SIZE]
[-rnn REQUEST_NODE_NAME]
{profiling,run,start,load}
Perform TPC-H inspired benchmarks in a Kubernetes cluster. This either profiles the imported data in several DBMS and
compares some statistics, or runs the TPC-H queries. Optionally monitoring is actived. User can choose to detach the
componenten of the benchmarking system, so that as much as possible is run inside a Kubernetes (K8s) cluster. User can
also choose some parameters like number of runs per query and configuration and request some resources.
positional arguments:
{profiling,run,start,load}
profile the import of TPC-H data, or run the TPC-H queries, or start DBMS and load data, or
just start the DBMS
optional arguments:
-h, --help show this help message and exit
-db, --debug dump debug informations
-c CONNECTION, --connection CONNECTION
name of DBMS
-cx CONTEXT, --context CONTEXT
context of Kubernetes (for a multi cluster environment), default is current context
-e EXPERIMENT, --experiment EXPERIMENT
sets experiment code for continuing started experiment
-d, --detached puts most of the experiment workflow inside the cluster
-m, --monitoring activates monitoring
-ms MAX_SUT, --max-sut MAX_SUT
maximum number of parallel DBMS configurations, default is no limit
-dt, --datatransfer activates datatransfer
-md MONITORING_DELAY, --monitoring-delay MONITORING_DELAY
time to wait [s] before execution of the runs of a query
-nr NUM_RUN, --num-run NUM_RUN
number of runs per query
-nc NUM_CONFIG, --num-config NUM_CONFIG
number of runs per configuration
-ne NUM_QUERY_EXECUTORS, --num-query-executors NUM_QUERY_EXECUTORS
comma separated list of number of parallel clients
-sf SCALING_FACTOR, --scaling-factor SCALING_FACTOR
scaling factor (SF)
-t TIMEOUT, --timeout TIMEOUT
timeout for a run of a query
-rr REQUEST_RAM, --request-ram REQUEST_RAM
request ram
-rc REQUEST_CPU, --request-cpu REQUEST_CPU
request cpus
-rct REQUEST_CPU_TYPE, --request-cpu-type REQUEST_CPU_TYPE
request node having node label cpu=
-rg REQUEST_GPU, --request-gpu REQUEST_GPU
request number of gpus
-rgt REQUEST_GPU_TYPE, --request-gpu-type REQUEST_GPU_TYPE
request node having node label gpu=
-rst {None,,local-hdd,shared}, --request-storage-type {None,,local-hdd,shared}
request persistent storage of certain type
-rss REQUEST_STORAGE_SIZE, --request-storage-size REQUEST_STORAGE_SIZE
request persistent storage of certain size
-rnn REQUEST_NODE_NAME, --request-node-name REQUEST_NODE_NAME
request a specific node
The hardware requirements are set via
# pick hardware
cpu = str(args.request_cpu)
memory = str(args.request_ram)
cpu_type = str(args.request_cpu_type)
Evaluate Results in Dashboard
Evaluation is done using DBMSBenchmarker: https://github.com/Beuth-Erdelt/DBMS-Benchmarker/blob/master/docs/Dashboard.html
Concepts
An experiment is a benchmark of a DBMS in a certain host setting and a specific benchmark setting.
A host setting consists of
an instance (a virtual machine)
a DBMS (as a docker image)
a volume (containing some data)
an init script (telling the dbms how to store the data)
A benchmark setting consists of
a number of client processes
a number of runs per connection
a maximum timeout
a lot more, depending on the benchmark tool
Workflow
The management roughly means
In more detail this means
Prepare Experiment
Start Virtual Machine
AWS: Start Instance EC2
k8s: Create DeploymentAttach Network
AWS: Attach EIP
k8s: Create Service, Port ForwardingAttach Data Storage Volume
AWS: Attach and Mount EBS
k8s: Attach PVCStart Monitoring
Start Prometheus Exporter Docker Container
Start Experiment
Start DBMS Docker Container
Upload and run Init Scripts
Load Data from Data Storage Volume
Run Benchmarks
Report
Pull Logs
From DBMS ContainerPull Metrics
From Grafana Monitoring Server
Stop Experiment
AWS: Stop DBMS Docker Container, Remove Docker RemnantsClean Experiment
AWS: Unmount and Detach EBS Volume, Detach EIP, Stop Instance EC2
k8s: Stop Port Forwarding, Delete Deployment and Services
Prerequisits
This tool relies on
dbms benchmarker for the actual benchmarks
boto for AWS management
paramiko for SSH handling
scp for SCP handling
kubernetes for k8s management
and some more python libraries
How to configure an experiment setup
We need
a config file containing cluster information , say
cluster.config
a config folder, say
experiments/tpch/
, containinga config file
queries.config
for the workloadfolders for DDL scripts (per DBMS)
a python script managing the experimental workflow, say
tpch.py
, see example
To use the predefined examples you will only have to change the context and namespace of the Kubernetes cluster - see below.
Cluster-Config
The configuration of the cluster, that is the possible host and experiment settings, consists of these parts (see also example config file):
Config of the Benchmark tool
You probably can leave this as is.
'benchmarker': {
'resultfolder': './', # Local path to results folder of benchmark tool
'jarfolder': './jars/' # Optional: Local path to JDBC drivers
},
resultfolder
: Where the benchmarker puts it’s result foldersjarfolder
: Where the benchmarker expects the JDBC jar files
Both folders are used to correspond with the Docker containers of the benchmarker and must match the settings inside of the image.
Credentials of the Cluster
You will have to adjust the name of the namespace my_namespace
.
The rest probably can stay as is.
'credentials': {
'k8s': {
'appname': 'bexhoma', # K8s: To find corresponding deployments etc
'context': {
'my_context': { # K8s: Name of context of cluster
'namespace': 'my_namespace', # K8s: Namespace of User
'clustername': 'my_cluster', # K8s: Name of Cluster (just for annotation)
'service_sut': '{service}.{namespace}.svc.cluster.local',
'port': 9091, # K8s: Local port for connecting via JDBC after port forwarding
},
},
my_context
: Context (name) of the cluster. Repeat this section for every K8s cluster you want to use. This also allows to useand compare several Clouds.namespace
: Namespace in the cluster.port
: Arbitrary (free) local port that is used to ping running DBMS.
(Hardware) Monitoring
This defines where to scrape the Prometheus metrics and is defined per context (cluster). The services and the monitoring pods can be installed automatically by bexhoma.
'monitor': {
'service_monitoring': 'http://{service}.{namespace}.svc.cluster.local:9090/api/v1/',
'extend': 20,
'shift': 0,
extend
: Number of seconds the scraping interval should be extended (at both ends).shift
: Number of seconds the scraping interval should be shifted (into future).
(Hardware) Metrics
It follows a dict of hardware metrics that should be collected per DBMS. The attributes are set by bexhoms automatically so that corresponding pods can be identified. The host is found using the service of the DBMS.
'metrics': {
'total_cpu_memory': {
'query': 'container_memory_working_set_bytes{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}}/1024/1024',
'title': 'CPU Memory [MiB]'
},
'total_cpu_memory_cached': {
'query': 'container_memory_usage_bytes{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}}/1024/1024',
'title': 'CPU Memory Cached [MiB]'
},
'total_cpu_util': {
'query': 'sum(irate(container_cpu_usage_seconds_total{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}}[1m]))',
'title': 'CPU Util [%]'
},
'total_cpu_throttled': {
'query': 'sum(irate(container_cpu_cfs_throttled_seconds_total{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}}[1m]))',
'title': 'CPU Throttle [%]'
},
'total_cpu_util_others': {
'query': 'sum(irate(container_cpu_usage_seconds_total{{job="monitor-node", container_label_io_kubernetes_container_name!="dbms",id!="/"}}[1m]))',
'title': 'CPU Util Others [%]'
},
'total_cpu_util_s': {
'query': 'sum(container_cpu_usage_seconds_total{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}})',
'title': 'CPU Util [s]'
},
'total_cpu_util_user_s': {
'query': 'sum(container_cpu_user_seconds_total{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}})',
'title': 'CPU Util User [s]'
},
'total_cpu_util_sys_s': {
'query': 'sum(container_cpu_system_seconds_total{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}})',
'title': 'CPU Util Sys [s]'
},
'total_cpu_throttled_s': {
'query': 'sum(container_cpu_cfs_throttled_seconds_total{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}})',
'title': 'CPU Throttle [s]'
},
'total_cpu_util_others_s': {
'query': 'sum(container_cpu_usage_seconds_total{{job="monitor-node", container_label_io_kubernetes_container_name!="dbms",id!="/"}})',
'title': 'CPU Util Others [s]'
},
'total_network_rx': {
'query': 'sum(container_network_receive_bytes_total{{container_label_app="bexhoma", job="monitor-node"}})/1024/1024',
'title': 'Net Rx [MiB]'
},
'total_network_tx': {
'query': 'sum(container_network_transmit_bytes_total{{container_label_app="bexhoma", job="monitor-node"}})/1024/1024',
'title': 'Net Tx [MiB]'
},
'total_fs_read': {
'query': 'sum(container_fs_reads_bytes_total{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}})/1024/1024',
'title': 'FS Read [MiB]'
},
'total_fs_write': {
'query': 'sum(container_fs_writes_bytes_total{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}})/1024/1024',
'title': 'FS Write [MiB]'
},
'total_gpu_util': {
'query': 'sum(DCGM_FI_DEV_GPU_UTIL{{UUID=~"{gpuid}"}})',
'title': 'GPU Util [%]'
},
'total_gpu_power': {
'query': 'sum(DCGM_FI_DEV_POWER_USAGE{{UUID=~"{gpuid}"}})',
'title': 'GPU Power Usage [W]'
},
'total_gpu_memory': {
'query': 'sum(DCGM_FI_DEV_FB_USED{{UUID=~"{gpuid}"}})',
'title': 'GPU Memory [MiB]'
},
}
},
}
},
Data Sources
Data sources and imports can be adressed using a key. This is organized as follows:
'volumes': {
'tpch': {
'initscripts': {
'SF1': [
'initschema-tpch.sql',
'initdata-tpch-SF1.sql',
'initdata-tpch-SF1.sh'
],
'SF1-index': [
'initschema-tpch.sql',
'initdata-tpch-SF1.sql',
'initdata-tpch-SF1.sh',
'initindexes-tpch.sql',
],
'SF10': [
'initschema-tpch.sql',
'initdata-tpch-SF10.sql',
'initdata-tpch-SF10.sh'
],
'SF10-index': [
'initschema-tpch.sql',
'initdata-tpch-SF10.sql',
'initdata-tpch-SF10.sh',
'initindexes-tpch.sql',
],
}
}
},
tpch
: Name of the data source.initscripts
: Dict of scripts to load the data source into a database. It consists ofa name, for example
SF1-index
,a list of script names.
The scripts.sql
are sent to the command line tool of the DBMS (loadData
- see below) and the files.sh
are executed as shell scripts. The scripts must be present in a config folder, sayexperiments/tpch/
.
The data itself must reside on a persistent volume within the cluster, that will be mounted into the DBMS container.
The examples above refer to /data/tpch/SF1/
for example.
DBMS
DBMS can be adressed using a key.
We have to define some data per key, for example for the key MonetDB
we use:
'dockers': {
'MonetDB': {
'loadData': 'cd /home/monetdb;mclient demo < {scriptname}',
'template': {
'version': '11.37.11',
'alias': 'Columnwise',
'docker_alias': 'Columnwise',
'JDBC': {
'auth': ['monetdb', 'monetdb'],
'driver': 'nl.cwi.monetdb.jdbc.MonetDriver',
'jar': 'monetdb-jdbc-2.29.jar',
'url': 'jdbc:monetdb://{serverip}:9091/demo?so_timeout=0'
}
},
'logfile': '/tmp/monetdb5/dbfarm/merovingian.log',
'datadir': '/var/monetdb5/',
'priceperhourdollar': 0.0,
},
}
This includes
loadData
: A command to run a script inside of the DBMS. This will run inside of the container of the DBMS and is used to load data.{scriptname}
is a placeholder for the script name inside the container.template: [DBMS](https://dbmsbenchmarker.readthedocs.io/en/latest/DBMS.html) JDBC connection info that will be handed over to the benchmarker, c.f. example.
Some of the data in the reference, likehostsystem
, will be added by bexhoma automatically.
The JDBC driver jar must be locally available inside the container.
Some placeholders in the URL are:serverip
(set automatically to match the corresponding pod),dbname
,DBNAME
,timout_s
,timeout_ms
(name of the database in lower and upper case, timeout in seconds and miliseconds)logfile
anddatadir
that contain information about where the DBMS stores logs and databases resp.an optional
priceperhourdollar
that is currently ignored.
DBMS
To include a DBMS in a Kubernetes-based experiment you will need
a Docker Image
a JDBC Driver
a Kubernetes Deployment Template
some configuration
How to load data (DDL command)
DDL scripts
How to connect via JDBC
This document contains examples for
Example Explained
Deployment
See documentation of deployments.
Configuration
'dockers': {
'OmniSci': {
'loadData': 'bin/omnisql -u admin -pHyperInteractive < {scriptname}', # DBMS: Command to Login and Run Scripts
'template': { # Template for Benchmark Tool
'version': 'CE v5.4',
'alias': 'GPU',
'docker_alias': 'GPU',
'JDBC': {
'driver': 'com.omnisci.jdbc.OmniSciDriver',
'url': 'jdbc:omnisci:{serverip}:9091:omnisci',
'auth': {'user': 'admin', 'password': 'HyperInteractive'},
'jar': './omnisci-jdbc-4.7.1.jar' # DBMS: Local Path to JDBC Jar
}
},
'logfile': '/omnisci-storage/data/mapd_log/omnisci_server.INFO', # DBMS: Path to Log File on Server
'datadir': '/omnisci-storage/data/mapd_data/', # DBMS: Path to directory containing data storage
'priceperhourdollar': 0.0, # DBMS: Price per hour in USD if DBMS is rented
}
}
This has
a base name for the DBMS
a placeholder
template
for the benchmark toolthe JDBC driver jar locally available
a command
loadData
for running the init scripts with{scriptname}
as a placeholder for the script name inside the container{serverip}
as a placeholder for the host address (localhost for k8s, an Elastic IP for AWS){dbname}
as a placeholder for the db namean optional
priceperhourdollar
an optional name of a
logfile
that is downloaded after the benchmarkname of the
datadir
of the DBMS. It’s size is measured usingdu
after data loading has been finished.
MariaDB
Deployment
Configuration
'MariaDB': {
'loadData': 'mysql < {scriptname}',
'template': {
'version': 'v10.4.6',
'alias': 'GP A',
'docker_alias': 'GP A',
'dialect': 'MySQL',
'JDBC': {
'driver': "org.mariadb.jdbc.Driver",
'auth': ["root", ""],
'url': 'jdbc:mysql://{serverip}:9091/{dbname}',
'jar': './mariadb-java-client-2.3.0.jar'
}
},
'logfile': '',
'datadir': '/var/lib/mysql/',
'priceperhourdollar': 0.0,
},
**DDL Scripts**
Example for TPC-H
MonetDB
Deployment
Configuration
'MonetDB': {
'loadData': 'cd /home/monetdb;mclient db < {scriptname}',
'template': {
'version': 'v11.31.7',
'alias': 'In-Memory C',
'docker_alias': 'In-Memory C',
'JDBC': {
'auth': ['monetdb', 'monetdb'],
'driver': 'nl.cwi.monetdb.jdbc.MonetDriver',
'jar': './monetdb-jdbc-2.29.jar',
'url': 'jdbc:monetdb://{serverip}:9091/db'
}
},
'logfile': '',
'datadir': '/var/monetdb5/',
'priceperhourdollar': 0.0,
},
**DDL Scripts**
Example for TPC-H
OmniSci
Deployment
Configuration
'OmniSci': {
'loadData': 'bin/omnisql -u admin -pHyperInteractive < {scriptname}',
'template': {
'version': 'CE v4.7',
'alias': 'GPU A',
'docker_alias': 'GPU A',
'JDBC': {
'driver': 'com.omnisci.jdbc.OmniSciDriver',
'url': 'jdbc:omnisci:{serverip}:9091:omnisci',
'auth': {'user': 'admin', 'password': 'HyperInteractive'},
'jar': './omnisci-jdbc-4.7.1.jar'
}
},
'logfile': '/omnisci-storage/data/mapd_log/omnisci_server.INFO',
'datadir': '/omnisci-storage/',
'priceperhourdollar': 0.0,
},
**DDL Scripts**
Example for TPC-H
PostgreSQL
Deployment
Configuration
'PostgreSQL': {
'loadData': 'psql -U postgres < {scriptname}',
'template': {
'version': 'v11.4',
'alias': 'GP D',
'docker_alias': 'GP D',
'JDBC': {
'driver': "org.postgresql.Driver",
'auth': ["postgres", ""],
'url': 'jdbc:postgresql://{serverip}:9091/postgres',
'jar': './postgresql-42.2.5.jar'
}
},
'logfile': '',
'datadir': '/var/lib/postgresql/data/',
'priceperhourdollar': 0.0,
},
**DDL Scripts**
Example for TPC-H
Deployments in Kubernetes
The deployment is expected to be given as a file named 'deployment-'+docker+'-'+instance+'.yml'
Such files are generated from a template.
Content of this document:
How do templates work
What templates are included
Adjust the templates to your cluster
How to parametrize templates at runtime
Templates
Template files are named 'deploymenttemplate-"+docker+".yml'
.
To generate a file 'deployment-'+docker+'-'+instance+'.yml'
from this
the instance name is understood as
cpu-mem-gpu-gputype
the yaml file is changed as
dep['spec']['template']['spec']['containers'][0]['resources']['requests']['cpu'] = cpu dep['spec']['template']['spec']['containers'][0]['resources']['limits']['cpu'] = cpu dep['spec']['template']['spec']['containers'][0]['resources']['requests']['memory'] = mem dep['spec']['template']['spec']['containers'][0]['resources']['limits']['memory'] = mem dep['spec']['template']['spec']['nodeSelector']['gpu'] = gputype dep['spec']['template']['spec']['containers'][0]['resources']['limits']['nvidia.com/gpu'] = int(gpu)
Included
This repository includes some templates at https://github.com/Beuth-Erdelt/Benchmark-Experiment-Host-Manager/tree/master/k8s
DBMS included are:
MariaDB (10.4.6)
MonetDB (11.31.7)
OmniSci (v5.4.0)
PostgreSQL (11.4)
To be added in near future:
Exasol (7.0.0)
You will need a Docker image including EXAplusMemSQL (centos-7.1.8-43a12901be-2.0.0-1.7.0)
You will have to add a licence keyMySQL (8.0.21)
You will need a Docker image including tarOracle DB (18.4.0-xe)
You will need to build the Docker imageMS SQL Server (2019-CU5-ubuntu-18.04)
Your Cluster
To make these work, you may have to add the name of your Docker pull secret and the name of your persistant volume.
The default name of the secret is private-registry-auth
:
imagePullSecrets:
- {name: private-registry-auth}
The default name of the PV is volume-benchmarking
:
- name: benchmark-data-volume
persistentVolumeClaim: {claimName: volume-benchmarking}
Parametrize Templates
The resources (requests, limits and nodeSelector) can also be set explicitly using
cluster.set_resources(
requests = {
'cpu': cpu,
'memory': mem
},
limits = {
'cpu': 0, # unlimited
'memory': 0 # unlimited
},
nodeSelector = {
'cpu': cpu_type,
'gpu': gpu_type,
})
For further information and option see the documentation.
Monitoring
To include monitoring you will need
a Prometheus server scraping a fixed IP / Port
a Grafana server collecting metrics from the Prometheus server
some configuration what metrics to collect
This document contains information about the
Concept
There is
an Experiment Host - this needs Prometheus exporters
a Monitor - this needs a Prometheus server and a Grafana server scraping the Experiment Host
a Manager - this needs a configuration (which metrics to collect and where from)
Installation
To be documented
Kubernetes
Experiment Host: Exporters are part of the deployments
Monitor: Servers are deployed using Docker images, fixed on a separate monitoring instance
Manager: See configuration
AWS
Experiment Host: Exporters are deployed using Docker images, fixed on the benchmarked instance
Monitor: Servers are deployed using Docker images, fixed on a separate monitoring instance
Manager: See configuration
Configuration
We insert information about
the Grafana server
access token
URL
the collection
extension of measure intervals
time shift
metrics definitions
into the cluster configuration. This is handed over to the DBMS configuration of the benchmarker in a monitoring section.
Example
The details of the metrics correspond to the YAML configuration of the deployments:
job="monitor-node"
container_name="dbms"
'monitor': {
'grafanatoken': 'Bearer ABCDE==',
'grafanaurl': 'http://localhost:3000/api/datasources/proxy/1/api/v1/',
'grafanaextend': 20,
'grafanashift': 0,
'prometheus_url': 'http://localhost:9090/api/v1/',
'metrics': {
'total_cpu_memory': {
'query': 'container_memory_working_set_bytes{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}}',
'title': 'CPU Memory [MiB]'
},
'total_cpu_memory_cached': {
'query': 'container_memory_usage_bytes{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}}',
'title': 'CPU Memory Cached [MiB]'
},
'total_cpu_util': {
'query': 'sum(irate(container_cpu_usage_seconds_total{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}}[1m]))',
'title': 'CPU Util [%]'
},
'total_cpu_throttled': {
'query': 'sum(irate(container_cpu_cfs_throttled_seconds_total{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}}[1m]))',
'title': 'CPU Throttle [%]'
},
'total_cpu_util_others': {
'query': 'sum(irate(container_cpu_usage_seconds_total{{job="monitor-node", container_label_io_kubernetes_container_name!="dbms",id!="/"}}[1m]))',
'title': 'CPU Util Others [%]'
},
'total_cpu_util_s': {
'query': 'sum(container_cpu_usage_seconds_total{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}})',
'title': 'CPU Util [s]'
},
'total_cpu_throttled_s': {
'query': 'sum(container_cpu_cfs_throttled_seconds_total{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}})',
'title': 'CPU Throttle [s]'
},
'total_cpu_util_others_s': {
'query': 'sum(container_cpu_usage_seconds_total{{job="monitor-node", container_label_io_kubernetes_container_name!="dbms",id!="/"}})',
'title': 'CPU Util Others [s]'
},
'total_network_rx': {
'query': 'sum(container_network_receive_bytes_total{{container_label_app="dbmsbenchmarker", job="monitor-node"}})',
'title': 'Net Rx [b]'
},
'total_network_tx': {
'query': 'sum(container_network_transmit_bytes_total{{container_label_app="dbmsbenchmarker", job="monitor-node"}})',
'title': 'Net Tx [b]'
},
'total_fs_read': {
'query': 'sum(container_fs_reads_bytes_total{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}})',
'title': 'FS Read [b]'
},
'total_fs_write': {
'query': 'sum(container_fs_writes_bytes_total{{job="monitor-node", container_label_io_kubernetes_container_name="dbms"}})',
'title': 'FS Write [b]'
},
'total_gpu_util': {
'query': 'sum(DCGM_FI_DEV_GPU_UTIL{{UUID=~"{gpuid}"}})',
'title': 'GPU Util [%]'
},
'total_gpu_power': {
'query': 'sum(DCGM_FI_DEV_POWER_USAGE{{UUID=~"{gpuid}"}})',
'title': 'GPU Power Usage [W]'
},
'total_gpu_memory': {
'query': 'sum(DCGM_FI_DEV_FB_USED{{UUID=~"{gpuid}"}})',
'title': 'GPU Memory [MiB]'
},
}
}
Fine Tuning
If the Grafana server has metrics coming from general Prometheus server, that is it scrapes more exporters than just the bexhoma related, we will need to specify further which metrics we are interested in.
There is a placeholder {gpuid}
that is substituted automatically by a list of GPUs present in the pod.
Contributing to Bexhoma
You would like to contribute? Great!
Some things that you can help on include:
New Workloads: The
example/
folder includes the TPC-H and TPC-DS (reading) queries in various dialects. We are interested in adding other relevant workloads.Documentation: If a point in the documentation is unclear, we look forward to receiving tips and suggestions for improvement.
Testing: If the behavior is not as expected and you suspect a bug, please report it to our issue tracker.
Use Cases: If you have had any experiences with peculiarities, mistakes, ambiguities or oddities or particularly beautiful cases etc., we are interested in hearing about them and passing them on to others.
Non-code contributions
Even if you don’t feel ready or able to contribute code, you can still help out. There always things that can be improved on the documentation (even just proof reading, or telling us if a section isn’t clear enough).
Code contributions
We welcome pull requests to fix bugs or add new features.
Licensing
In your git commit and/or pull request, please explicitly state that you agree to your contributions being licensed under “GNU Affero General Public License v3”.
Git Usage
If you are planning to make a pull request, start by creating a new branch with a short but descriptive name (rather than using your master branch).
Coding Conventions
DBMSBenchmarker tries to follow the coding conventions laid out in PEP8 and PEP257
Testing
New features or functions will not be accepted without testing. Likewise for any enhancement or bug fix, we require including an additional test.
If the feature or functionality concerns benchmarking
We expect it to be testable with the TPC-H workload. Otherwise please add references to data and queries you used to test the functionality. They must be publicly accessible.
If the feature or functionality concerns evaluation
Please include a zipped result folder, so we can trace the enhancement of evaluations based on the same results you have used. (And please be sure to not include secret passwords in the connection information).
bexhoma package API
Subpackages
bexhoma.scripts package
Submodules
bexhoma.scripts.experimentsmanager module
This script contains some code snippets for testing the detached mode in Kubernetes
Copyright (C) 2021 Patrick Erdelt
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- bexhoma.scripts.experimentsmanager.manage()
bexhoma.scripts.tpcds module
- Date:
2021-02-12
- Version:
0.1
- Authors:
Patrick Erdelt
Perform TPC-DS inspired benchmarks in a Kubernetes cluster. This either profiles the imported data in several DBMS and compares some statistics, or runs the TPC-H queries. Optionally monitoring is actived. User can choose to detach the componenten of the benchmarking system, so that as much as possible is run inside a Kubernetes (K8s) cluster. User can also choose some parameters like number of runs per query and configuration and request some resources.
- bexhoma.scripts.tpcds.do_benchmark()
bexhoma.scripts.tpch module
- Date:
2021-02-12
- Version:
0.1
- Authors:
Patrick Erdelt
Perform TPC-H inspired benchmarks in a Kubernetes cluster. This either profiles the imported data in several DBMS and compares some statistics, or runs the TPC-H queries. Optionally monitoring is actived. User can choose to detach the componenten of the benchmarking system, so that as much as possible is run inside a Kubernetes (K8s) cluster. User can also choose some parameters like number of runs per query and configuration and request some resources.
- bexhoma.scripts.tpch.do_benchmark()
Module contents
The clustermanager module
Submodules
bexhoma.clusters module
- Date:
2022-10-01
- Version:
0.6.0
- Authors:
Patrick K. Erdelt
Module to manage testbeds. Historically this supported different implementations based on IaaS. All methods will be deprecated except for Kubernetes (K8s), so the structure will change in future.
Copyright (C) 2020 Patrick K. Erdelt
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- class bexhoma.clusters.aws(clusterconfig='cluster.config', experiments_configfolder='experiments/', yamlfolder='k8s/', context=None, code=None, instance=None, volume=None, docker=None, script=None, queryfile=None)
Bases:
kubernetes
- Date:
2022-10-01
- Version:
0.6.0
- Authors:
Patrick K. Erdelt
Class for containing Kubernetes methods specific to AWS. This adds handling of nodegroups for elasticity.
Copyright (C) 2020 Patrick K. Erdelt
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- check_nodegroup(nodegroup_type='', nodegroup_name='', num_nodes_aux_planned=0)
- eksctl(command)
Runs an eksctl command.
- Parameters:
command – An eksctl command
- Returns:
stdout of the eksctl command
- get_nodegroup_size(nodegroup_type='', nodegroup_name='')
- get_nodes(app='', nodegroup_type='', nodegroup_name='')
Get all nodes of a cluster. This overwrites the cluster method with the AWS specific nodegroup-name label.
- Parameters:
app – Name of the pod
nodegroup_type – Type of the nodegroup, e.g. sut
nodegroup_name – Name of the nodegroup, e.g. sut_high_memory
- scale_nodegroup(nodegroup_name, size)
- scale_nodegroups(nodegroup_names, size=None)
- wait_for_nodegroup(nodegroup_type='', nodegroup_name='', num_nodes_aux_planned=0)
- wait_for_nodegroups(nodegroup_names, size=None)
- class bexhoma.clusters.kubernetes(clusterconfig='cluster.config', experiments_configfolder='experiments/', yamlfolder='k8s/', context=None, code=None, instance=None, volume=None, docker=None, script=None, queryfile=None)
Bases:
testbed
- Date:
2022-10-01
- Version:
0.6.0
- Authors:
Patrick K. Erdelt
Class for containing specific Kubernetes (K8s) methods. This class can be overloaded to define specific implementations of Kubernetes, for example AWS.
Copyright (C) 2020 Patrick K. Erdelt
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- add_experiment(experiment)
Add an experiment to this cluster.
- Parameters:
experiment – Experiment object
- store_pod_log(pod_name, container='')
Store the log of a pod in a local file in the experiment result folder. Optionally the name of a container can be given (mandatory, if pod has multiple containers).
- Parameters:
pod_name – Name of the pod
container – Name of the container
- class bexhoma.clusters.testbed(clusterconfig='cluster.config', experiments_configfolder='experiments/', yamlfolder='k8s/', context=None, code=None, instance=None, volume=None, docker=None, script=None, queryfile=None)
Bases:
object
- Date:
2022-10-01
- Version:
0.6.0
- Authors:
Patrick K. Erdelt
Class to manage experiments in a Kubernetes cluster.
TODO:
Remove instance / volume references from IaaS
Documentation for purpose and position
Documentation for “copy log and init” mechanisms
Clearify if OLD_ can be reused
Copyright (C) 2020 Patrick K. Erdelt
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- OLD__getTimediff()
- OLD_continueBenchmarks(connection=None, query=None)
- OLD_getChildProcesses()
- OLD_runReporting()
- OLD_startPortforwarding(service='', app='', component='sut')
- OLD_stopPortforwarding()
- add_to_messagequeue(queue, data)
Add data to (Redis) message queue.
- Parameters:
queue – Name of the queue
data – Data to be added to queue
- check_DBMS_connection(ip, port)
Check if DBMS is open for connections. Tries to open a socket to ip:port. Returns True if this is possible.
- Parameters:
ip – IP of the host to connect to
port – Port of the server on the host to connect to
- Returns:
True, iff connecting is possible
- cluster_access()
provide access to an K8s cluster by initializing connection handlers.
- connect_dashboard()
Connects to the dashboard component. This means the output ports of the dashboard component are forwarded to localhost. Expect results be available under port 8050 (dashboard) and 8888 (Jupyter).
- connect_master(experiment='', configuration='')
Connects to the master node of a sut component. This means the output ports of the component are forwarded to localhost. Must be limited to a specific experiment or dbms configuration.
- Parameters:
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- copyInits()
- copyLog()
- create_dashboard_name(app='', component='dashboard')
Creates a suitable name for the dashboard component.
- Parameters:
app – app the dashboard belongs to
component – Component name, should be ‘dashboard’ typically
- dashboard_is_running()
Returns True, iff dashboard is running.
- Returns:
True, iff dashboard is running
- delay(sec)
Function for waiting some time and inform via output about this. Synonymous for wait()
- Parameters:
sec – Number of seconds to wait
- delete_deployment(deployment)
Delete a deployment given by name.
- Parameters:
deployment – Name of the deployment to be deleted.
- delete_job(jobname='', app='', component='', experiment='', configuration='', client='')
Delete a job given by name or matching a set of labels (component/ experiment/ configuration)
- Parameters:
jobname – Name of the job we want to delete
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
client – DEPRECATED?
- delete_job_pods(jobname='', app='', component='', experiment='', configuration='', client='')
Delete all pods of a job given by name or matching a set of labels (component/ experiment/ configuration)
- Parameters:
jobname – Name of the job we want to delete the pods of
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
client – DEPRECATED?
- delete_pod(name)
Delete a pod given by name
- Parameters:
name – name of the pod to be deleted
- delete_pvc(name)
Delete a persistent volume claim given by name
- Parameters:
name – name of the pvc to be deleted
- delete_service(name)
Delete a service given by name
- Parameters:
name – name of the service to be deleted
- delete_stateful_set(name)
Delete a stateful set given by name
- Parameters:
name – name of the stateful set to be deleted
- downloadLog()
- execute_command_in_pod(command, pod='', container='', params='')
Runs an shell command remotely inside a container of a pod.
- Parameters:
command – A shell command
pod – The name of the pod
container – The name of the container in the pod
params – Optional parameters, currently ignored
- Returns:
stdout of the shell command
- get_dashboard_pod_name(app='', component='dashboard')
Returns the name of the dashboard pod.
- Parameters:
app – app the dashboard belongs to
component – Component name, should be ‘dashboard’ typically
- Returns:
name of the dashboard pod
- get_deployments(app='', component='', experiment='', configuration='')
Return all deployments matching a set of labels (component/ experiment/ configuration)
- Parameters:
app – app the deployment belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- get_job_pods(app='', component='', experiment='', configuration='', client='')
Return all pods of a jobs matching a set of labels (component/ experiment/ configuration)
- Parameters:
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
client – DEPRECATED?
- get_job_status(jobname='', app='', component='', experiment='', configuration='', client='')
Return status of a jobs given by name or matching a set of labels (component/ experiment/ configuration)
- Parameters:
jobname – Name of the job we want to know the status of
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
client – DEPRECATED?
- get_jobs(app='', component='', experiment='', configuration='', client='')
Return all jobs matching a set of labels (component/ experiment/ configuration)
- Parameters:
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
client – DEPRECATED?
- get_nodes(app='', nodegroup_type='', nodegroup_name='')
Get all nodes of a cluster.
- Parameters:
app – Name of the pod
nodegroup_type – Type of the nodegroup, e.g. sut
nodegroup_name – Name of the nodegroup, e.g. sut_high_memory
- get_pod_status(pod, app='')
Return status of a pod given by name
- Parameters:
app – app the set belongs to
pod – Name of the pod the status of which should be returned
- get_pods(app='', component='', experiment='', configuration='', status='')
Return all pods matching a set of labels (component/ experiment/ configuration)
- Parameters:
app – app the pod belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
status – Status of the pod
- get_pods_labels(app='', component='', experiment='', configuration='')
Return all labels of pods matching a set of labels (component/ experiment/ configuration)
- Parameters:
app – app the set belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- get_ports_of_service(app='', component='', experiment='', configuration='')
Return all ports of a services matching a set of labels (component/ experiment/ configuration)
- Parameters:
app – app the service belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- get_pvc(app='', component='', experiment='', configuration='')
Return all persistent volume claims matching a set of labels (component/ experiment/ configuration)
- Parameters:
app – app the pvc belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- get_pvc_labels(app='', component='', experiment='', configuration='', pvc='')
Return all labels of persistent volume claims matching a set of labels (component/ experiment/ configuration) or name
- Parameters:
app – app the pvc belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
pvc – Name of the PVC
- get_pvc_specs(app='', component='', experiment='', configuration='', pvc='')
Return all specs of persistent volume claims matching a set of labels (component/ experiment/ configuration) or name
- Parameters:
app – app the pvc belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
pvc – Name of the PVC
- get_pvc_status(app='', component='', experiment='', configuration='', pvc='')
Return status of persistent volume claims matching a set of labels (component/ experiment/ configuration) or name
- Parameters:
app – app the pvc belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
pvc – Name of the PVC
- get_services(app='', component='', experiment='', configuration='')
Return all services matching a set of labels (component/ experiment/ configuration)
- Parameters:
app – app the service belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- get_stateful_sets(app='', component='', experiment='', configuration='')
Return all stateful sets matching a set of labels (component/ experiment/ configuration)
- Parameters:
app – app the set belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- kubectl(command)
Runs an kubectl command in the current context.
- Parameters:
command – An eksctl command
- Returns:
stdout of the kubectl command
- log_experiment(experiment)
Function to log current step of experiment. This is supposed to be written on disk for comprehension and repetition. This should be reworked and yield a YAML format for example. Moreover this should respect “new” workflows with detached parallel loaders for example.
- Parameters:
experiment – Dict that stores parameters of current experiment stept
- pod_log(pod, container='')
- restart_dashboard(app='', component='dashboard')
Stops the dashboard component and its service.
- Parameters:
app – app the dashboard belongs to
component – Component name, should be ‘dashboard’ typically
- set_code(code)
Sets the unique identifier of an experiment. Use case: We start a cluster (without experiment), then define an experiment, which creates an identifier. This identifier will be set in the cluster as the default experiment.
- Parameters:
code – Unique identifier of an experiment
- set_connectionmanagement(**kwargs)
Sets connection management data for the experiments. This is for the benchmarker component (dbmsbenchmarker). Can be overwritten by experiment and configuration.
- Parameters:
kwargs – Dict of meta data, example ‘timout’ => 60
- set_ddl_parameters(**kwargs)
Sets DDL parameters for the experiments. This substitutes placeholders in DDL script. Can be overwritten by experiment and configuration.
- Parameters:
kwargs – Dict of meta data, example ‘index’ => ‘btree’
- set_experiment(instance=None, volume=None, docker=None, script=None)
Sets a specific setting for an experiment. In particular this sets instance, volume and dbms (docker image) and name of a list of DDL scrips. This typically comes from a cluster.config.
- Parameters:
instances – Dict of instances (DEPRECATED, was for IaaS?)
volumes – Dict of volumes, that carry data
dockers – Dict of docker images and meta data about how to usw
script – Name of list of DDL scripts, that are run when start_loading() is called
- set_experiments(instances=None, volumes=None, dockers=None)
Assigns dicts containing information about instances, volumes and dbms (docker images). This typically comes from a cluster.config.
- Parameters:
instances – Dict of instances (DEPRECATED, was for IaaS?)
volumes – Dict of volumes, that carry data
dockers – Dict of docker images and meta data about how to usw
- set_experiments_configfolder(experiments_configfolder)
Sets the configuration folder for the experiments. Bexhoma expects subfolders for expeiment types, for example tpch. In there, bexhoma looks for query.config files (for dbmsbenchmarker) and subfolders containing the schema per dbms.
- Parameters:
experiments_configfolder – Relative path to an experiment folder
- set_queryfile(queryfile)
Sets the name of a query file of an experiment. This is for the benchmarker component (dbmsbenchmarker).
- Parameters:
code – Unique identifier of an experiment
- set_querymanagement(**kwargs)
Sets query management data for the experiments. This is for the benchmarker component (dbmsbenchmarker).
- Parameters:
kwargs – Dict of meta data, example ‘numRun’ => 3
- set_resources(**kwargs)
Sets resources for the experiments. This is for the SUT component. Can be overwritten by experiment and configuration.
- Parameters:
kwargs – Dict of meta data, example ‘requests’ => {‘cpu’ => 4}
- set_workload(**kwargs)
Sets mata data about the experiments for example name and description.
- Parameters:
kwargs – Dict of meta data, example ‘name’ => ‘TPC-H’
- start_dashboard(app='', component='dashboard')
Starts the dashboard component and its service, if there is no such pod. Manifest is expected in ‘deploymenttemplate-bexhoma-dashboard.yml’.
- Parameters:
app – app the dashboard belongs to
component – Component name, should be ‘dashboard’ typically
- start_messagequeue(app='', component='messagequeue')
Starts the message queue. Manifest is expected in ‘deploymenttemplate-bexhoma-messagequeue.yml’
- Parameters:
app – app the messagequeue belongs to
component – Component name, should be ‘messagequeue’ typically
- stop_benchmarker(experiment='', configuration='')
Stops all benchmarking components (jobs and their pods) in the cluster. Can be limited to a specific experiment or dbms configuration.
- Parameters:
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- stop_dashboard(app='', component='dashboard')
Stops the dashboard component and its service.
- Parameters:
app – app the dashboard belongs to
component – Component name, should be ‘dashboard’ typically
- stop_loading(experiment='', configuration='')
Stops all loading components (jobs and their pods) in the cluster. Can be limited to a specific experiment or dbms configuration.
- Parameters:
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- stop_maintaining(experiment='', configuration='')
Stops all maintaining components (jobs and their pods) in the cluster. Can be limited to a specific experiment or dbms configuration.
- Parameters:
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- stop_monitoring(app='', component='monitoring', experiment='', configuration='')
Stops all monitoring components (deployments and their pods) in the cluster and their service. Can be limited to a specific experiment or dbms configuration.
- Parameters:
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- stop_sut(app='', component='sut', experiment='', configuration='')
Stops all sut components (deployments and their pods, stateful sets and services) in the cluster. Can be limited to a specific experiment or dbms configuration.
- Parameters:
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- wait(sec)
Function for waiting some time and inform via output about this
- Parameters:
sec – Number of seconds to wait
bexhoma.configurations module
- Date:
2022-10-01
- Version:
0.6.0
- Authors:
Patrick K. Erdelt
Class for managing an DBMS configuation. This is plugged into an experiment object.
Copyright (C) 2020 Patrick K. Erdelt
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- class bexhoma.configurations.default(experiment, docker=None, configuration='', script=None, alias=None, num_experiment_to_apply=None, clients=[1], dialect='', worker=0, dockerimage='')
Bases:
object
- Date:
2022-10-01
- Version:
0.6.0
- Authors:
Patrick K. Erdelt
Class for managing an DBMS configuation. This is plugged into an experiment object.
- param experiment:
Unique identifier of the experiment
- param docker:
Name of the Docker image
- param configuration:
Name of the configuration
- param script:
Unique identifier of the experiment
- param alias:
Unique identifier of the experiment
Copyright (C) 2020 Patrick K. Erdelt
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- OLD_get_items(app='', component='', experiment='', configuration='')
- add_benchmark_list(list_clients)
Add a list of (number of) benchmarker instances, that are to benchmark the current SUT. Example: [1,2,1] means sequentially we will have 1, then 2 and then 1 benchmarker instances.
- Parameters:
list_clients – List of (number of) benchmarker instances
- attach_worker()
Attaches worker nodes to the master of the sut. This runs the dockertemplate[‘attachWorker’] command.
- check_DBMS_connection(ip, port)
Check if DBMS is open for connections. Tries to open a socket to ip:port. Returns True if this is possible.
- Parameters:
ip – IP of the host to connect to
port – Port of the server on the host to connect to
- Returns:
True, iff connecting is possible
- check_load_data()
Check if loading of the sut has finished. If yes, store timeLoadingStart, timeLoadingEnd, timeLoading as labels and in this object as attributes. If there is a loading job: check if all pods are completed. Copy the logs of the containers in the pods and remove the pods. If there is no loading job: Read the labels. If loaded is True, store the timings in this object as attributes.
- check_sut()
Check if the pod of the sut is running. If yes, store it’s name in self.pod_sut.
- client
If we have a sequence of benchmarkers, this tells at which position we are
- configuration
Name of the configuration, default: Name of the Docker image
- connection_parameter
Collect all parameters that might be interesting in evaluation of results
- copyLog()
- create_manifest_benchmarking(connection, app='', component='benchmarker', experiment='', configuration='', experimentRun='', client='1', parallelism=1, alias='', env={}, template='', num_pods=1)
Creates a job template for the benchmarker. This sets meta data in the template and ENV.
- Parameters:
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
client – Number of benchmarker if there is a sequence of benchmarkers
parallelism – Number of parallel pods in job
alias – Alias name of the dbms
env – Dict of environment variables
template – Template for the job manifest
- Returns:
Name of file in YAML format containing the benchmarker job
- create_manifest_job(app='', component='benchmarker', experiment='', configuration='', experimentRun='', client='1', parallelism=1, env={}, template='', nodegroup='', num_pods=1)
Creates a job and sets labels (component/ experiment/ configuration).
- Parameters:
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
experimentRun – Number of run of the configuration in this experiment
client – Number of client of the job for this experiment run
parallelism – Number of parallel pods in this job
env – Dict of environment variables for the job manifest
template – Template name of the job manifest
nodegroup – Nodegroup of the pods of the job
num_pods – Number of pods that run in total
- create_manifest_loading(app='', component='loading', experiment='', configuration='', parallelism=1, alias='', num_pods=1)
Creates a job template for loading. This sets meta data in the template and ENV.
- Parameters:
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
parallelism – Number of parallel pods in job
- Returns:
Name of file in YAML format containing the loading job
- create_manifest_maintaining(app='', component='maintaining', experiment='', configuration='', parallelism=1, alias='', num_pods=1)
Creates a job template for maintaining. This sets meta data in the template and ENV.
- Parameters:
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
parallelism – Number of parallel pods in job
- Returns:
Name of file in YAML format containing the maintaining job
- create_monitoring(app='', component='monitoring', experiment='', configuration='')
Generate a name for the monitoring component. Basically this is {app}-{component}-{configuration}-{experiment}-{client}
- Parameters:
app – app the component belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- delay(sec)
Function for waiting some time and inform via output about this. Synonymous for wait()
- Parameters:
sec – Number of seconds to wait
- docker
Name of the Docker image
- dockerimage
Name of the Docker image of the SUT
- dockertemplate
Template of the Docker information taken from cluster.config
- execute_command_in_pod_sut(command, pod='', container='dbms', params='')
Runs an shell command remotely inside a container of a pod. This defaults to the current sut’s pod and the container “dbms”
- Parameters:
command – A shell command
pod – The name of the pod - default current sut’s pod
container – The name of the container in the pod - default dbms
params – Optional parameters, currently ignored
- Returns:
stdout of the shell command
- experiment
Unique identifier of the experiment
- experiment_done
True, iff the SUT has performed the experiment completely
- generate_component_name(app='', component='', experiment='', configuration='', experimentRun='', client='')
Generate a name for the component. Basically this is {app}-{component}-{configuration}-{experiment}-{client}
- Parameters:
app – app the component belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
client – Number of the client, if it comes from a sequence of same components (in particular benchmarker)
- getTimediff()
- get_connection_config(connection, alias='', dialect='', serverip='localhost', monitoring_host='localhost')
Returns information about the sut’s host disk space. Basically this calls df / on the host.
- Returns:
Size of disk in Bytes
- get_host_all()
Calls all get_host_x() methods. Returns information about the sut’s host as a dict.
- Returns:
Dict of informations about the host
- get_host_cores()
Returns information about the sut’s host CPU’s cores. Basically this calls grep -c ^processor /proc/cpuinfo on the host.
- Returns:
CPU’s cores of the host
- get_host_cpu()
Returns information about the sut’s host CPU. Basically this calls more /proc/cpuinfo | grep ‘model name’ on the host.
- Returns:
CPU of the host
- get_host_cuda()
Returns information about the sut’s host CUDA version. Basically this calls nvidia-smi | grep ‘CUDA’ on the host.
- Returns:
CUDA version of the host
- get_host_diskspace_used()
Returns information about the sut’s host disk space. Basically this calls df / on the host.
- Returns:
Size of disk in Bytes
- get_host_diskspace_used_data()
Returns information about the sut’s host disk space used for the data (the database). Basically this calls du on the host directory that is mentioned in cluster.config as to store the database.
- Returns:
Size of disk used for database in Bytes
- get_host_gpu_ids()
Returns information about the sut’s host GPUs. Basically this calls nvidia-smi -L on the host and generates a list of UUIDs of the GPUs.
- Returns:
List of GPU UUIDs of the host
- get_host_gpus()
Returns information about the sut’s host GPUs. Basically this calls nvidia-smi -L on the host and aggregates result.
- Returns:
GPUs of the host
- get_host_memory()
Returns information about the sut’s host RAM. Basically this calls grep MemTotal /proc/meminfo on the host.
- Returns:
RAM of the host
- get_host_node()
Returns information about the sut’s host name. Basically this calls kubectl get pod to receive the information.
- Returns:
Node name of the host
- get_host_system()
Returns information about the sut’s host OS. Basically this calls uname -r on the host.
- Returns:
OS of the host
- get_instance_from_resources()
Generates an instance name out of the resource parameters that are set using set_resources(). Should be DEPRECATED and replaced by something better.
- Parameters:
app – app the component belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- load_data()
Start loading data into the sut. This runs load_data_asynch() as an asynchronous thread. At first prepare_init_dbms() is run.
- loading_after_time
Time as an integer when initial loading should start - to give the system time to start up completely
- loading_finished
Time as an integer when initial loading has finished
- loading_started
Time as an integer when initial loading has started
- maintaining_is_pending()
Returns True, iff maintaining is in pending state.
- Returns:
True, if maintaining is in pendig state
- maintaining_is_running()
Returns True, iff maintaining is running.
- Returns:
True, if dbms is running
- monitoring_is_pending()
Returns True, iff monitoring is in pending state.
- Returns:
True, if monitoring is in pendig state
- monitoring_is_running()
Returns True, iff monitoring is running.
- Returns:
True, if monitoring is running
- pod_sut
Name of the sut’s master pod
- prepare_init_dbms()
Prepares to load data into the dbms. This copies the DDL scripts to /tmp on the host of the sut. Optionally parameters in DDL script are replaced by ddl_parameters. The files are renamed filled_ then.
- reset_sut()
Forget that the SUT has been loaded and benchmarked.
- run_benchmarker_pod(connection=None, alias='', dialect='', query=None, app='', component='benchmarker', experiment='', configuration='', client='1', parallelism=1)
Runs the benchmarker job. Sets meta data in the connection.config. Copy query.config and connection.config to the first pod of the job (result folder mounted into every pod)
- Parameters:
connection – Name of configuration prolonged by number of runs of the sut (installations) and number of client in a sequence of
alias – An alias can be given if we want to anonymize the dbms
dialect – A name of a SQL dialect can be given
query – The benchmark can be fixed to a specific query
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
client – Number of benchmarker this is in a sequence of
parallelism – Number of parallel benchmarker pods we want to have
- set_connectionmanagement(**kwargs)
Sets connection management data for the experiment. This is for the benchmarker component (dbmsbenchmarker). Can be overwritten by configuration.
- Parameters:
kwargs – Dict of meta data, example ‘timout’ => 60
- set_ddl_parameters(**kwargs)
Sets DDL parameters for the experiments. This substitutes placeholders in DDL script. Can be overwritten by configuration.
- Parameters:
kwargs – Dict of meta data, example ‘index’ => ‘btree’
- set_eval_parameters(**kwargs)
Sets some arbitrary parameters that are supposed to be handed over to the benchmarker component. Can be set by experiment before creation of configuration.
- Parameters:
kwargs – Dict of meta data, example ‘type’ => ‘noindex’
- set_experiment(instance=None, volume=None, docker=None, script=None)
Read experiment details from cluster config
- set_loading(parallel, num_pods=None)
Sets job parameters for loading components: Number of parallel pods and optionally (if different) total number of pods. By default total number of pods is set to number of parallel pods. Can be set by experiment before creation of configuration.
- Parameters:
parallel – Number of parallel pods
num_pods – Optionally (if different) total number of pods
- set_loading_parameters(**kwargs)
Sets ENV for loading components. Can be set by experiment before creation of configuration.
- Parameters:
kwargs – Dict of meta data, example ‘PARALLEL’ => ‘64’
- set_maintaining(parallel, num_pods=None)
Sets job parameters for maintaining components: Number of parallel pods and optionally (if different) total number of pods. By default total number of pods is set to number of parallel pods. Can be set by experiment before creation of configuration.
- Parameters:
parallel – Number of parallel pods
num_pods – Optionally (if different) total number of pods
- set_maintaining_parameters(**kwargs)
Sets ENV for maintaining components. Can be set by experiment before creation of configuration.
- Parameters:
kwargs – Dict of meta data, example ‘PARALLEL’ => ‘64’
- set_nodes(**kwargs)
- set_resources(**kwargs)
Sets resources for the experiment. This is for the SUT component. Can be overwritten by experiment and configuration.
- Parameters:
kwargs – Dict of meta data, example ‘requests’ => {‘cpu’ => 4}
- set_storage(**kwargs)
Sets parameters for the storage that might be attached to components. This is in particular for the database of dbms under test. Example:
storageClassName = ‘ssd’, storageSize = ‘100Gi’, keep = False
Can be set by experiment before creation of configuration.
- Parameters:
kwargs – Dict of meta data, example ‘storageSize’ => ‘100Gi’
- start_loading(delay=0)
Starts data ingestion by calling scripts inside the sut (dbms) container.
- Parameters:
delay – Number of seconds to wait after calling scripts
- start_loading_pod(app='', component='loading', experiment='', configuration='', parallelism=1, num_pods=1)
Starts a job for parallel data ingestion.
- Parameters:
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
parallelism – Number of parallel pods in job
- start_maintaining(app='', component='maintaining', experiment='', configuration='', parallelism=1, num_pods=1)
Starts a maintaining job.
- Parameters:
app – app the component belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
parallelism – Number of parallel pods in job
- start_monitoring(app='', component='monitoring', experiment='', configuration='')
Starts a monitoring deployment.
- Parameters:
app – app the component belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- start_sut(app='', component='sut', experiment='', configuration='')
Start the system-under-test (dbms). This also controls optional worker and storage. Resources are set according to set_resources().
- Parameters:
app – app the component belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- stop_loading(app='', component='loading', experiment='', configuration='')
Stops a loading job and removes all its pods.
- Parameters:
app – app the component belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- stop_maintaining(app='', component='maintaining', experiment='', configuration='')
Stops a monitoring deployment and removes all its pods.
- Parameters:
app – app the component belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- stop_monitoring(app='', component='monitoring', experiment='', configuration='')
Stops a monitoring deployment and removes its service.
- Parameters:
app – app the component belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- stop_sut(app='', component='sut', experiment='', configuration='')
Stops a sut deployment and removes all its services and (optionally) stateful sets. It also stops and removes all related components (monitoring, maintaining, loading).
- Parameters:
app – app the component belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
- sut_is_pending()
Returns True, iff system-under-test (dbms) is in pending state.
- Returns:
True, if dbms is in pendig state
- sut_is_running()
Returns True, iff system-under-test (dbms) is running.
- Returns:
True, if dbms is running
- timeLoading
Time in seconds the system has taken for the initial loading of data
- use_storage()
Return True, iff storage for the database should be used. Otherwise database is inside ephemeral-storage.
- wait(sec, silent=False)
Function for waiting some time and inform via output about this
- Parameters:
sec – Number of seconds to wait
silent – True means we do not output anything about this waiting
- class bexhoma.configurations.hammerdb(experiment, docker=None, configuration='', script=None, alias=None, num_experiment_to_apply=None, clients=[1], dialect='', worker=0, dockerimage='')
Bases:
default
- Date:
2022-10-01
- Version:
0.6.0
- Authors:
Patrick K. Erdelt
Class for managing an DBMS configuation. This is plugged into an experiment object.
- param experiment:
Unique identifier of the experiment
- param docker:
Name of the Docker image
- param configuration:
Name of the configuration
- param script:
Unique identifier of the experiment
- param alias:
Unique identifier of the experiment
Copyright (C) 2020 Patrick K. Erdelt
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- create_manifest_benchmarking(connection, app='', component='benchmarker', experiment='', configuration='', experimentRun='', client='1', parallelism=1, alias='', num_pods=1)
Creates a job template for the benchmarker. This sets meta data in the template and ENV. This sets some settings specific to HammerDB.
- Parameters:
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
client – Number of benchmarker if there is a sequence of benchmarkers
parallelism – Number of parallel pods in job
alias – Alias name of the dbms
- Returns:
Name of file in YAML format containing the benchmarker job
- run_benchmarker_pod(connection=None, alias='', dialect='', query=None, app='', component='benchmarker', experiment='', configuration='', client='1', parallelism=1)
Runs the benchmarker job. Sets meta data in the connection.config. Copy query.config and connection.config to the first pod of the job (result folder mounted into every pod)
- Parameters:
connection – Name of configuration prolonged by number of runs of the sut (installations) and number of client in a sequence of
alias – An alias can be given if we want to anonymize the dbms
dialect – A name of a SQL dialect can be given
query – The benchmark can be fixed to a specific query
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
client – Number of benchmarker this is in a sequence of
parallelism – Number of parallel benchmarker pods we want to have
- bexhoma.configurations.load_data_asynch(app, component, experiment, configuration, pod_sut, scriptfolder, commands, loadData, path, volume, context)
- class bexhoma.configurations.ycsb(experiment, docker=None, configuration='', script=None, alias=None, num_experiment_to_apply=None, clients=[1], dialect='', worker=0, dockerimage='')
Bases:
default
- Date:
2022-10-01
- Version:
0.6.0
- Authors:
Patrick K. Erdelt
Class for managing an DBMS configuation. This is plugged into an experiment object.
- param experiment:
Unique identifier of the experiment
- param docker:
Name of the Docker image
- param configuration:
Name of the configuration
- param script:
Unique identifier of the experiment
- param alias:
Unique identifier of the experiment
Copyright (C) 2020 Patrick K. Erdelt
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- create_manifest_benchmarking(connection, app='', component='benchmarker', experiment='', configuration='', experimentRun='', client='1', parallelism=1, alias='', num_pods=1)
Creates a job template for the benchmarker. This sets meta data in the template and ENV. This sets some settings specific to YCSB.
- Parameters:
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
client – Number of benchmarker if there is a sequence of benchmarkers
parallelism – Number of parallel pods in job
alias – Alias name of the dbms
- Returns:
Name of file in YAML format containing the benchmarker job
- run_benchmarker_pod(connection=None, alias='', dialect='', query=None, app='', component='benchmarker', experiment='', configuration='', client='1', parallelism=1)
Runs the benchmarker job. Sets meta data in the connection.config. Copy query.config and connection.config to the first pod of the job (result folder mounted into every pod)
- Parameters:
connection – Name of configuration prolonged by number of runs of the sut (installations) and number of client in a sequence of
alias – An alias can be given if we want to anonymize the dbms
dialect – A name of a SQL dialect can be given
query – The benchmark can be fixed to a specific query
app – app the job belongs to
component – Component, for example sut or monitoring
experiment – Unique identifier of the experiment
configuration – Name of the dbms configuration
client – Number of benchmarker this is in a sequence of
parallelism – Number of parallel benchmarker pods we want to have
bexhoma.experiments module
- Date:
2022-10-01
- Version:
0.6.0
- Authors:
Patrick K. Erdelt
Classes for managing an experiment. This is plugged into a cluster object. It collects some configuation objects. Two examples are included, dealing with TPC-H and TPC-DS tests. Another example concerns TSBS experiment. Each experiment also should have an own folder having:
a query file
a subfolder for each dbms, that may run this experiment, including schema files
Copyright (C) 2020 Patrick K. Erdelt
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- class bexhoma.experiments.default(cluster, code=None, num_experiment_to_apply=1, timeout=7200, detached=True)
Bases:
object
Class for defining an experiment. Settings are set generally. This class should be overloaded to define specific experiments.
- add_benchmark_list(list_clients)
Add a list of (number of) benchmarker instances, that are to benchmark the current SUT. Example [1,2,1] means sequentially we will have 1, then 2 and then 1 benchmarker instances. This is applied to all dbms configurations of the experiment.
- Parameters:
list_clients – List of (number of) benchmarker instances
- add_configuration(configuration)
Adds a configuration object to the list of configurations of this experiment. When a new configuration object is instanciated, an experiment object has to be provided. This method is then called automatically.
- Parameters:
configuration – Configuration object
- benchmark_list(list_clients)
DEPRECATED? Is not used anymore. Runs a given list of benchmarker applied to all running SUTs of experiment.
- Parameters:
list_clients – List of (number of) benchmarker instances
- delay(sec)
Function for waiting some time and inform via output about this. Synonymous for wait()
- Parameters:
sec – Number of seconds to wait
- end_benchmarking(jobname)
Ends a benchmarker job. This is for storing or cleaning measures.
- Parameters:
jobname – Name of the job to clean
- end_loading(jobname)
Ends a loading job. This is for storing or cleaning measures.
- Parameters:
jobname – Name of the job to clean
- evaluate_results(pod_dashboard='')
Let the dashboard pod build the evaluations. This is specific to dbmsbenchmarker.
All local logs are copied to the pod.
Benchmarker in the dashboard pod is updated (dev channel)
All results of all DBMS are joined (merge.py of benchmarker) in dashboard pod
Evaluation cube is built (python benchmark.py read -e yes) in dashboard pod
- set_connectionmanagement(**kwargs)
Sets connection management data for the experiment. This is for the benchmarker component (dbmsbenchmarker). Can be overwritten by configuration.
- Parameters:
kwargs – Dict of meta data, example ‘timout’ => 60
- set_ddl_parameters(**kwargs)
Sets DDL parameters for the experiments. This substitutes placeholders in DDL script. Can be overwritten by configuration.
- Parameters:
kwargs – Dict of meta data, example ‘index’ => ‘btree’
- set_eval_parameters(**kwargs)
Sets some arbitrary parameters that are supposed to be handed over to the benchmarker component. Can be overwritten by configuration.
- Parameters:
kwargs – Dict of meta data, example ‘type’ => ‘noindex’
- set_experiment(instance=None, volume=None, docker=None, script=None)
Read experiment details from cluster config
- Parameters:
instance –
volume –
docker –
script –
- set_experiments_configfolder(experiments_configfolder)
Sets the configuration folder for the experiment. Bexhoma expects subfolders for expeiment types, for example tpch. In there, bexhoma looks for query.config files (for dbmsbenchmarker) and subfolders containing the schema per dbms.
- Parameters:
experiments_configfolder – Relative path to an experiment folder
- set_loading(parallel, num_pods=None)
Sets job parameters for loading components: Number of parallel pods and optionally (if different) total number of pods. By default total number of pods is set to number of parallel pods. Can be overwritten by configuration.
- Parameters:
parallel – Number of parallel pods
num_pods – Optionally (if different) total number of pods
- set_loading_parameters(**kwargs)
Sets ENV for loading components. Can be overwritten by configuration.
- Parameters:
kwargs – Dict of meta data, example ‘PARALLEL’ => ‘64’
- set_maintaining(parallel, num_pods=None)
Sets job parameters for maintaining components: Number of parallel pods and optionally (if different) total number of pods. By default total number of pods is set to number of parallel pods. Can be overwritten by configuration.
- Parameters:
parallel – Number of parallel pods
num_pods – Optionally (if different) total number of pods
- set_maintaining_parameters(**kwargs)
Sets ENV for maintaining components. Can be overwritten by configuration.
- Parameters:
kwargs – Dict of meta data, example ‘PARALLEL’ => ‘64’
- set_nodes(**kwargs)
- set_queryfile(queryfile)
Sets the name of a query file of the experiment. This is for the benchmarker component (dbmsbenchmarker).
- Parameters:
code – Unique identifier of an experiment
- set_querymanagement(**kwargs)
Sets query management data for the experiment. This is for the benchmarker component (dbmsbenchmarker).
- Parameters:
kwargs – Dict of meta data, example ‘numRun’ => 3
- set_querymanagement_monitoring(numRun=256, delay=10, datatransfer=False)
Sets some parameters that are supposed to be suitable for a monitoring test:
high number of runs
optional delay
optional data transfer
monitoring active
- Parameters:
numRun – Number of runs per query (this is for the benchmarker component)
delay – Number of seconds to wait between queries (this is for the benchmarker component)
datatransfer – If data should we retrieved and compared
- set_querymanagement_quicktest(numRun=1, datatransfer=False)
Sets some parameters that are supposed to be suitable for a quick functional test:
small number of runs
no delay
optional data transfer
no monitoring
- Parameters:
numRun – Number of runs per query (this is for the benchmarker component)
datatransfer – If data should we retrieved and compared
- set_resources(**kwargs)
Sets resources for the experiment. This is for the SUT component. Can be overwritten by experiment and configuration.
- Parameters:
kwargs – Dict of meta data, example ‘requests’ => {‘cpu’ => 4}
- set_storage(**kwargs)
Sets parameters for the storage that might be attached to components. This is in particular for the database of dbms under test. Example:
storageClassName = ‘ssd’, storageSize = ‘100Gi’, keep = False
Can be overwritten by configuration.
- Parameters:
kwargs – Dict of meta data, example ‘storageSize’ => ‘100Gi’
- set_workload(**kwargs)
Sets mata data about the experiment, for example name and description.
- Parameters:
kwargs – Dict of meta data, example ‘name’ => ‘TPC-H’
- start_loading()
Tells all dbms configurations of this experiment to start loading data.
- start_monitoring()
Start monitoring for all dbms configurations of this experiment.
- start_sut()
Start all dbms configurations of this experiment.
- stop_benchmarker(configuration='')
Stop all benchmarker jobs of this experiment. If a dbms configurations is given, use it. Otherwise tell the cluster to stop all benchmarker jobs belonging to this experiment code.
- stop_loading()
Stop all loading jobs of this experiment. If a list of dbms configurations is set, use it. Otherwise tell the cluster to stop all loading jobs belonging to this experiment code.
- stop_maintaining()
Stop all maintaining jobs of this experiment. If a list of dbms configurations is set, use it. Otherwise tell the cluster to stop all maintaining jobs belonging to this experiment code.
- stop_monitoring()
Stop all monitoring deployments of this experiment. If a list of dbms configurations is set, use it. Otherwise tell the cluster to stop all monitoring deployments belonging to this experiment code.
- stop_sut()
Stop all SUT deployments of this experiment. If a list of dbms configurations is set, use it. Otherwise tell the cluster to stop all monitoring deployments belonging to this experiment code.
- test_results()
Run test script in dashboard pod. Extract exit code.
- Returns:
exit code of test script
- wait(sec)
Function for waiting some time and inform via output about this
- Parameters:
sec – Number of seconds to wait
- work_benchmark_list(intervals=30, stop=True)
Run typical workflow:
start SUT
start monitoring
start loading (at first scripts (schema or loading via pull), then optionally parallel loading pods)
optionally start maintaining pods
at the same time as 4. run benchmarker jobs corresponding to list given via add_benchmark_list()
- Parameters:
intervals – Seconds to wait before checking change of status
stop – Tells if SUT should be removed when all benchmarking has finished. Set to False if we want to have loaded SUTs for inspection.
- zip()
Zip the result folder in the dashboard pod.
- class bexhoma.experiments.iot(cluster, code=None, queryfile='queries-iot.config', SF='1', num_experiment_to_apply=1, timeout=7200)
Bases:
default
Class for defining an TSBS experiment. This sets
the folder to the experiment - including query file and schema informations per dbms
name and information about the experiment
additional parameters - here SF (the scaling factor)
- set_queries_full()
- set_queries_profiling()
- set_querymanagement_maintaining(numRun=128, delay=5, datatransfer=False)
- class bexhoma.experiments.tpcc(cluster, code=None, SF='1', num_experiment_to_apply=1, timeout=7200)
Bases:
default
Class for defining an TPC-C experiment (in the HammerDB version). This sets
the folder to the experiment - including query file and schema informations per dbms
name and information about the experiment
additional parameters - here SF (the scaling factor), i.e. number of warehouses
- end_benchmarking(jobname)
Ends a benchmarker job. This is for storing or cleaning measures.
- Parameters:
jobname – Name of the job to clean
- test_results()
Run test script locally. Extract exit code.
- Returns:
exit code of test script
- class bexhoma.experiments.tpcds(cluster, code=None, queryfile='queries-tpcds.config', SF='100', num_experiment_to_apply=1, timeout=7200)
Bases:
default
Class for defining an TPC-DS experiment. This sets
the folder to the experiment - including query file and schema informations per dbms
name and information about the experiment
additional parameters - here SF (the scaling factor)
- set_queries_full()
- set_queries_profiling()
- class bexhoma.experiments.tpch(cluster, code=None, queryfile='queries-tpch.config', SF='100', num_experiment_to_apply=1, timeout=7200)
Bases:
default
Class for defining an TPC-H experiment. This sets
the folder to the experiment - including query file and schema informations per dbms
name and information about the experiment
additional parameters - here SF (the scaling factor)
- set_queries_full()
- set_queries_profiling()
- class bexhoma.experiments.tsbs(cluster, code=None, queryfile='queries-tsbs.config', SF='1', num_experiment_to_apply=1, timeout=7200)
Bases:
default
Class for defining an TSBS experiment. This sets
the folder to the experiment - including query file and schema informations per dbms
name and information about the experiment
additional parameters - here SF (the scaling factor)
- end_loading(jobname)
Ends a loading job. This is for storing or cleaning measures.
- Parameters:
jobname – Name of the job to clean
- set_queries_full()
- set_queries_profiling()
- set_querymanagement_maintaining(numRun=128, delay=5, datatransfer=False)
- class bexhoma.experiments.ycsb(cluster, code=None, SF='1', num_experiment_to_apply=1, timeout=7200)
Bases:
default
Class for defining an YCSB experiment. This sets
the folder to the experiment - including query file and schema informations per dbms
name and information about the experiment
additional parameters - here SF (the scaling factor), i.e. number of rows divided by 10.000
- end_benchmarking(jobname)
Ends a benchmarker job. This is for storing or cleaning measures.
- Parameters:
jobname – Name of the job to clean
- end_loading(jobname)
Ends a loading job. This is for storing or cleaning measures.
- Parameters:
jobname – Name of the job to clean
- log_to_df(filename)
- test_results()
Run test script locally. Extract exit code.
- Returns:
exit code of test script
Module contents
The clustermanager module
Benchmark Experiment Host Manager (Bexhoma)
This Python tools helps managing benchmark experiments of Database Management Systems (DBMS) in a Kubernetes-based High-Performance-Computing (HPC) cluster environment. It enables users to configure hardware / software setups for easily repeating tests over varying configurations.
It serves as the orchestrator [2] for distributed parallel benchmarking experiments in a Kubernetes Cloud. This has been tested at Amazon Web Services, Google Cloud, Microsoft Azure, IBM Cloud, Oracle Cloud, and at Minikube installations, running with Clickhouse, Exasol, Citus Data (Hyperscale), IBM DB2, MariaDB, MariaDB Columnstore, MemSQL (SingleStore), MonetDB, MySQL, OmniSci (HEAVY.AI), Oracle DB, PostgreSQL, SQL Server, SAP HANA, TimescaleDB, and Vertica. .
The basic workflow is [1,2]: start a virtual machine, install monitoring software and a database management system, import data, run benchmarks (external tool) and shut down everything with a single command. A more advanced workflow is: Plan a sequence of such experiments, run plan as a batch and join results for comparison.
See the homepage and the documentation.
If you encounter any issues, please report them to our Github issue tracker.
Installation
Download the repository: https://github.com/Beuth-Erdelt/Benchmark-Experiment-Host-Manager
Install the package
pip install bexhoma
Make sure you have a working
kubectl
installed
(Also make sure to have access to a running Kubernetes cluster - for example Minikube)Adjust configuration
Rename
k8s-cluster.config
tocluster.config
Set name of context, namespace and name of cluster in that file
Install data [tbd in detail]
Example for TPC-H SF=1:Run
kubectl create -f k8s/job-data-tpch-1.yml
When job is done, clean up with
kubectl delete job -l app=bexhoma -l component=data-source
and
kubectl delete deployment -l app=bexhoma -l component=data-source
.
Install result folder
Runkubectl create -f k8s/pvc-bexhoma-results.yml
Quickstart
The repository contains a tool for running TPC-H (reading) queries at MonetDB and PostgreSQL.
Run
tpch run -sf 1 -t 30
.You can watch status using
bexperiments status
while running.
This is equivalent topython cluster.py status
.After benchmarking has finished, run
bexperiments dashboard
to connect to a dashboard. You can open dashboard in browser athttp://localhost:8050
.
This is equivalent topython cluster.py dashboard
Alternatively you can open a Jupyter notebook athttp://localhost:8888
.
More Informations
For full power, use this tool as an orchestrator as in [2]. It also starts a monitoring container using Prometheus and a metrics collector container using cAdvisor. It also uses the Python package dbmsbenchmarker, [3], as query executor and evaluator as in [1,2]. See the images folder for more details.
Contributing, Bug Reports
If you have any question or found a bug, please report them to our Github issue tracker. In any bug report, please let us know:
Which operating system and hardware (32 bit or 64 bit) you are using
Python version
Bexhoma version (or git commit/date)
Traceback that occurs (the full error message)
We are always looking for people interested in helping with code development, documentation writing, technical administration, and whatever else comes up. If you wish to contribute, please first read the contribution section or visit the documentation.
References
If you use Bexhoma in work contributing to a scientific publication, we kindly ask that you cite our application note [2] or [1]:
Erdelt P.K. (2021) A Framework for Supporting Repetition and Evaluation in the Process of Cloud-Based DBMS Performance Benchmarking. In: Nambiar R., Poess M. (eds) Performance Evaluation and Benchmarking. TPCTC 2020. Lecture Notes in Computer Science, vol 12752. Springer, Cham. https://doi.org/10.1007/978-3-030-84924-5_6
[2] Orchestrating DBMS Benchmarking in the Cloud with Kubernetes
Erdelt P.K. (2022) Orchestrating DBMS Benchmarking in the Cloud with Kubernetes. In: Nambiar R., Poess M. (eds) Performance Evaluation and Benchmarking. TPCTC 2021. Lecture Notes in Computer Science, vol 13169. Springer, Cham. https://doi.org/10.1007/978-3-030-94437-7_6
[3] DBMS-Benchmarker: Benchmark and Evaluate DBMS in Python
Erdelt P.K., Jestel J. (2022). DBMS-Benchmarker: Benchmark and Evaluate DBMS in Python. Journal of Open Source Software, 7(79), 4628 https://doi.org/10.21105/joss.04628