Memcache
Store and retrieve data in memory(not persistent) base on specific hash function.
concepts
Slab: allocate as many pages as the ones available
Page: a memory area of default 1MB which contains as many chunks
Chunk: minimum allocated space for a single item
LRU: least recently used list
ref: Journey to the centre of memcached
we could say that we would run out of memory when all the available pages are allocated to slabs
memcached is designed to evict old/unused items in order to store new ones
every item operation (get, set, update or remove) requires the item in question to be locked
memcached only tries to remove the first 5 items of the LRU — after that it simply gives up and answers with OOM (out of memory)
commands with telnet
1 2 3 |
<command> <key> <flags> <exptime> <bytes> <data> |
get
set
12345678set key3 0 0 3abcSTOREDset key3 0 0 4abcdSTOREDflush_alladd: add key or return NOT_STORED if exists
1234567891011add key1 0 0 3abcSTOREDadd key1 0 0 3xyzNOT_STOREDadd key2 0 0 3abcdCLIENT_ERROR bad data chunkflush_allreplace: replace key or return NOT_STORED if exists
append, prepend
123456789101112set key1 0 0 3abcSTOREDappend key1 0 0 3efgSTOREDget key1VALUE key1 0 6abcefgENDflush_allincr, decr
123456789set key1 0 0 3999STOREDincr key1 11000decr key1 10010flush_alldelete
flush_all
stats
version
quit
Run Service
Image used: memcached
1 2 3 4 5 6 |
$ docker run --name my-memcache -p 11211:11211 -d memcached memcached -m 64 $ telnet localhost 11211 Trying 127.0.0.1... Connected to localhost. |
Python client: pymemcache
Distributed Caching
Modulo Hashing
- Pros: Balancing the distribution between instances in cluster
- Cons: 1. Loss data if instance down 2. hard to scale
Example
Run 3 instances, expose at port 11211, 11212, 11213
1 2 3 4 5 |
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7532e2610ba1 memcached "docker-entrypoint.s…" 3 seconds ago Up 1 second 0.0.0.0:11213->11211/tcp memcache-2 490638b0bc19 memcached "docker-entrypoint.s…" 9 seconds ago Up 7 seconds 0.0.0.0:11212->11211/tcp memcache-1 215c8f2c3cb5 memcached "docker-entrypoint.s…" 25 seconds ago Up 23 seconds 0.0.0.0:11211->11211/tcp memcache-0 |
Use python client to set key
Get client instance
1 2 3 4 |
>>> from pymemcache.client.hash import HashClient >>> servers = [('127.0.0.1', port) for port in [11211, 11212, 11213]] >>> client = HashClient(servers) |
pymemcache
use Murmur3 hashing
1 2 3 4 5 6 7 |
>>> from pymemcache.client.murmur3 import murmur3_32 >>> murmur3_32('abc') 3017643002 >>> murmur3_32('abc') % 3 # we have 3 cache server 2 >>> client.set('abc', 'this key go to server 3/3)') |
Test with telnet
telnet the third cache server
1 2 3 4 5 6 7 8 9 |
~$ telnet localhost 11213 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. get abc VALUE abc 0 25 this key go to server 3/3 END |
Consistent Hashing
Scale up / down not affect all the servers on the ring
High Availability
- Repcached: replica data between masters
- KeepAlive: port forword to slave if master down