A simplified Redis server implementation written in Golang. This is my solution for John Crickett's Write Your Own Redis Server Coding Challenge.
The server listens for clients. Once a client connects, a go routine is created to handle the client's session. During a session the client can send commands with RESP (Redis serialization protocol) messages. The server parses a message and then sends a response in the same RESP message format.
git clone https://github.com/C41M50N/Redis-Server-Lite
cd Redis-Server-Lite
go run cmd/redis-server/server.go
A list of the server's supported commands and their usage syntax.
Returns PONG
if no argument is provided, otherwise return a copy of the argument as a bulk.
PING [message]
Returns message
.
ECHO message
Set key
to hold the string value
. If key
already holds a value, it is overwritten, regardless of its type.
SET key value [EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT unix-time-milliseconds]
Returns the value of key
. If the key does not exist the special value nil
is returned.
GET key
Returns the number of keys that exist from those specified as arguments.
EXISTS key [key ...]
Removes the specified keys. A key is ignored if it does not exist. Returns the number of keys that were removed.
DEL key [key ...]
Increments the number stored at key
by one. If the key does not exist, it is set to 0
before performing the operation. An error is returned if the key contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64 bit signed integers. Returns the value of the key (as an integer) after the increment.
INCR key
Decrements the number stored at key
by one. If the key does not exist, it is set to 0
before performing the operation. An error is returned if the key contains a value of the wrong type or contains a string that can not be represented as integer. This operation is limited to 64 bit signed integers. Returns the value of the key (as an integer) after the decrement.
DECR key
Insert all the specified values at the head of the list stored at key
. If key
does not exist, it is created as empty list before performing the push operations. When key
holds a value that is not a list, an error is returned. Returns the length of the list after the push operation.
LPUSH key element [element ...]
Insert all the specified values at the tail of the list stored at key
. If key
does not exist, it is created as empty list before performing the push operation. When key
holds a value that is not a list, an error is returned. Returns the length of the list after the push operation.
RPUSH key element [element ...]
Returns the specified elements of the list stored at key
. If the data type of the value at the given key
is not a list, then an error is returned. The offsets start
and stop
are zero-based indexes, with 0
being the first element of the list (the head of the list), 1
being the next element and so on. The offsets can also be negative numbers indicating offsets starting at the end of the list.
LRANGE key start stop
The following benchmarks were performed on my M2 MacBook Pro.
> redis-benchmark -t set,get -n 100000 -q
SET: 42735.04 requests per second, p50=0.687 msec
GET: 46019.32 requests per second, p50=0.615 msec
> redis-benchmark -t set,get -n 100000 -q
SET: 44014.08 requests per second, p50=0.695 msec
GET: 46210.72 requests per second, p50=0.607 msec
> redis-benchmark -t set,get -n 100000 -q
SET: 44503.79 requests per second, p50=0.663 msec
GET: 47169.81 requests per second, p50=0.591 msec
> redis-benchmark -t set,get -n 100000 -q
SET: 165289.25 requests per second, p50=0.143 msec
GET: 159489.64 requests per second, p50=0.143 msec
> redis-benchmark -t set,get -n 100000 -q
SET: 163934.42 requests per second, p50=0.143 msec
GET: 165016.50 requests per second, p50=0.143 msec
> redis-benchmark -t set,get -n 100000 -q
SET: 171821.30 requests per second, p50=0.143 msec
GET: 168350.17 requests per second, p50=0.143 msec