forked from ikolomi/resp-bench
-
Notifications
You must be signed in to change notification settings - Fork 1
Add Python benchmark engine (async valkey-glide, redis-py, valkey-py) #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jamesx-improving
wants to merge
3
commits into
main
Choose a base branch
from
feat/add-python-engine
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
b83ef00
Add Python benchmark engine (async valkey-glide, redis-py, valkey-py)
jamesx-improving 3eab581
address comment: claim requests from a shared budget like Java
jamesx-improving 4096bac
address comment: worker isolation, config validation, driver config p…
jamesx-improving File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "schema_version": "1.0", | ||
| "description": "redis-py async client - default configuration", | ||
| "driver_id": "redis-py", | ||
| "mode": "standalone", | ||
| "command_timeout_ms": 5000, | ||
| "specific_driver_config": {} | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "schema_version": "1.0", | ||
| "description": "valkey-glide Python async client - default configuration", | ||
| "driver_id": "valkey-glide-python", | ||
| "mode": "standalone", | ||
| "command_timeout_ms": 5000, | ||
| "specific_driver_config": {} | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "schema_version": "1.0", | ||
| "description": "redis-py async client - standalone mode", | ||
| "driver_id": "redis-py", | ||
| "mode": "standalone", | ||
| "command_timeout_ms": 5000, | ||
| "specific_driver_config": {} | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "schema_version": "1.0", | ||
| "description": "valkey-glide Python async client - standalone mode", | ||
| "driver_id": "valkey-glide-python", | ||
| "mode": "standalone", | ||
| "command_timeout_ms": 5000, | ||
| "specific_driver_config": {} | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "schema_version": "1.0", | ||
| "description": "redis-py async client - high-throughput configuration", | ||
| "driver_id": "redis-py", | ||
| "mode": "standalone", | ||
| "specific_driver_config": {}, | ||
| "command_timeout_ms": 10000 | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "schema_version": "1.0", | ||
| "description": "valkey-glide Python async client - high-throughput configuration", | ||
| "driver_id": "valkey-glide-python", | ||
| "mode": "standalone", | ||
| "specific_driver_config": {}, | ||
| "command_timeout_ms": 10000 | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| .venv/ | ||
| __pycache__/ | ||
| *.egg-info/ | ||
| *.pyc | ||
| dist/ | ||
| build/ | ||
| .pytest_cache/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,67 +1,79 @@ | ||
| # resp-bench Python Engine | ||
|
|
||
| 🚧 **This engine is planned but not yet implemented.** | ||
| Python implementation of the resp-bench benchmark suite, at parity with the | ||
| Java (reference), Ruby, and C# engines. | ||
|
|
||
| ## Overview | ||
| ## Supported Drivers | ||
|
|
||
| Python implementation of the resp-bench benchmark suite. | ||
| | Driver | `driver_id` | Package | Notes | | ||
| |--------|-------------|---------|-------| | ||
| | Valkey GLIDE | `valkey-glide-python` | `valkey-glide` (`import glide`) | Async client | | ||
| | redis-py | `redis-py` | `redis` (`redis.asyncio`) | Async client, RESP3, retries disabled | | ||
| | Recording | `recording` | — | In-memory; for server-free tests | | ||
|
|
||
| ## Planned Drivers | ||
| Peer drivers are kept deliberately few so each one's configuration can be held | ||
| equivalent (same RESP version, same retry policy, same command timeout). A | ||
| `valkey-py` driver is a planned follow-up. | ||
|
|
||
| | Driver | Package | Status | | ||
| |--------|---------|--------| | ||
| | redis-py | `redis` | 📋 Planned | | ||
| | redis-py-async | `redis[hiredis]` | 📋 Planned | | ||
| | valkey-glide | `valkey-glide` | 📋 Planned | | ||
| > The GLIDE `driver_id` is `valkey-glide-python` (not the bare `valkey-glide`, | ||
| > which is the Java driver) — matching the `valkey-glide-ruby` / | ||
| > `valkey-glide-csharp` convention. | ||
|
|
||
| ## Planned Features | ||
| ## Execution model | ||
|
|
||
| - Full parity with Java engine | ||
| - Async/await based execution using `asyncio` | ||
| - HdrHistogram for latency collection | ||
| - NDJSON metrics output | ||
| The engine is asyncio-based. For a phase with `connections = N`, it creates | ||
| **N client instances** (one client per connection — the `client == connection` | ||
| invariant shared by every engine) and runs **N worker coroutines** concurrently | ||
| on a single event loop. Each worker awaits one command at a time, i.e. | ||
| `pipeline_depth = 1` — the faithful async analogue of the Java/Ruby | ||
| "one in-flight request per connection" model, keeping results comparable across | ||
| engines. | ||
|
|
||
| ## Contributing | ||
| This one-client-per-connection mapping is this engine's baseline; it is not a | ||
| property of the whole suite (among other engines' drivers, `lettuce` and | ||
| `redis-rb` are 1:1, but `jedis`/`redisson` pool, `spring-data-*` share a | ||
| template, and `stackexchange-redis` multiplexes). Sharing a single multiplexing client across | ||
| workers was proposed and declined upstream | ||
| ([ikolomi/resp-bench#11](https://github.com/ikolomi/resp-bench/issues/11)) in | ||
| favour of keeping this baseline. | ||
|
|
||
| We welcome contributions to implement the Python engine! Please see: | ||
| - [Architecture Documentation](../docs/ARCHITECTURE.md) | ||
| - [Adding a Language Guide](../docs/ADDING_LANGUAGE.md) | ||
| ### Known limits | ||
|
|
||
| ## Directory Structure (Planned) | ||
| - **`pipeline_depth > 1`** (multiple in-flight requests per connection) is not | ||
| implemented; such a phase runs at depth 1 and logs a warning. | ||
| - **Single event loop.** Above ~128 connections the event loop, not the driver, | ||
| becomes the bottleneck, and loop queuing delay is attributed to the driver in | ||
| the reported latency. The engine warns past that threshold. The Java engine hit | ||
| the same ceiling with one command-issuing thread and added multiple issuer | ||
| threads; this engine has no equivalent yet, so high-connection-count Python | ||
| numbers are not directly comparable to other engines. | ||
|
|
||
| ``` | ||
| python/ | ||
| ├── README.md | ||
| ├── pyproject.toml | ||
| ├── requirements.txt | ||
| └── src/ | ||
| └── resp_bench/ | ||
| ├── __init__.py | ||
| ├── __main__.py | ||
| ├── client/ | ||
| │ ├── __init__.py | ||
| │ ├── interface.py | ||
| │ └── impl/ | ||
| │ └── redis_py.py | ||
| ├── command/ | ||
| ├── config/ | ||
| ├── engine/ | ||
| └── metrics/ | ||
| ``` | ||
|
|
||
| ## Usage (Future) | ||
| ## Installation | ||
|
|
||
| ```bash | ||
| # Install | ||
| pip install -e . | ||
| # with test tooling: | ||
| pip install -e ".[dev]" | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| # Run benchmark | ||
| ```bash | ||
| python -m resp_bench \ | ||
| --server localhost:6379 \ | ||
| --driver ../configs/drivers/example-redis-py-standalone.json \ | ||
| --driver ../configs/drivers/default/redis-py.json \ | ||
| --workload ../configs/workloads/example-workload.json \ | ||
| --metrics output.ndjson | ||
|
|
||
| # Show supported drivers | ||
| # Show supported drivers and commands | ||
| python -m resp_bench --info | ||
| ``` | ||
|
|
||
| ## Testing | ||
|
|
||
| ```bash | ||
| pytest # unit + recording-driver integration (no server needed) | ||
| ``` | ||
|
|
||
| See [../docs/ADDING_LANGUAGE.md](../docs/ADDING_LANGUAGE.md) and | ||
| [../docs/ARCHITECTURE.md](../docs/ARCHITECTURE.md) for the shared contracts. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| [build-system] | ||
| requires = ["setuptools>=68"] | ||
| build-backend = "setuptools.build_meta" | ||
|
|
||
| [project] | ||
| name = "resp-bench-python" | ||
| version = "0.1.0" | ||
| description = "Python benchmark engine for resp-bench (async valkey-glide and redis-py)" | ||
| readme = "README.md" | ||
| requires-python = ">=3.10" | ||
| license = { text = "Apache-2.0" } | ||
| # Pinned to exact released versions for reproducible benchmark runs, matching the | ||
| # Ruby/Java/C# engines. Client-library defaults that affect throughput (RESP | ||
| # version, pool size, socket timeouts, retry counts) have changed between minor | ||
| # releases, so a range would make results depend on the resolution date. | ||
| # hiredis is pinned in deliberately so redis-py always uses its compiled parser | ||
| # (GLIDE parses in Rust); the parser actually in use is recorded in the metrics | ||
| # metadata. | ||
| dependencies = [ | ||
| "valkey-glide==2.5.2", | ||
| "redis==8.1.0", | ||
| "hiredis==3.4.1", | ||
| "hdrhistogram==0.10.7", | ||
| ] | ||
|
|
||
| [project.optional-dependencies] | ||
| dev = [ | ||
| "pytest>=8.0", | ||
| "pytest-asyncio>=0.23", | ||
| ] | ||
|
|
||
| [project.scripts] | ||
| resp-bench = "resp_bench.cli:main" | ||
|
|
||
| [tool.setuptools.packages.find] | ||
| where = ["src"] | ||
|
|
||
| [tool.pytest.ini_options] | ||
| asyncio_mode = "auto" | ||
| testpaths = ["tests"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| """resp-bench Python engine. | ||
|
|
||
| Async implementation of the resp-bench benchmark suite, at parity with the | ||
| Java (reference), Ruby, and C# engines. Drives async clients (valkey-glide, | ||
| redis-py asyncio) on a single asyncio event loop with one client per | ||
| connection. | ||
| """ | ||
|
|
||
| from .version import VERSION | ||
|
|
||
| __all__ = ["VERSION"] |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.