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
- Host: GitHub
- URL: https://github.com/josephscott/marmerine
- Owner: josephscott
- License: mit
- Created: 2021-12-28T00:36:03.000Z (over 4 years ago)
- Default Branch: trunk
- Last Pushed: 2024-01-20T03:45:23.000Z (over 2 years ago)
- Last Synced: 2024-04-20T18:42:54.955Z (about 2 years ago)
- Topics: memcached, memcached-server
- Language: PHP
- Homepage:
- Size: 8.92 MB
- Stars: 3
- Watchers: 4
- Forks: 1
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
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.