Memcached is a free, open-source, high-performance, distributed memory object caching system, generic in nature but intended for use in speeding up dynamic web applications by alleviating database load.
Installation
Linux/Ubuntu
# Package manager installation
sudo apt update
sudo apt install memcached
# Verify installation
memcached -h
# Check version
memcached -h | grep memcached
macOS
# Homebrew installation
brew install memcached
# Start service
brew services start memcached
# Verify
memcached -h
Docker
# Pull official image
docker pull memcached:latest
# Run memcached container
docker run -d \
--name memcached \
-p 11211:11211 \
memcached:latest
# With memory limit (512MB)
docker run -d \
--name memcached \
-p 11211:11211 \
memcached:latest -m 512
# Verify
docker exec memcached memcached-tool localhost:11211 stats
Build from Source
# Download and compile
wget http://www.memcached.org/files/memcached-1.6.18.tar.gz
tar xzf memcached-1.6.18.tar.gz
cd memcached-1.6.18
./configure && make && sudo make install
# Verify
memcached -h
Daemon Startup
Basic Startup
# Start with default settings (port 11211, 64MB memory)
memcached
# Start in background daemon mode
memcached -d
# Specify port
memcached -p 11211 -d
# Specify memory limit (in MB)
memcached -m 256 -d
# Specify listen address
memcached -l 127.0.0.1 -p 11211 -d
Advanced Startup Options
# Multiple parameters
memcached -l 0.0.0.0 -p 11211 -m 512 -d -u memcache
# Enable verbose logging
memcached -l 0.0.0.0 -p 11211 -m 512 -v -d
# Set max connections (default: 1024)
memcached -c 4096 -m 512 -d
# Run with specific user
memcached -u memcache -m 512 -d
# Enable TCP/UDP protocols
memcached -p 11211 -U 11211 -m 512 -d
# Disable UDP (use -U 0)
memcached -p 11211 -U 0 -m 512 -d
Systemd Service Setup
# Create systemd service file
sudo tee /etc/systemd/system/memcached.service > /dev/null <<EOF
[Unit]
Description=Memcached
After=network.target
[Service]
Type=simple
User=memcache
ExecStart=/usr/bin/memcached -l 127.0.0.1 -p 11211 -m 512
Restart=always
[Install]
WantedBy=multi-user.target
EOF
# Enable and start service
sudo systemctl enable memcached
sudo systemctl start memcached
sudo systemctl status memcached
Telnet Protocol Interface
Connect to Memcached
# Connect via telnet
telnet localhost 11211
# Connect to remote host
telnet 192.168.1.10 11211
Data Storage Commands
| Command | Syntax | Description |
|---|
set | set <key> <flags> <exptime> <bytes>\r\n<data block>\r\n | Store data associated with a key |
add | add <key> <flags> <exptime> <bytes>\r\n<data block>\r\n | Store data only if key doesn’t exist |
replace | replace <key> <flags> <exptime> <bytes>\r\n<data block>\r\n | Replace data only if key exists |
append | append <key> <flags> <exptime> <bytes>\r\n<data block>\r\n | Append data to existing value |
prepend | prepend <key> <flags> <exptime> <bytes>\r\n<data block>\r\n | Prepend data to existing value |
Telnet Examples
# Telnet session - Set key
telnet localhost 11211
set mykey 0 3600 5
hello
STORED
# Get key
get mykey
VALUE mykey 0 5
hello
END
# Add key (fails if exists)
add mykey 0 3600 3
bye
NOT_STORED
# Add new key
add newkey 0 3600 5
world
STORED
# Replace existing key
replace mykey 0 3600 6
goodbye
STORED
# Append to value
append mykey 0 3600 6
there
STORED
# Prepend to value
prepend mykey 0 3600 5
hello
STORED
Data Retrieval Commands
| Command | Syntax | Description |
|---|
get | get <key> [<key> ...] | Retrieve data for one or more keys |
gets | gets <key> [<key> ...] | Retrieve data with CAS token |
delete | delete <key> | Delete a key |
incr | incr <key> <value> | Increment numeric value |
decr | decr <key> <value> | Decrement numeric value |
Telnet Retrieval Examples
# Get single key
get mykey
VALUE mykey 0 8
goodbye
END
# Get multiple keys
get key1 key2 key3
VALUE key1 0 5
value1
VALUE key2 0 5
value2
END
# Delete key
delete mykey
DELETED
# Delete non-existent key
delete nonexistent
NOT_FOUND
# Increment counter
set counter 0 3600 1
0
STORED
incr counter 1
1
incr counter 5
6
# Decrement counter
decr counter 2
4
Admin Commands
| Command | Syntax | Description |
|---|
stats | stats | Display server statistics |
stats slabs | stats slabs | Memory slab statistics |
stats items | stats items | Item statistics by slab |
stats cachedump | stats cachedump <slab> <limit> | Dump items in slab |
flush_all | flush_all [<delay>] | Clear all data |
quit | quit | Close connection |
Admin Examples
# Get server stats
stats
STAT pid 1234
STAT uptime 3600
STAT time 1640000000
STAT version 1.6.18
STAT libevent 2.1.12-stable
STAT pointer_size 64
STAT rusage_user 0.050000
STAT rusage_system 0.025000
STAT curr_items 42
STAT total_items 150
STAT bytes 2048
STAT curr_connections 5
STAT total_connections 25
STAT connection_structures 8
STAT reserved_fds 20
STAT cmd_get 100
STAT cmd_set 50
STAT cmd_flush 1
STAT cmd_touch 0
STAT get_hits 80
STAT get_misses 20
STAT delete_misses 5
STAT delete_hits 10
STAT incr_misses 0
STAT incr_hits 5
STAT decr_misses 0
STAT decr_hits 3
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 5120
STAT bytes_written 10240
STAT limit_maxbytes 67108864
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT time_in_listen_disabled_us 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT malloc_fails 0
STAT server_id 0
END
# Get slab statistics
stats slabs
STAT active_slabs 5
STAT total_malloced 1048576
STAT 1:chunk_size 96
STAT 1:chunks_per_page 10922
STAT 1:total_pages 1
STAT 1:total_chunks 10922
STAT 1:used_chunks 42
STAT 1:free_chunks 10880
...
END
# Dump items from slab 1
stats cachedump 1 100
ITEM key1 [5 b; 1640000000 s]
ITEM key2 [8 b; 1640000100 s]
END
# Flush all data immediately
flush_all
OK
# Flush all data after 10 seconds
flush_all 10
OK
Client Libraries
Python (pymemcache)
#!/usr/bin/env python3
from pymemcache.client.hash import HashClient
# Create client
client = HashClient([
('localhost', 11211),
('localhost', 11212),
])
# Set value
client.set(b'key1', b'value1', expire=3600)
# Get value
result = client.get(b'key1')
print(result) # b'value1'
# Add (only if doesn't exist)
client.add(b'key2', b'value2', expire=3600)
# Replace (only if exists)
client.replace(b'key1', b'newvalue', expire=3600)
# Delete
client.delete(b'key1')
# Increment counter
client.incr(b'counter', 1)
# Decrement counter
client.decr(b'counter', 1)
# Get multiple keys
results = client.get_many([b'key1', b'key2', b'key3'])
# Append value
client.append(b'key1', b'_appended')
# Prepend value
client.prepend(b'key1', b'prepended_')
# Get stats
stats = client.stats()
# Flush all
client.flush_all()
# Close connection
client.close()
Java (Spymemcached)
import net.spy.memcached.MemcachedClient;
import java.net.InetSocketAddress;
import java.util.concurrent.Future;
public class MemcachedExample {
public static void main(String[] args) throws Exception {
// Create client
MemcachedClient mcc = new MemcachedClient(
new InetSocketAddress("localhost", 11211)
);
// Set value (expiry in seconds, 3600 = 1 hour)
mcc.set("key1", 3600, "value1");
// Get value
Object obj = mcc.get("key1");
System.out.println(obj);
// Asynchronous get
Future<Object> f = mcc.asyncGet("key1");
Object o = f.get();
System.out.println(o);
// Add (only if doesn't exist)
mcc.add("key2", 3600, "value2");
// Replace (only if exists)
mcc.replace("key1", 3600, "newvalue");
// Delete
mcc.delete("key1");
// Increment counter
mcc.incr("counter", 1);
// Decrement counter
mcc.decr("counter", 1);
// Flush all
mcc.flush();
// Shutdown
mcc.shutdown();
}
}
Node.js (node-memcached)
const Memcached = require('memcached');
// Create client
const memcached = new Memcached(['localhost:11211']);
// Set value (expiry in seconds)
memcached.set('key1', 'value1', 3600, (err) => {
if (err) console.error(err);
else console.log('Set successful');
});
// Get value
memcached.get('key1', (err, data) => {
if (err) console.error(err);
else console.log(data); // 'value1'
});
// Get multiple keys
memcached.getMulti(['key1', 'key2'], (err, data) => {
if (err) console.error(err);
else console.log(data);
});
// Add (only if doesn't exist)
memcached.add('key2', 'value2', 3600, (err) => {
if (err) console.error(err);
});
// Replace (only if exists)
memcached.replace('key1', 'newvalue', 3600, (err) => {
if (err) console.error(err);
});
// Delete
memcached.del('key1', (err) => {
if (err) console.error(err);
});
// Increment
memcached.incr('counter', 1, (err, value) => {
if (err) console.error(err);
else console.log(value);
});
// Decrement
memcached.decr('counter', 1, (err, value) => {
if (err) console.error(err);
else console.log(value);
});
// Flush all
memcached.flush((err) => {
if (err) console.error(err);
});
// Get stats
memcached.stats((err, stats) => {
if (err) console.error(err);
else console.log(stats);
});
// Close connection
memcached.end();
PHP (Memcached)
<?php
// Create client
$memcached = new Memcached();
$memcached->addServer('localhost', 11211);
// Set value (expiry in seconds)
$memcached->set('key1', 'value1', 3600);
// Get value
$value = $memcached->get('key1');
echo $value; // 'value1'
// Add (only if doesn't exist)
$memcached->add('key2', 'value2', 3600);
// Replace (only if exists)
$memcached->replace('key1', 'newvalue', 3600);
// Delete
$memcached->delete('key1');
// Get multiple keys
$values = $memcached->getMulti(['key1', 'key2', 'key3']);
// Increment
$memcached->increment('counter', 1);
// Decrement
$memcached->decrement('counter', 1);
// Flush all
$memcached->flush();
// Get stats
$stats = $memcached->getStats();
print_r($stats);
// Get server list
$servers = $memcached->getServerList();
print_r($servers);
// Get version
$version = $memcached->getVersion();
print_r($version);
?>
# Get server stats
memcached-tool localhost:11211 stats
# Get slab information
memcached-tool localhost:11211 stats slabs
# Get items per slab
memcached-tool localhost:11211 stats items
# Dump keys from slab
memcached-tool localhost:11211 dump 1 1000
# Full inspection
memcached-tool localhost:11211 inspect
nc (netcat) Commands
# Connect and send command
echo "stats" | nc localhost 11211
# Get stats
echo "stats" | nc localhost 11211 | head -20
# Flush all
echo "flush_all" | nc localhost 11211
# Set and get
echo -e "set mykey 0 3600 5\nhello" | nc localhost 11211
echo "get mykey" | nc localhost 11211
Startup Parameters
# Optimize for read-heavy workload
memcached -c 4096 -m 2048 -t 8 -d
# Optimize for write-heavy workload
memcached -c 8192 -m 4096 -t 16 -d -o hashpower=16
# Optimize for high concurrency
memcached -c 16384 -m 8192 -t 32 -d
# Parameters explained:
# -c: max concurrent connections (default: 1024)
# -m: maximum memory in MB (default: 64)
# -t: number of worker threads (default: 4)
# -o: misc options (hashpower, etc.)
Memory Management
# Monitor memory usage
echo "stats" | nc localhost 11211 | grep bytes
# Check memory fragmentation
echo "stats slabs" | nc localhost 11211 | grep waste
# Eviction policy details
echo "stats" | nc localhost 11211 | grep eviction
Monitoring
Basic Monitoring
# Real-time monitoring with watch
watch -n 1 'echo "stats" | nc localhost 11211'
# Monitor hit/miss ratio
watch -n 5 'echo "stats" | nc localhost 11211 | grep -E "get_hits|get_misses"'
# Monitor connections
watch -n 2 'echo "stats" | nc localhost 11211 | grep -E "curr_connections|total_connections"'
# Monitor memory
watch -n 2 'echo "stats" | nc localhost 11211 | grep -E "bytes|limit_maxbytes"'
Calculating Statistics
#!/bin/bash
# Calculate hit ratio
STATS=$(echo "stats" | nc localhost 11211)
HITS=$(echo "$STATS" | grep "get_hits" | awk '{print $3}')
MISSES=$(echo "$STATS" | grep "get_misses" | awk '{print $3}')
TOTAL=$((HITS + MISSES))
RATIO=$(echo "scale=2; $HITS * 100 / $TOTAL" | bc)
echo "Hit Ratio: $RATIO%"
Best Practices
- Set appropriate expiration times for cache items
- Use consistent key naming conventions
- Monitor hit/miss ratios to optimize cache effectiveness
- Configure adequate memory allocation based on expected data size
- Use connection pooling in client applications
- Implement proper error handling for cache misses
- Consider using consistent hashing for distributed caching
- Regularly monitor server statistics and performance metrics
- Use dedicated servers for memcached in production
- Implement redundancy for critical cache data
- Test cache behavior under load
- Document cache key schemas and TTL policies