Skip to content

Commit 04179f6

Browse files
Introduced hardware test workload
1 parent d0bf49b commit 04179f6

File tree

12 files changed

+1530
-368
lines changed

12 files changed

+1530
-368
lines changed

README.md

Lines changed: 219 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,24 +94,36 @@ make build
9494
# bin/plgm-darwin-arm64.tar.gz
9595
```
9696

97-
98-
### Usage
97+
#### Usage
9998

10099
To view the full usage guide, including available flags and environment variables, run the help command:
101100

102101
```bash
103-
bin/plgm --help
102+
./plgm --help
103+
104104
plgm: Percona Load Generator for MongoDB Clusters
105-
Usage: ./bin/plgm [flags] [config_file]
105+
Usage: ./plgm [flags] [config_file]
106106

107107
Examples:
108-
./bin/plgm # Run with default 'config.yaml'
109-
./bin/plgm my_test.yaml # Run with specific config file
110-
./bin/plgm --help # Show this help message
108+
./plgm # Run with default 'config.yaml'
109+
./plgm my_test.yaml # Run with specific config file
110+
./plgm --help # Show this help message
111111

112112
Flags:
113113
-config string
114114
Path to the configuration file (default "config.yaml")
115+
-raw-injector
116+
Enable Raw BSON Injector (High Performance Mode)
117+
-raw-injector-batch int
118+
Bulk batch size (ops per network round trip) (default 1000)
119+
-raw-injector-drop
120+
Drop the collection before starting
121+
-raw-injector-max-docs int
122+
Maximum number of documents to operate on (default 10000000)
123+
-raw-injector-size int
124+
Document size in bytes (default 1024)
125+
-raw-injector-type string
126+
Operation: insert, upsert, update, delete, find, mixed (default "insert")
115127
-version
116128
Print version information and exit
117129

@@ -135,9 +147,20 @@ Environment Variables (Overrides):
135147
PLGM_SKIP_SEED Do not seed initial data on start (true/false)
136148
PLGM_SEED_BATCH_SIZE Number of documents to insert per batch during SEED phase
137149
PLGM_DEBUG_MODE Enable verbose logic logs (true/false)
150+
PLGM_PPROF_ENABLED Enable pprof server on localhost:6060 (true/false)
138151
PLGM_USE_TRANSACTIONS Enable transactional workloads (true/false)
139152
PLGM_MAX_TRANSACTION_OPS Maximum number of operations to group into a single transaction block
140153

154+
[Raw Injector Mode] (High Performance Hardware Test)
155+
PLGM_INJECTOR Enable Raw Injector mode (true/false)
156+
PLGM_INJECTOR_TYPE Operation: insert, upsert, update, delete, find, mixed
157+
PLGM_INJECTOR_SIZE Document size in bytes
158+
PLGM_INJECTOR_BATCH_SIZE Operations per network batch (default: 1000)
159+
PLGM_INJECTOR_MAX_DOCS Total documents to operate on (default: 10M)
160+
PLGM_INJECTOR_DROP Drop collection on start (true/false)
161+
PLGM_INJECTOR_DB Database name
162+
PLGM_INJECTOR_COLLECTION Collection name
163+
141164
[Operation Ratios] (Must sum to ~100)
142165
PLGM_FIND_PERCENT % of ops that are FIND
143166
PLGM_UPDATE_PERCENT % of ops that are UPDATE
@@ -159,7 +182,7 @@ Environment Variables (Overrides):
159182
GOMAXPROCS Go Runtime CPU limit
160183
```
161184

162-
### 2. Run Default Workload
185+
### 2. Default Workload
163186
plgm comes with a built-in default workload useful for immediate testing and get you started right away.
164187
```bash
165188
# Edit config.yaml to set your URI, then run:
@@ -176,7 +199,189 @@ If you wish to use a different default workload, you can replace these two files
176199
./bin/plgm /path/to/some/custom_config.yaml
177200
```
178201

179-
### 3. Additional Workloads
202+
### 3. Raw Injector Mode (High Performance Hardware Test) Workload
203+
204+
The **Raw Injector** is a specialized, ultra-high-performance engine built directly into `PLGM`. Instead of using the standard MongoDB driver structs (which consume CPU and memory for BSON marshaling), the Raw Injector pre-compiles raw BSON byte arrays and performs zero-allocation bitwise mutations in a tight loop.
205+
206+
This mode is designed exclusively to **stress-test network throughput, disk I/O, and extreme CPU limits** of the MongoDB cluster. It can saturate high-end infrastructure significantly faster than standard workloads. This functionality was developed to mimic other benchmarking tools, enabling an apples-to-apples comparison between PLGM and alternative solutions.
207+
208+
Unlike the other workloads PLGM supports, this mode is not configurable. It was intentionally built solely for stress testing purposes and is not intended to function as a workload simulator, but instead, a simple benchmark stress test.
209+
210+
***Important Note on Ops/Sec: In Raw Injector mode, the printed Ops/Sec refers to the number of documents processed, not the number of network commands. For example, if your batch size is 1,000, and plgm reports 50,000 Ops/Sec, it is executing 50 bulk network commands per second.***
211+
212+
#### Configuration
213+
214+
You can configure the Raw Injector via `config.yaml` or directly via CLI flags/environment variables. These are the available options:
215+
216+
```yaml
217+
# config.yaml snippet
218+
raw_injector:
219+
enabled: true
220+
drop_collection: true
221+
type: "mixed" # Options: insert, upsert, find, update, delete, mixed
222+
document_size: 1024 # Size of the random binary payload in bytes
223+
max_docs: 10000000 # Total documents to generate/query
224+
batch_size: 1000 # Number of operations packed into a single network round-trip
225+
db_name: "plgm_injector"
226+
collection_name: "injector_data"
227+
```
228+
229+
Environment variables:
230+
231+
```bash
232+
PLGM_INJECTOR Enable Raw Injector mode (true/false)
233+
PLGM_INJECTOR_TYPE Operation: insert, upsert, update, delete, find, mixed
234+
PLGM_INJECTOR_SIZE Document size in bytes
235+
PLGM_INJECTOR_BATCH_SIZE Operations per network batch (default: 1000)
236+
PLGM_INJECTOR_MAX_DOCS Total documents to operate on (default: 10M)
237+
PLGM_INJECTOR_DROP Drop collection on start (true/false)
238+
PLGM_INJECTOR_DB Database name
239+
PLGM_INJECTOR_COLLECTION Collection name
240+
```
241+
242+
#### Modes of Operation (type)
243+
244+
* insert: Floods the database with new documents. Automatically pre-splits chunks if sharding is enabled.
245+
* find / update / delete: Operates on the existing data seeded by an insert run.
246+
* upsert: Fires upsert commands, creating documents if they don't exist.
247+
* mixed: Runs a randomized distribution of reads, inserts, updates, and deletes simultaneously.
248+
249+
250+
#### Running via CLI
251+
You can bypass the YAML config entirely and trigger a raw injection test purely through flags:
252+
253+
##### Run a pure insert flood, dropping existing data, with 4KB documents
254+
255+
```bash
256+
./plgm -raw-injector -raw-injector-type=insert -raw-injector-drop -raw-injector-size=4096 -raw-injector-batch=2000
257+
```
258+
259+
##### Run a mixed workload against the generated data
260+
261+
```bash
262+
./plgm -raw-injector -raw-injector-type=mixed
263+
```
264+
265+
<details>
266+
<summary>Sample output:</summary>
267+
268+
```bash
269+
./plgm -raw-injector -raw-injector-type=insert -raw-injector-drop -raw-injector-size=4096 -raw-injector-batch=2000
270+
[INFO] Performance: Automatically disabled driver compression (compressors=none)
271+
Enter Password for user 'root':
272+
2026/02/23 11:26:45 [RawInjector] Dropping collection 'injector_data'...
273+
2026/02/23 11:26:47 [RawInjector] Range sharding enabled on { _id: 1 }
274+
2026/02/23 11:26:47 [RawInjector] Pre-splitting: 4 workers -> 2 shards
275+
2026/02/23 11:26:48 >>> RAW INJECTOR START [mixed] workers=4 batch=2000 maxDocs=10000000 docSize=4096 <<<
276+
277+
> Starting Workload...
278+
279+
TIME | TOTAL OPS | SELECT | INSERT | UPSERT | UPDATE | DELETE | AGG | TRANS
280+
-----------------------------------------------------------------------------------------
281+
00:01 | 76,000 | 48,000 | 10,000 | 0 | 18,000 | 0 | 0 | 0
282+
00:02 | 160,000 | 108,000 | 10,000 | 0 | 30,000 | 12,000 | 0 | 0
283+
00:03 | 140,000 | 90,000 | 18,000 | 0 | 20,000 | 12,000 | 0 | 0
284+
00:04 | 142,000 | 78,000 | 8,000 | 0 | 38,000 | 18,000 | 0 | 0
285+
00:05 | 160,000 | 112,000 | 12,000 | 0 | 28,000 | 8,000 | 0 | 0
286+
00:06 | 140,000 | 78,000 | 12,000 | 0 | 34,000 | 16,000 | 0 | 0
287+
00:07 | 138,000 | 72,000 | 4,000 | 0 | 40,000 | 22,000 | 0 | 0
288+
00:08 | 156,000 | 98,000 | 4,000 | 0 | 44,000 | 10,000 | 0 | 0
289+
00:09 | 144,000 | 84,000 | 6,000 | 0 | 38,000 | 16,000 | 0 | 0
290+
00:10 | 180,000 | 126,000 | 4,000 | 0 | 34,000 | 16,000 | 0 | 0
291+
292+
> Workload Finished.
293+
294+
SUMMARY
295+
--------------------------------------------------
296+
Runtime: 10.00s
297+
Total Ops: 1,444,000
298+
Avg Rate: 144,400 ops/sec
299+
300+
LATENCY DISTRIBUTION (ms)
301+
--------------------------------------------------
302+
TYPE AVG MIN MAX P95 P99
303+
SELECT 0.01 ms 0.01 ms 0.03 ms 0.00 ms 0.00 ms
304+
INSERT 0.07 ms 0.04 ms 0.15 ms 0.00 ms 0.00 ms
305+
UPSERT - - - - -
306+
UPDATE 0.04 ms 0.04 ms 0.07 ms 0.00 ms 0.00 ms
307+
DELETE 0.04 ms 0.03 ms 0.06 ms 0.00 ms 0.00 ms
308+
AGG - - - - -
309+
TRANS - - - - -
310+
```
311+
</details>
312+
313+
##### Run the workload configuring it via any of the available environment variables
314+
315+
<details>
316+
<summary>Sample output:</summary>
317+
318+
```bash
319+
export PLGM_PASSWORD=super_duper_password_here
320+
PLGM_INJECTOR=true PLGM_INJECTOR_TYPE=mixed PLGM_DURATION=30s ./plgm
321+
[INFO] Performance: Automatically disabled driver compression (compressors=none)
322+
2026/02/23 11:48:26 [RawInjector] Range sharding enabled on { _id: 1 }
323+
2026/02/23 11:48:26 [RawInjector] Pre-splitting: 4 workers -> 2 shards
324+
2026/02/23 11:48:27 [RawInjector] Checking for existing data to resume sequences...
325+
2026/02/23 11:48:27 >>> RAW INJECTOR START [mixed] workers=4 batch=1000 maxDocs=10000000 docSize=200 <<<
326+
327+
> Starting Workload...
328+
329+
TIME | TOTAL OPS | SELECT | INSERT | UPSERT | UPDATE | DELETE | AGG | TRANS
330+
-----------------------------------------------------------------------------------------
331+
00:01 | 65,000 | 41,000 | 4,000 | 0 | 11,000 | 9,000 | 0 | 0
332+
00:02 | 79,000 | 53,000 | 3,000 | 0 | 14,000 | 9,000 | 0 | 0
333+
00:03 | 85,000 | 52,000 | 4,000 | 0 | 18,000 | 11,000 | 0 | 0
334+
00:04 | 77,000 | 44,000 | 3,000 | 0 | 21,000 | 9,000 | 0 | 0
335+
00:05 | 93,000 | 53,000 | 9,000 | 0 | 16,000 | 15,000 | 0 | 0
336+
00:06 | 98,000 | 63,000 | 4,000 | 0 | 24,000 | 7,000 | 0 | 0
337+
00:07 | 99,000 | 70,000 | 1,000 | 0 | 17,000 | 11,000 | 0 | 0
338+
00:08 | 93,000 | 54,000 | 4,000 | 0 | 26,000 | 9,000 | 0 | 0
339+
00:09 | 121,000 | 84,000 | 8,000 | 0 | 18,000 | 11,000 | 0 | 0
340+
00:10 | 96,000 | 55,000 | 6,000 | 0 | 29,000 | 6,000 | 0 | 0
341+
00:11 | 113,000 | 73,000 | 7,000 | 0 | 23,000 | 10,000 | 0 | 0
342+
00:12 | 102,000 | 67,000 | 4,000 | 0 | 18,000 | 13,000 | 0 | 0
343+
00:13 | 124,000 | 87,000 | 7,000 | 0 | 26,000 | 4,000 | 0 | 0
344+
00:14 | 114,000 | 73,000 | 6,000 | 0 | 27,000 | 8,000 | 0 | 0
345+
00:15 | 117,000 | 73,000 | 12,000 | 0 | 20,000 | 12,000 | 0 | 0
346+
00:16 | 109,000 | 67,000 | 5,000 | 0 | 31,000 | 6,000 | 0 | 0
347+
00:17 | 127,000 | 89,000 | 9,000 | 0 | 15,000 | 14,000 | 0 | 0
348+
00:18 | 121,000 | 86,000 | 2,000 | 0 | 19,000 | 14,000 | 0 | 0
349+
00:19 | 116,000 | 78,000 | 4,000 | 0 | 16,000 | 18,000 | 0 | 0
350+
00:20 | 105,000 | 71,000 | 5,000 | 0 | 18,000 | 11,000 | 0 | 0
351+
00:21 | 129,000 | 91,000 | 9,000 | 0 | 24,000 | 5,000 | 0 | 0
352+
00:22 | 121,000 | 83,000 | 3,000 | 0 | 27,000 | 8,000 | 0 | 0
353+
00:23 | 130,000 | 94,000 | 4,000 | 0 | 22,000 | 10,000 | 0 | 0
354+
00:24 | 118,000 | 82,000 | 6,000 | 0 | 18,000 | 12,000 | 0 | 0
355+
00:25 | 111,000 | 71,000 | 7,000 | 0 | 21,000 | 12,000 | 0 | 0
356+
00:26 | 109,000 | 74,000 | 5,000 | 0 | 20,000 | 10,000 | 0 | 0
357+
00:27 | 117,000 | 77,000 | 3,000 | 0 | 25,000 | 12,000 | 0 | 0
358+
00:28 | 111,000 | 72,000 | 5,000 | 0 | 28,000 | 6,000 | 0 | 0
359+
00:29 | 118,000 | 76,000 | 6,000 | 0 | 27,000 | 9,000 | 0 | 0
360+
00:30 | 111,000 | 67,000 | 6,000 | 0 | 25,000 | 13,000 | 0 | 0
361+
362+
> Workload Finished.
363+
364+
SUMMARY
365+
--------------------------------------------------
366+
Runtime: 30.00s
367+
Total Ops: 3,233,000
368+
Avg Rate: 107,766 ops/sec
369+
370+
LATENCY DISTRIBUTION (ms)
371+
--------------------------------------------------
372+
TYPE AVG MIN MAX P95 P99
373+
SELECT 0.02 ms 0.01 ms 0.06 ms 0.00 ms 0.00 ms
374+
INSERT 0.02 ms 0.01 ms 0.05 ms 0.00 ms 0.00 ms
375+
UPSERT - - - - -
376+
UPDATE 0.07 ms 0.04 ms 0.23 ms 0.00 ms 0.00 ms
377+
DELETE 0.09 ms 0.05 ms 0.17 ms 0.00 ms 0.00 ms
378+
AGG - - - - -
379+
TRANS - - - - -
380+
```
381+
382+
</details>
383+
384+
### 4. Additional Workloads
180385
181386
You will find additional workloads that you can use as references to benchmark your environment in cases where you prefer not to provide your own collection definitions and queries. However, if your goal is to test your application accurately, we strongly recommend creating collection definitions and queries that match those used by your application.
182387
@@ -186,7 +391,7 @@ The additional collection and query definitions can be found here:
186391
* [queries](./resources/queries/)
187392
188393
189-
### 4. Workload Configuration & Loading
394+
### 5. Workload Configuration & Loading
190395
191396
You can supply your own collections and queries using the `PLGM_COLLECTIONS_PATH` and `PLGM_QUERIES_PATH` environment variables (or the corresponding config file fields).
192397
@@ -215,7 +420,9 @@ When using **Directory Mode**, the behavior depends on the `PLGM_DEFAULT_WORKLOA
215420
* **`false` (Custom):** Loads all JSON files **except** `default.json`.
216421
* *Use Case:* Set this to `false` to run your custom workload files while keeping `default.json` in the folder for reference (it will be ignored).
217422
218-
### 5. Kubernetes & Docker
423+
---
424+
425+
## Kubernetes & Docker
219426
Prefer running in a container? We have a dedicated guide for building Docker images and running performance jobs directly inside Kubernetes (recommended for accurate network latency testing).
220427
221428
[View the Docker & Kubernetes Guide](k8s_and_docker.md)
@@ -249,6 +456,7 @@ You can override any setting in `config.yaml` using environment variables. This
249456
| `skip_seed` | `PLGM_SKIP_SEED` | Do not seed initial data on start (`true`/`false`) | `true` |
250457
| `seed_batch_size` | `PLGM_SEED_BATCH_SIZE` | Number of documents to insert per batch during SEED phase | `1000` |
251458
| `debug_mode` | `PLGM_DEBUG_MODE` | Enable verbose debug logging (`true`/`false`) | `false` |
459+
| `pprof_enabled` | `PLGM_PPROF_ENABLED` | Enable pprof server on localhost:6060 (`true`/`false`) | `false` |
252460
| `use_transactions` | `PLGM_USE_TRANSACTIONS` | Enable Transactional Workloads (`true`/`false`) | `false` |
253461
| `max_transaction_ops` | `PLGM_MAX_TRANSACTION_OPS` | Maximum number of operations to group into a single transaction block | `5` |
254462
| **Operation Ratios** | | (Must sum to ~100) | |

0 commit comments

Comments
 (0)