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::RwLock
for write operations and inner mutability (usingstd::sync::Mutex
) for read operationsUtf8Bytes
: Wrapper aroundbytes::Bytes
ensuring 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 run
API 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::Bytes
for efficient memory management of values - Custom
Utf8Bytes
type 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-governor
for 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)