Skip to content

Commit 0ebaf2a

Browse files
max number of ops per transaction is now configurable
1 parent 6fd6fb8 commit 0ebaf2a

File tree

5 files changed

+77
-6
lines changed

5 files changed

+77
-6
lines changed

README.md

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ To view the full usage guide, including available flags and environment variable
7575
```bash
7676
bin/plgm --help
7777
plgm: Percona Load Generator for MongoDB Clusters
78-
Usage: bin/plgm [flags] [config_file]
78+
Usage: ./bin/plgm [flags] [config_file]
7979

8080
Examples:
81-
bin/plgm # Run with default 'config.yaml'
82-
bin/plgm my_test.yaml # Run with specific config file
83-
bin/plgm --help # Show this help message
81+
./bin/plgm # Run with default 'config.yaml'
82+
./bin/plgm my_test.yaml # Run with specific config file
83+
./bin/plgm --help # Show this help message
8484

8585
Flags:
8686
-config string
@@ -108,6 +108,7 @@ Environment Variables (Overrides):
108108
PERCONALOAD_SKIP_SEED Do not seed initial data on start (true/false)
109109
PERCONALOAD_DEBUG_MODE Enable verbose logic logs (true/false)
110110
PERCONALOAD_USE_TRANSACTIONS Enable transactional workloads (true/false)
111+
PERCONALOAD_MAX_TRANSACTION_OPS Maximum number of operations to group into a single transaction block
111112

112113
[Operation Ratios] (Must sum to ~100)
113114
PERCONALOAD_FIND_PERCENT % of ops that are FIND
@@ -188,6 +189,7 @@ You can override any setting in `config.yaml` using environment variables. This
188189
| `skip_seed` | `PERCONALOAD_SKIP_SEED` | Do not seed initial data on start (`true`/`false`) | `true` |
189190
| `debug_mode` | `PERCONALOAD_DEBUG_MODE` | Enable verbose debug logging (`true`/`false`) | `false` |
190191
| `use_transactions` | `PERCONALOAD_USE_TRANSACTIONS` | Enable Transactional Workloads (`true`/`false`) | `false` |
192+
| `max_transaction_ops` | `PERCONALOAD_MAX_TRANSACTION_OPS` | Maximum number of operations to group into a single transaction block | `5` |
191193
| **Operation Ratios** | | (Must sum to ~100) | |
192194
| `find_percent` | `PERCONALOAD_FIND_PERCENT` | Percentage of Find operations | `50` |
193195
| `insert_percent` | `PERCONALOAD_INSERT_PERCENT` | Percentage of Insert operations (this is not related to the initial seed inserts) | `20` |
@@ -233,6 +235,59 @@ When executed, plgm performs the following steps:
233235

234236
![plgm](./plgm.gif)
235237

238+
### Interpreting the Output
239+
240+
To show how the Ops/Sec metrics are represented and what they signify, here is a sample of the real-time monitor output and a final summary. This data is modeled after the flights workload used when default_workload is true.
241+
242+
#### Real-Time Monitor Sample
243+
While running a workload, plgm prints a row every second (based on `status_refresh_rate_sec`).
244+
245+
```bash
246+
> Starting Workload...
247+
248+
TIME | TOTAL OPS | SELECT | INSERT | UPDATE | DELETE | AGG | TRANS
249+
-------------------------------------------------------------------------------
250+
00:01 | 8,300 | 5,004 | 798 | 1,650 | 848 | 0 | 0
251+
00:02 | 8,048 | 4,736 | 773 | 1,694 | 845 | 0 | 0
252+
00:03 | 8,168 | 4,728 | 824 | 1,737 | 879 | 0 | 0
253+
```
254+
What this represents:
255+
256+
* TIME: The elapsed time since the workload started (MM:SS).
257+
* TOTAL OPS: The combined number of all operations executed across all workers in that specific 1-second interval.
258+
* SELECT/INSERT/UPDATE/DELETE/AGG: The raw count of each specific operation type completed in that second.
259+
* TRANS: The number of successful transaction blocks completed in that second (reusing the CRUD operations above internally).
260+
261+
#### Final Summary and Latency Sample
262+
At the end of the run, plgm calculates the overall averages and the latency distribution.
263+
264+
```bash
265+
> Workload Finished.
266+
267+
SUMMARY
268+
--------------------------------------------------
269+
Runtime: 10.00s
270+
Total Ops: 81,746
271+
Avg Rate: 8,174 ops/sec
272+
273+
LATENCY DISTRIBUTION (ms)
274+
--------------------------------------------------
275+
TYPE AVG MIN MAX P95 P99
276+
---- --- --- --- --- ---
277+
SELECT 1.24 ms 0.45 ms 15.20 ms 4.00 ms 9.00 ms
278+
INSERT 12.11 ms 4.10 ms 85.00 ms 66.00 ms 73.00 ms
279+
UPDATE 9.71 ms 3.20 ms 78.40 ms 65.00 ms 71.00 ms
280+
DELETE 9.60 ms 3.05 ms 76.20 ms 65.00 ms 72.00 ms
281+
TRANS 25.40 ms 12.00 ms 145.00 ms 95.00 ms 112.00 ms
282+
```
283+
284+
What this represents:
285+
286+
* Avg Rate (Ops/Sec): The total throughput of the database cluster. It is calculated by dividing Total Ops by the total Runtime.
287+
* AVG Latency: The average time (in milliseconds) it took the MongoDB driver to receive a response for that operation.
288+
* P95/P99 (Percentiles): These are the most critical metrics for performance tuning. P99 represents the "worst-case" scenario for 99% of your users. For example, if P99 SELECT is 9.00ms, it means 99% of your flight searches completed in under 9ms, while 1% took longer.
289+
* TRANS Latency: This will typically be higher than individual operations because a single transaction block contains 1 to X grouped operations, where X is defined in the config file via `max_transaction_ops` or the env var `PERCONALOAD_MAX_TRANSACTION_OPS`.
290+
236291
---
237292

238293
## Custom Workloads
@@ -327,6 +382,8 @@ Please note:
327382
* If `use_transactions: false`, the transaction_percent value is ignored.
328383
* If there are no aggregation queries defined in queries.json, the aggregate_percent value is also ignored.
329384
* Aggregate operations will only generate activity if at least one query with "operation": "aggregate" is defined in your active JSON query files.
385+
* The maximum number of operations within a transaction is defined in the config file via `max_transaction_ops` or the env var `PERCONALOAD_MAX_TRANSACTION_OPS`. The number of operations per transaction will be randomized, with the max number being set as explained above.
386+
330387

331388
#### Concurrency & Workers
332389
* **`concurrency`**: Controls the number of "Active Workers" continuously executing operations against the database.

cmd/plgm/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func main() {
5959
fmt.Fprintf(os.Stderr, " %-35s %s\n", "PERCONALOAD_SKIP_SEED", "Do not seed initial data on start (true/false)")
6060
fmt.Fprintf(os.Stderr, " %-35s %s\n", "PERCONALOAD_DEBUG_MODE", "Enable verbose logic logs (true/false)")
6161
fmt.Fprintf(os.Stderr, " %-35s %s\n", "PERCONALOAD_USE_TRANSACTIONS", "Enable transactional workloads (true/false)")
62+
fmt.Fprintf(os.Stderr, " %-35s %s\n", "PERCONALOAD_MAX_TRANSACTION_OPS", "Maximum number of operations to group into a single transaction block")
6263

6364
fmt.Fprintf(os.Stderr, "\n [Operation Ratios] (Must sum to ~100)\n")
6465
fmt.Fprintf(os.Stderr, " %-35s %s\n", "PERCONALOAD_FIND_PERCENT", "% of ops that are FIND")

config.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ duration: "10s"
7575
# Enable transactional workload
7676
use_transactions: false
7777

78+
# The maximum number of operations to group into a single transaction block.
79+
# plgm will pick a random number between 1 and this value for each transaction.
80+
max_transaction_ops: 5
81+
7882
# --- Operation Mix ---
7983
# The percentage of operations allocated to each type.
8084
# Will be normalized automatically if the sum != 100.

internal/config/config.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type AppConfig struct {
2929
AggregatePercent int `yaml:"aggregate_percent"`
3030
TransactionPercent int `yaml:"transaction_percent"`
3131
UseTransactions bool `yaml:"use_transactions"`
32+
MaxTransactionOps int `yaml:"max_transaction_ops"`
3233
DebugMode bool `yaml:"debug_mode"`
3334

3435
FindBatchSize int `yaml:"find_batch_size"`
@@ -99,6 +100,9 @@ func applyDefaults(cfg *AppConfig) {
99100
if cfg.RetryBackoffMs <= 0 {
100101
cfg.RetryBackoffMs = 5
101102
}
103+
if cfg.MaxTransactionOps <= 0 {
104+
cfg.MaxTransactionOps = 3
105+
}
102106
}
103107

104108
func applyEnvOverrides(cfg *AppConfig) {
@@ -161,6 +165,11 @@ func applyEnvOverrides(cfg *AppConfig) {
161165
cfg.UseTransactions = b
162166
}
163167
}
168+
if v := os.Getenv("PERCONALOAD_MAX_TRANSACTION_OPS"); v != "" {
169+
if n, err := strconv.Atoi(v); err == nil && n > 0 {
170+
cfg.MaxTransactionOps = n
171+
}
172+
}
164173
if envDocs := os.Getenv("PERCONALOAD_DOCUMENTS_COUNT"); envDocs != "" {
165174
if n, err := strconv.Atoi(envDocs); err == nil && n >= 0 {
166175
cfg.DocumentsCount = n

internal/mongo/runner.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ func runTransaction(ctx context.Context, id int, wCfg workloadConfig, rng *rand.
175175
start := time.Now()
176176

177177
_, err = session.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
178-
// Run 2 to 5 random operations per transaction
179-
numOps := rng.Intn(4) + 2
178+
// generates a random number between 1 and MaxTransactionOps, this controls the number of random operations per transaction
179+
numOps := rng.Intn(wCfg.appConfig.MaxTransactionOps) + 1
180180
for i := 0; i < numOps; i++ {
181181
// Select standard CRUD
182182
innerOp := selectOperation(wCfg.percentages, rng)

0 commit comments

Comments
 (0)