A concurrent key-value store with an HTTP API. Implemented in Rust with the Tokio asynchronous runtime and the Axum web framework.
Copyright 2024 Patrick Lambein
This project implements a in-memory key-value store with the following characteristics:
- Concurrent access using Tokio's asynchronous runtime
- HTTP-based RESTful API built with Axum
- Compare-and-swap (CAS) operations for atomic updates
- Time-to-live (TTL) support for key expiration
- Server-Sent Events (SSE) for key change notifications
- Batch operations for multiple key-value manipulations
LockMap: Custom concurrent map implementation usingtokio::sync::RwLockfor write operations and inner mutability (usingstd::sync::Mutex) for read operationsUtf8Bytes: Wrapper aroundbytes::Bytesensuring UTF-8 validity
GET /store/:key: Retrieve a valuePUT /store/:key: Insert or update a valueDELETE /store/:key: Remove a key-value pairPOST /store/cas/:key: Compare-and-swap operationGET /watch_key/:key: Watch a single key for changesPOST /watch: Watch multiple keys for changesPOST /batch: Perform multiple operations in a single requestGET /status: Retrieve store metrics
- Read operations use
RwLock::read()with inner mutability for updates - Write operations use
RwLock::write()for exclusive access - Compare-and-swap uses optimistic locking with
RwLock::read()
- Unit tests for individual components (
LockMap,Utf8Bytes) - Integration tests for API endpoints
To run the server:
cargo runAPI interaction examples:
# Insert a key-value pair
curl -X PUT http://localhost:3000/store/key1 -d "value1"
# Retrieve a value
curl http://localhost:3000/store/key1
# Delete a key-value pair
curl -X DELETE http://localhost:3000/store/key1
# Compare-and-swap
curl -X POST http://localhost:3000/store/cas/key1 -H "Content-Type: application/json" -d '{"expected":"old_value","new":"new_value"}'
# Watch a single key for changes
curl http://localhost:3000/watch_key/key1
# Watch multiple keys for changes
curl -X POST http://localhost:3000/watch -H "Content-Type: application/json" -d '["key1", "key2", "key3"]'- Use of
bytes::Bytesfor efficient memory management of values - Custom
Utf8Bytestype to ensure UTF-8 validity while maintaining the efficiency ofBytes - Separation of concerns between the storage layer (
LockMap) and the API layer - Use of
tower-governorfor rate limiting
- Current implementation is in-memory only; no persistence
- No support for distributed operations or clustering
- Potential for reader starvation in high-contention scenarios due to the use of
RwLock
axum: Web frameworktokio: Asynchronous runtimetower-governor: Rate limitingtracing: Logging and instrumentationserde: Serialization and deserialization of JSON payloadsbytes: Efficient byte buffer management
This project serves as a practical exploration of concurrent data structure design and RESTful API implementation in Rust.
See the LICENSE.md file for license rights and limitations (AGPLv3)