An open API service indexing awesome lists of open source software.

https://github.com/josephscott/marmerine

An alternate Memcached implementation
https://github.com/josephscott/marmerine

memcached memcached-server

Last synced: 11 months ago
JSON representation

An alternate Memcached implementation

Awesome Lists containing this project

README

          

# Marmerine

This is an alternate Memcached implementation.

```
git clone https://github.com/josephscott/marmerine.git
composer install
php server.php start
```

## Storage Commands

### `set`

- **Supported:** Yes ✅
- **Format:** `set [noreply]\r\n\r\n`
- **Success Response:** `STORED\r\n`
- **Error Response:** `CLIENT_ERROR [error]\r\nERROR\r\n`

__Examples__
```shell
$ printf "set thing 0 300 3\r\nabc\r\n" | nc localhost 11211
STORED
```

```shell
$ printf "set thing 0 300 3\r\nabc123XYZ\r\n" | nc localhost 11211
CLIENT_ERROR bad data chunk
ERROR
```

__Description__

This will store the value of the given key, even if it already exists.

### `add`

- **Supported:** Yes ✅
- **Format:** `add [noreply]\r\n\r\n`
- **Success Response:** `STORED\r\n`
- **Failure Response:** `NOT_STORED\r\n`
- **Error Response:** `CLIENT_ERROR [error]\r\nERROR\r\n`

__Examples__
```shell
$ printf "add thing 0 300 3\r\nabc\r\n" | nc localhost 11211
STORED
```

```shell
$ printf "add thing 0 300 3\r\nabc123XYZ\r\n" | nc localhost 11211
CLIENT_ERROR bad data chunk
ERROR
```

```shell
$ printf "add thing 0 300 3\r\nabc\r\n" | nc localhost 11211
STORED
$ printf "add thing 0 300 3\r\nabc\r\n" | nc localhost 11211
NOT_STORED
```

__Description__

This will store the value of the given key, only if it does not already exist.

### `replace`

- **Supported:** Yes ✅
- **Format:** `replace [noreply]\r\n\r\n`
- **Success Response:** `STORED\r\n`
- **Error Response:** `NOT_STORED\r\n`

__Examples__
```shell
$ printf "add thing 0 300 3\r\nabc\r\n" | nc localhost 11211
STORED
$ printf "replace thing 0 300 12\r\nabc-REPLACED\r\n" | nc localhost 11211
STORED
$ printf "get thing\r\n" | nc localhost 11211
VALUE thing 0 12
abc-REPLACED
END
```

```shell
$ printf "replace thing 0 300 3\r\nabc\r\n" | nc localhost 11211
NOT_STORED
```

__Description__

This will replace the value of the given key.

### `append`

- **Supported:** Yes ✅
- **Format:** `append [noreply]\r\n\r\n`
- **Success Response:** `STORED\r\n`
- **Error Response:** `NOT_STORED\r\n`

__Examples__
```shell
$ printf "add thing 0 300 3\r\nabc\r\n" | nc localhost 11211
STORED
$ printf "append thing 0 300 6\r\n-AFTER\r\n" | nc localhost 11211
STORED
$ printf "get thing\r\n" | nc localhost 11211
VALUE thing 0 9
abc-AFTER
END
```

```shell
$ printf "append thing 0 300 6\r\n-AFTER\r\n" | nc localhost 11211
NOT_STORED
```

__Description__
This will append a string to the value of an existing key.

### `prepend`

- **Supported:** Yes ✅
- **Format:** `prepend [noreply]\r\n\r\n`
- **Success Response:** `STORED\r\n`
- **Error Response:** `NOT_STORED\r\n`

__EXAMPLES__
```shell
$ printf "add thing 0 300 3\r\nabc\r\n" | nc localhost 11211
STORED
$ printf "prepend thing 0 300 7\r\nBEFORE-\r\n" | nc localhost 11211
STORED
$ printf "get thing\r\n" | nc localhost 11211
VALUE thing 0 10
BEFORE-abc
END
```

__Description__
This will prepend a string to the value of an existing key.

### `cas`

- **Supported:** Yes ✅
- **Format:** `cas [noreply]\r\n\r\n`
- **Success Response:** `STORED\r\n`
- **Error Resposne:** `NOT_STORED\r\n`

__EXAMPLES__
```
$ printf "set thing 0 300 3\r\nabc\r\n" | nc localhost 11211
STORED
$ printf "gets thing\r\n" | nc localhost 11211
VALUE thing 0 3 1
abc
END
$ printf "cas thing 0 300 3 1\r\nXYZ\r\n"| nc localhost 11211
STORED
```

__Description__

Set a new value for a key if the cas token hasn't changed.

### `touch`

- **Supported:** Yes ✅
- **Format:** `touch [noreply]\r\n`
- **Success Response:** `TOUCHED\r\n`
- **Error Resposne:** `NOT_FOUND\r\n`

__Examples__
```shell
$ printf "add thing 0 300 3\r\nabc\r\n" | nc localhost 11211
STORED
$ printf "touch thing 1800\r\n" | nc localhost 11211
TOUCHED
```

__Description__

Update the expiration time of an existing key.

## Retrieve Commands

### `get`

- **Supported:** Yes ✅
- **Format:** `get [key2 key3 ... keyn]\r\n`
- **Found Response:** `VALUE \r\n\r\nEND\r\n`
- **Not Found Response:** `END\r\n`

__Examples__
```shell
$ printf "set thing 0 300 3\r\nabc\r\n" | nc localhost 11211
STORED
$ printf "get thing\r\n" | nc localhost 11211
VALUE thing 0 3
abc
END
```

```shell
$ printf "get thing\r\n" | nc localhost 11211
END
```

```shell
$ printf "set thing1 0 300 4\r\n1abc\r\n" | nc localhost 11211
STORED
$ printf "set thing2 0 300 4\r\n2abc\r\n" | nc localhost 11211
STORED
$ printf "set thing3 0 300 4\r\n3abc\r\n" | nc localhost 11211
STORED
$ printf "get thing thing1 thing2 thing3\r\n" | nc localhost 11211
VALUE thing1 0 4
1abc
VALUE thing2 0 4
2abc
VALUE thing3 0 4
3abc
END
```

__Description__

Gets the value for the given key. When the key does not exist, a response with just `END\r\n` is given. When multiple keys are provided, only ones that exist will be returned.

### `gets`

- **Supported:** Yes ✅
- **Format:** `get [key2 key3 ... keyn]\r\n`
- **Found Response:** `VALUE \r\n\r\nEND\r\n`
- **Not Found Response:** `END\r\n`

__Examples__
```shell
$ printf "set thing 0 300 3\r\nabc\r\n" | nc localhost 11211
STORED
$ printf "gets thing\r\n" | nc localhost 11211
VALUE thing 0 3 1
abc
END
```

```shell
$ printf "gets thing\r\n" | nc localhost 11211
END
```

__Description__

This is the get command with the addition of the cas token in the response.

### `gat`

- **Supported:** No ⛔

### `gats`

- **Supported:** No ⛔

## Delete Commands

### `delete`

- **Supported:** Yes ✅
- **Format:** `delete [noreply]\r\n`
- **Success Response:** `DELETED\r\n`
- **Not Found Response:** `NOT_FOUND\r\n`

__Examples__
```shell
$ printf "set thing 0 300 3\r\nabc\r\n" | nc localhost 11211
STORED
$ printf "delete thing\r\n" | nc localhost 11211
DELETED
```

```shell
$ printf "delete thing\r\n" | nc localhost 11211
NOT_FOUND
```

__Description__

Delete the given key. If the key does not exist then `NOT_FOUND` is returned.

### `flush_all`

- **Supported:** Yes ✅
- **Format:** `flush_all [delay] [noreply]\r\n`
- **Every Response:** `OK\r\n`

__Examples__
```shell
$ printf "flush_all\r\n" | nc localhost 11211
OK
```

```shell
$ printf "flush_all\r\n" | nc localhost 11211
OK
$ printf "flush_all\r\n" | nc localhost 11211
OK
```

__Description__

Delete all of the stored keys. There is no fail or error condition, it always returns `OK`.

## Arithmetic Commands

### `incr`

- **Supported:** Yes ✅
- **Format:** `incr [noreply]\r\n`
- **Success Response:** `\r\n`
- **Error Response:** `CLIENT_ERROR cannot increment or decrement non-numeric value`

__Examples__
```shell
$ printf "add thing 0 300 1\r\n1\r\n" | nc localhost 11211
STORED
$ printf "incr thing 1\r\n" | nc localhost 11211
2
$ printf "incr thing 1\r\n" | nc localhost 11211
3
```

```shell
$ printf "add thing 0 300 3\r\nabc\r\n" | nc localhost 11211
STORED
$ printf "incr thing 1\r\n" | nc localhost 11211
CLIENT_ERROR cannot increment or decrement non-numeric value
```

__Description__

This only works on integer values.

### `decr`

- **Supported:** Yes ✅
- **Format:** `decr [noreply]\r\n`
- **Success Response:** `\r\n`
- **Error Response:** `CLIENT_ERROR cannot increment or decrement non-numeric value`

__Examples__
```shell
$ printf "add thing 0 300 1\r\n9\r\n" | nc localhost 11211
STORED
$ printf "decr thing 1\r\n" | nc localhost 11211
8
$ printf "decr thing 1\r\n" | nc localhost 11211
7
```

```shell
$ printf "add thing 0 300 3\r\nabc\r\n" | nc localhost 11211
STORED
$ printf "decr thing 1\r\n" | nc localhost 11211
CLIENT_ERROR cannot increment or decrement non-numeric value
```

__Description__

This only works on integer values.

## Miscellaneous Commands

### `quit`

- **Supported:** Yes ✅
- **Format:** `quit\r\n`
- **Every Response:** ( None )

__Examples__
```shell
$ printf "quit\r\n" | nc localhost 11211
```

__Description__

This closes the connection to the server. It does not return anything.

### `version`

- **Supported:** Yes ✅
- **Format:** `version\r\n`
- **Every Response:** `VERSION \r\n`

__Examples__
```shell
$ printf "version\r\n" | nc localhost 11211
VERSION 1.6.12
```

__Description__

Get the version number from the server.

### `verbosity`

- **Supported:** No ⛔

### `stats`

- **Supported:** Yes ✅
- **Format:** `stats\r\n`
- **Every Response:** `STAT \r\nEND\r\n`

__Example__
```shell
$ printf "stats\r\n" | nc localhost 11211
STAT pid 92458
STAT uptime 9
STAT time 1650595977
END
```

__Description__

Stats that are currently supported:

- pid
- uptime
- time
- total_connections
- curr_items
- cmd_
- _hits
- _misses

## Memcached Resources

- [Memcached](https://github.com/memcached/memcached), the original.
- [Memcached Protocol.txt](https://github.com/memcached/memcached/blob/master/doc/protocol.txt), general description of the protocols.
- [Twemproxy](https://github.com/twitter/twemproxy), a proxy for Memcached and Redis from Twitter.
- [Twemproxy Memcached Notes](https://github.com/twitter/twemproxy/blob/master/notes/memcache.md), helpful list of of supported Memcached comands in Twemproxy.
- [MySQL Memcached TCP Text Protocol](https://docs.oracle.com/cd/E17952_01/mysql-5.6-en/ha-memcached-interfaces-protocol.html), commands outlined for the MySQL implementation.
- [Memcached Cheat Sheet](https://lzone.de/cheat-sheet/memcached), a list of other Memcached resources and examples.
- [libmemcached-awesome](https://github.com/awesomized/libmemcached), an updated version of the original [libmemcached](https://libmemcached.org/libMemcached.html).
- [memc.rs](https://www.memc.rs/intro), Memcached clone written in Rust, compatible with the binary protocol.
- [memtier_benchmark](https://github.com/RedisLabs/memtier_benchmark), a Memcached ( and Redis ) benchmarking tool.
- [Expiration Times](https://www.php.net/manual/en/memcached.expiration.php), good description of how Memcached treats the expiration times.