mirror of
https://github.com/hanzoai/datastore.git
synced 2026-09-26 13:55:07 +00:00
Adds a stress testing framework for ClickHouse Keeper under `tests/stress/keeper/`, wired into CI (PR gate + nightly workflows). Key components: - Workloads: `keeper_bench.py` runner with YAML-defined workload profiles (`prod_mix.yaml`, `read_requests.yaml`, `write_requests.yaml`, etc.) - Scenarios: `core_no_faults.yaml` and `core_faults.yaml` with netem-based network fault injection (latency, jitter, packet loss) - Fault framework: `faults/network.py` (netem), `faults/base.py` (step dispatcher with `kind: parallel` support) - Metrics: `MetricsSampler` collects keeper stats, `sink.py` writes JSONL, ingested into CIDB via `ingest_keeper_metrics.py` post-hook - Gates: scenario pass/fail conditions based on RPS, p99 latency, error rate - Grafana dashboards for run details, 1vs1 comparison, historical progression CI integration: - PR job: 3 no-fault scenarios (prod-mix, read-multi, write-multi), ARM_LARGE, 15 min each, runs when `src/Coordination/` or stress test files change - Nightly (no-faults): all no-fault scenarios, default + rocks backends, ARM_LARGE - Nightly (faults): all fault scenarios, default + rocks backends, ARM_LARGE - Single `keeper_stress_job` config; mode detected via `Info().pr_number` and `Info().workflow_name` inside the job script Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
37 lines
1.0 KiB
Python
37 lines
1.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Post-hook script: ingest keeper_metrics.jsonl into CIDB after a keeper stress job."""
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
_repo_dir = str(Path(__file__).resolve().parents[3])
|
|
_ci_dir = str(Path(__file__).resolve().parents[2])
|
|
for _p in (_repo_dir, _ci_dir):
|
|
if _p not in sys.path:
|
|
sys.path.insert(0, _p)
|
|
|
|
from praktika.settings import Settings
|
|
from praktika.utils import Utils
|
|
from ci.jobs.scripts.cidb_cluster import CIDBCluster
|
|
|
|
|
|
def main():
|
|
metrics_file = os.environ.get(
|
|
"KEEPER_METRICS_FILE",
|
|
f"{Utils.absolute_path(Settings.TEMP_DIR)}/keeper_metrics.jsonl",
|
|
)
|
|
if not os.path.exists(metrics_file):
|
|
print(f"NOTE: keeper metrics file not found at {metrics_file!r}, skipping ingestion")
|
|
return
|
|
|
|
ci_db = CIDBCluster()
|
|
inserted, _ = ci_db.insert_keeper_metrics_from_file(
|
|
file_path=metrics_file,
|
|
chunk_size=1000,
|
|
)
|
|
print(f"NOTE: keeper metrics ingested: file={metrics_file} inserted={inserted}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|