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
K
to 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 inR
had been evaluated normally.
There are 2 kinds of responses:
- Response that the value
V
for requested keyK
was found. This is formatted as[-1, V]
. - Response that the value for requested key
K
was 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"]]