benchmarking/locust: capture cluster hardware facts and density frontiers in runner - #1603
Conversation
Max Smythe (maxsmythe)
left a comment
There was a problem hiding this comment.
Thanks for this! Left a few initial comments.
| if with_boomer: | ||
| boomer_cmd = [BOOMER_BINARY, "--user-class", Path(test_file(args.file)).stem] | ||
| boomer_cmd = [BOOMER_BINARY] | ||
| if "boomer-glutton" not in os.path.basename(BOOMER_BINARY): |
There was a problem hiding this comment.
Is all this switching to avoid breaking changes? Shouldn't the binary be bundled in the container? May be able to just straight rename the binary.
There was a problem hiding this comment.
yeah, my benchmark cluster was still running an older image from before the #1295 rename, so I needed
these to get my trials running against it. None of it applies to a normal run since the Dockerfile
bundles /app/boomer-worker. Reverting to that and dropping the env knobs.
| return int(float(mem_str)) | ||
|
|
||
|
|
||
| def get_cluster_hardware_facts(logs: TextIO | None = None) -> dict[str, any]: |
There was a problem hiding this comment.
I think this batch of code is large enough and focused enough to warrant its own file.
There was a problem hiding this comment.
will move it into its own file
| "allocatable_ram_gb": None, | ||
| "worker_pod_count": None, | ||
| } | ||
| # 1. Environment variables override |
There was a problem hiding this comment.
Why do we need overrides?
There was a problem hiding this comment.
I added them as a fallback in case the runner couldn't read the cluster, but this PR adds the RBAC for
that anyway so they aren't really needed. Removing them.
| ): | ||
| return facts | ||
|
|
||
| # 2. In-cluster HTTP API or local kubectl discovery |
There was a problem hiding this comment.
I think K8s has a Python client we can use for this?
There was a problem hiding this comment.
oh yeah... I went with urllib because the locust image is distroless and I was trying to avoid
adding a dependency, but we already install pip packages in there anyway, so that isn't really a
concern. will be switching to the client.
| except Exception: | ||
| pass | ||
| elif shutil.which("kubectl"): | ||
| # Local workstation fallback via kubectl |
There was a problem hiding this comment.
Why do we need this? Also I think we may get standard auth for free w/a client
There was a problem hiding this comment.
that was just so I could run runner.py from my workstation, but you're right that the client handles
that for us. Dropping the kubectl path.
| else: | ||
| stats_generated = jsonl_path.exists() | ||
| if stats_generated: | ||
| facts = get_cluster_hardware_facts(logs) |
There was a problem hiding this comment.
for truly large clusters, we may want the ability to disable this (hitting every node may take a long time)
There was a problem hiding this comment.
good call, will be adding a --cluster-facts / --no-cluster-facts flag (default on) so it can be skipped
entirely.
|
Thanks for the review, Max. All fixes are in the latest commit. Reverted the boomer switching (that only existed because my cluster was on a Added a Other things I did along the way:
Tests
Run with: Also validated on a live cluster with glutton runs. |
Fixes #1590
What this PR does
In alignment with the Actor Density Benchmark Specs, this PR updates
benchmarking/locust/runner.pyto auto-discover cluster capacity, record hardware density frontiers (both client-side and server-side A/P ratios), and harvest server-side Prometheus metrics intostats.jsonlandserver_summary.json.Proposed Changes
runner.py,locust.yaml):nodes,pods) for the Locust service account inlocust.yaml.trial_summary): Computesactors_per_node,actors_per_vcpu,actors_per_gb_ram, and steady-state A/P demand percentiles fromstats_history.csv.server_summary): Gathers true physical worker assignment (ate_workerpool_workers), host Linux kernel PSI stalls (CPU/Mem/IO), and snapshot performance from in-cluster Prometheus.stats.jsonland outputsserver_summary.jsonwhile keepingstatus.jsonschema strictly unchanged.server_telemetry.py):How this was tested
benchmarking/locust/unit_tests/test_server_telemetry.py(all passed).gluttonruns:stats.jsonlcontainstrial_summary(hardware facts + client frontiers) andserver_summary.server_summary.jsonis populated with Prometheus metrics.status.jsonminimal schema is preserved.References
Agent Substrate: Actor Density Benchmark Specs
Tests pass
Appropriate changes to documentation are included in the PR