Load Generator Framework
Theodolite’s benchmarks come with a flexible load generator framework. It is used to create load on the 4 Theodolite benchmarks, but can also be applied to create custom load generators. It is particularly designed for scalability: Just spin up multiple instances of the load generator and the instances automatically divide the load to be generated among themselves.
Prebuilt container images
For each benchmark, we provide a load generator as OCI container image. These load generators simulate smart power meters in an industrial facility, which generate measurement records at a fixed rate. Records are published to an Apache Kafka topic (default) or sent as POST requests to an HTTP endpoint.
You can simply run a load generator container, for example, for benchmark UC1 with:
docker run -it ghcr.io/cau-se/theodolite-uc1-workload-generator
Message format
Messages generated by the load generators represent a single measurement of active power. The corresponding message type is specified as ActivePowerRecords
defined with Avro. It consists of an identifier for simulated power sensor, a timestamp in epoch milliseconds and the actual measured (simulated) value in watts.
When sending generated records via Apache Kafka, these records are serialized with the Confluent Schema Registry. If the load generator is configured to send records as HTTP POST requests, records are serialized as JSON according to the following format:
{
"identifier": "sensor-id",
"timestamp": 1645564942000,
"valueInW": 1234.56
}
Configuration
The prebuilt container images can be configured with the following environment variables:
Environment Variable | Description | Default |
---|---|---|
BOOTSTRAP_SERVER |
Address (hostname:port ) of another load generator instance to form a cluster with. Can also be this instance. |
localhost:5701 |
KUBERNETES_DNS_NAME |
Kubernetes service name to discover other load generators to form a cluster with. Must be a fully qualified domain name (FQDN), e.g., something like <service>.<namespace>.svc.cluster.local . Requires BOOTSTRAP_SERVER not to be set. |
|
PORT |
Port used for for coordination among load generator instances. | 5701 |
PORT_AUTO_INCREMENT |
If set to true and the specified PORT is already used, use the next higher one. Useful if multiple instances should run on the same host, without configuring each instance individually. | true |
CLUSTER_NAME_PREFIX |
Only required if unrelated load generators form a cluster. | theodolite-load-generation |
TARGET |
The target system the load generator send messages to. Valid values are: kafka , http and pubsub . |
kafka |
KAFKA_BOOTSTRAP_SERVERS |
A list of host/port pairs to use for establishing the initial connection to the Kafka cluster. See Kafka producer config: bootstrap.servers for more information. Only used if Kafka is set as TARGET . |
localhost:9092 |
KAFKA_INPUT_TOPIC |
Name of the Kafka topic, which should receive the generated messages. Only used if Kafka is set as TARGET . |
input |
SCHEMA_REGISTRY_URL |
URL of the Confluent Schema Registry. | http://localhost:8081 |
KAFKA_BATCH_SIZE |
Value for the Kafka producer configuration: batch.size . Only used if Kafka is set as TARGET . |
see Kafka producer config: batch.size |
KAFKA_LINGER_MS |
Value for the Kafka producer configuration: linger.ms . Only used if Kafka is set as TARGET . |
see Kafka producer config: linger.ms |
KAFKA_BUFFER_MEMORY |
Value for the Kafka producer configuration: buffer.memory Only used if Kafka is set as TARGET . |
see Kafka producer config: buffer.memory |
HTTP_URL |
The URL the load generator should post messages to. Only used if HTTP is set as TARGET . |
|
HTTP_ASYNC |
Whether the load generator should send HTTP messages asynchronously. Only used if HTTP is set as TARGET . |
false |
HTTP_TIMEOUT_MS |
Timeout in milliseconds for sending HTTP messages. Only used if HTTP is set as TARGET . |
1000 |
PUBSUB_INPUT_TOPIC |
The Google Cloud Pub/Sub topic to write messages to. Only used if Pub/Sub is set as TARGET . |
input |
PUBSUB_PROJECT |
The Google Cloud this Pub/Sub topic is associated with. Only used if Pub/Sub is set as TARGET . |
|
PUBSUB_EMULATOR_HOST |
A Pub/Sub emulator host. Only used if Pub/Sub is set as TARGET . |
|
NUM_SENSORS |
The amount of simulated sensors. | 10 |
PERIOD_MS |
The time in milliseconds between generating two messages for the same sensor. With our Theodolite benchmarks, we apply an open workload model in which new messages are generated at a fixed rate, without considering the think time of the target server nor the time required for generating a message. | 1000 |
VALUE |
The constant valueInW of an ActivePowerRecord . |
10 |
THREADS |
Number of worker threads used to generate the load. | 4 |
DISABLE_DNS_CACHING |
Set to true to disable DNS caching by the underlying JVM. You might want to do so when generating load via HTTP that should be sent to different target instances. |
false |
Please note that there are some additional configuration options for benchmark UC4’s load generator.
Creating a custom load generator
To create a custom load generator, you need to import the load-generator-commons project. You can then create an instance of the LoadGenerator
populated with a default configuration, adjust it as desired, and start it by calling its run
method:
LoadGenerator loadGenerator = new LoadGenerator.fromDefaults()
.setClusterConfig(clusterConfig)
.setLoadDefinition(new WorkloadDefinition(
new KeySpace(key_prefix, numSensors),
duration))
.setGeneratorConfig(new LoadGeneratorConfig(
recordGenerator,
recordSender))
.withThreads(threads);
loadGenerator.run();
Alternatively, you can also start with a LoadGenerator
created from environment variables and, optionally, adjust it as desired:
LoadGenerator loadGenerator = LoadGenerator.fromEnvironment();