Neks is an in-memory networked key/value server written in ~200 lines of Haskell.
It is intended to be very easy to modify.
- Very simple
- Pretty fast (>1M transactions per second is easy, see Benchmark)
- Highly concurrent
- Atomic transactions (e.g. atomic read-and-swap)
- Optional disk persistence (with atomic snapshotting)
cabal install neks
NeksServer <opt-args>
NeksClient <args>
cabal sandbox init
cabal install --only-dependencies
cabal run NeksServer
cabal run NeksClient -- <args>
or, with dependencies installed:
ghc -O2 -threaded Network/Neks/NeksServer.hs
ghc -O2 -threaded Network/Neks/NeksClient.hs
./Network/Neks/NeksServer +RTS -N<number of cores>
./Network/Neks/NeksClient <args>
To run the Python client:
python3 Client.py
NeksServer --help
NeksClient --help
The server and client run on two cores. The client runs
- 50 threads
- 200 requests per thread
- 50 reads and 50 writes per request
Speed depends on latency and bandwidth. Here's what I get on my home machines:
| Avg. Latency | Transactions / Second |
|---|---|
| .1ms (localhost) | 1,150,000 |
| .3ms (ethernet) | 1,100,000 |
| 3.5ms (wireless) | 750,000 |
All network encoding is done using msgpack.
Messages are preceded by the length of the message, transmitted as a 64-bit big-endian unsigned integer.
The client sends requests to the server, and the server responds with the results of the requests.
There are 4 kinds of requests:
- Requests to Get key
K. These are formatted as[0, K]. The server sends a response. - Requests to Set key
Kto valueV. These are formatted as[1, K, V]. The server does not send a response. - Requests to Delete key
K. These are formatted as[2, K]. The server does not send a response. - Requests to Atomically evaluate a list of requests
R. This is formatted as[3, R]. The server sends the response as if all requests inRhad been evaluated normally.
There are 2 kinds of responses:
- Response that the value
Vfor requested keyKwas found. This is formatted as[-1, V]. - Response that the value for requested key
Kwas not found. This is formatted as[-2].
Example conversation:
Client: <message length>[[1,"status","OK"],[0,"Jim"],[0,"Dwight"]]
Server: <message length>[[-1,"Halpert"],[-1,"Schrute"]]