Memcached ist ein leistungsstarkes In-Memory Key-Value-Store. Es beschleunigt Webanwendungen durch Caching von Datenbank-Abfragen, Sessions und berechneten Daten.
Warum Memcached?
Vorteile
- Extrem schnell (In-Memory)
- Einfaches Protokoll
- Horizontal skalierbar
- Bewährt (seit 2003)
- Geringer RessourcenverbrauchMemcached vs. Redis
| Feature | Memcached | Redis | |---------|-----------|-------| | Datentypen | Key-Value | Viele (Lists, Sets, etc.) | | Persistenz | Nein | Ja | | Replikation | Nein | Ja | | Komplexität | Einfach | Mittel | | Speichereffizienz | Besser | Gut | | Use Case | Caching | Caching + mehr |
Installation
Debian/Ubuntu
apt update
apt install memcached libmemcached-tools
# Status prüfen
systemctl status memcachedCentOS/RHEL
dnf install memcached
systemctl enable --now memcachedVersion prüfen
memcached -h | head -1Konfiguration
Hauptkonfiguration
# /etc/memcached.conf (Debian/Ubuntu)
# /etc/sysconfig/memcached (CentOS/RHEL)Wichtige Optionen
# /etc/memcached.conf
# Speicher (MB)
-m 256
# Port
-p 11211
# Benutzer
-u memcache
# Binding (nur lokal!)
-l 127.0.0.1
# Max. Verbindungen
-c 1024
# Verbose-Logging (für Debugging)
# -v
# Max. Item-Größe (Standard: 1MB)
-I 2mProduktions-Konfiguration
# /etc/memcached.conf
# Speicher großzügig bemessen
-m 512
# Nur lokal erreichbar
-l 127.0.0.1
# Standard-Port
-p 11211
# Mehr Verbindungen
-c 2048
# Als Daemon
-d
# Log-Datei
logfile /var/log/memcached.log
# Benutzer
-u memcache
# PID-Datei
-P /var/run/memcached/memcached.pid
# Größere Items erlauben
-I 4mÄnderungen übernehmen
systemctl restart memcachedGrundlegende Verwendung
telnet-Test
telnet localhost 11211# Wert setzen (set key flags exptime bytes)
set test 0 300 11
Hello World
STORED
# Wert abrufen
get test
VALUE test 0 11
Hello World
END
# Wert löschen
delete test
DELETED
# Statistiken
stats
stats items
stats slabs
# Beenden
quitmemcached-tool
# Statistiken anzeigen
memcached-tool localhost:11211 stats
# Slab-Verteilung
memcached-tool localhost:11211 display
# Dump aller Keys
memcached-tool localhost:11211 dumpPHP-Integration
PHP-Extension installieren
# Debian/Ubuntu
apt install php-memcached
# Oder php-memcache (ältere Extension)
apt install php-memcache
# PHP-FPM neu starten
systemctl restart php8.2-fpmEinfaches Beispiel
<?php
// Verbindung herstellen
$memcached = new Memcached();
$memcached->addServer('127.0.0.1', 11211);
// Wert setzen (Key, Value, Ablaufzeit in Sekunden)
$memcached->set('user_1', ['name' => 'Max', 'email' => 'max@example.com'], 3600);
// Wert abrufen
$user = $memcached->get('user_1');
if ($user !== false) {
echo "Name: " . $user['name'];
} else {
echo "Nicht im Cache";
}
// Wert löschen
$memcached->delete('user_1');
// Cache leeren
$memcached->flush();Cache-Aside Pattern
<?php
class DatabaseCache
{
private $memcached;
private $pdo;
private $ttl = 3600;
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
$this->memcached = new Memcached();
$this->memcached->addServer('127.0.0.1', 11211);
}
public function getUser(int $id): ?array
{
$cacheKey = "user_{$id}";
// Im Cache suchen
$user = $this->memcached->get($cacheKey);
if ($user !== false) {
return $user; // Cache-Hit
}
// Aus Datenbank laden
$stmt = $this->pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user) {
// In Cache speichern
$this->memcached->set($cacheKey, $user, $this->ttl);
}
return $user ?: null;
}
public function invalidateUser(int $id): void
{
$this->memcached->delete("user_{$id}");
}
}Session-Handler
// php.ini oder in Code
ini_set('session.save_handler', 'memcached');
ini_set('session.save_path', '127.0.0.1:11211');
session_start();
$_SESSION['user_id'] = 123;Python-Integration
Installation
pip install pymemcacheBeispiel
from pymemcache.client import base
# Verbindung
client = base.Client(('127.0.0.1', 11211))
# Setzen
client.set('key', 'value', expire=3600)
# Abrufen
result = client.get('key')
print(result.decode('utf-8')) # 'value'
# JSON speichern
import json
def json_serializer(key, value):
if isinstance(value, str):
return value, 1
return json.dumps(value), 2
def json_deserializer(key, value, flags):
if flags == 1:
return value.decode('utf-8')
if flags == 2:
return json.loads(value.decode('utf-8'))
return value
client = base.Client(
('127.0.0.1', 11211),
serializer=json_serializer,
deserializer=json_deserializer
)
client.set('user', {'name': 'Max', 'age': 30})
user = client.get('user')
print(user['name']) # 'Max'WordPress mit Memcached
Plugin installieren
cd /var/www/wordpress/wp-content
wget https://raw.githubusercontent.com/memcached/memcached/master/plugins/wordpress/object-cache.phpwp-config.php
// Memcached-Server definieren
$memcached_servers = array(
'default' => array(
'127.0.0.1:11211'
)
);Alternativ: W3 Total Cache
Plugins → W3 Total Cache → General Settings
→ Object Cache: Memcached
→ SaveLaravel mit Memcached
Konfiguration
// config/cache.php
'memcached' => [
'driver' => 'memcached',
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
'sasl' => [
env('MEMCACHED_USERNAME'),
env('MEMCACHED_PASSWORD'),
],
'options' => [
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
],
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],.env
CACHE_DRIVER=memcached
MEMCACHED_HOST=127.0.0.1Verwendung
// Cachen
Cache::put('key', 'value', $seconds);
// Abrufen
$value = Cache::get('key');
// Remember (abrufen oder berechnen)
$users = Cache::remember('users', 3600, function () {
return DB::table('users')->get();
});Verteiltes Caching
Mehrere Server
<?php
$memcached = new Memcached();
// Mehrere Server hinzufügen
$memcached->addServers([
['192.168.1.10', 11211, 33], // 33% Gewichtung
['192.168.1.11', 11211, 33],
['192.168.1.12', 11211, 34],
]);
// Konsistentes Hashing aktivieren
$memcached->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
$memcached->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);Netzwerk-Konfiguration
# /etc/memcached.conf
# Auf Netzwerk-Interface binden
-l 192.168.1.10
# ODER alle Interfaces (vorsichtig!)
# -l 0.0.0.0Firewall
# UFW
ufw allow from 192.168.1.0/24 to any port 11211Monitoring
Statistiken abfragen
echo "stats" | nc localhost 11211Wichtige Metriken:
STAT curr_items 12345 # Aktuelle Items
STAT bytes 123456789 # Speicherverbrauch
STAT get_hits 1000000 # Cache-Hits
STAT get_misses 50000 # Cache-Misses
STAT evictions 100 # Verdrängte ItemsHit Rate berechnen
Hit Rate = get_hits / (get_hits + get_misses) * 100Monitoring-Skript
#!/bin/bash
# memcached-stats.sh
STATS=$(echo "stats" | nc -w 1 localhost 11211)
HITS=$(echo "$STATS" | grep "get_hits" | awk '{print $3}')
MISSES=$(echo "$STATS" | grep "get_misses" | awk '{print $3}')
EVICTIONS=$(echo "$STATS" | grep "evictions" | awk '{print $3}')
if [ -n "$HITS" ] && [ -n "$MISSES" ]; then
TOTAL=$((HITS + MISSES))
if [ $TOTAL -gt 0 ]; then
HITRATE=$(echo "scale=2; $HITS * 100 / $TOTAL" | bc)
echo "Hit Rate: ${HITRATE}%"
fi
fi
echo "Evictions: $EVICTIONS"Prometheus-Exporter
# memcached_exporter installieren
docker run -d -p 9150:9150 \
prom/memcached-exporter \
--memcached.address=host.docker.internal:11211Sicherheit
Nur lokal binden
# /etc/memcached.conf
-l 127.0.0.1SASL-Authentifizierung
# /etc/memcached.conf
-S # SASL aktivieren# SASL-Benutzer erstellen
saslpasswd2 -a memcached -c usernameFirewall
# Nur von bestimmten IPs
iptables -A INPUT -p tcp --dport 11211 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 11211 -j DROPTroubleshooting
Verbindung testen
# Telnet
telnet localhost 11211
# Netcat
echo "stats" | nc localhost 11211
# PHP
php -r "var_dump((new Memcached())->addServer('127.0.0.1', 11211));"Service läuft nicht
systemctl status memcached
journalctl -u memcached
# Manuell starten (Debug)
memcached -u memcache -m 64 -p 11211 -l 127.0.0.1 -vvHohe Eviction-Rate
# Mehr Speicher zuweisen
# /etc/memcached.conf
-m 512 # 512 MB
# Oder größere Items erlauben
-I 4m # Max 4 MB pro ItemCache wird nicht genutzt
// Verbindung prüfen
$memcached = new Memcached();
$memcached->addServer('127.0.0.1', 11211);
var_dump($memcached->getStats());
// Array mit Statistiken = OK
// false/empty = ProblemZusammenfassung
| Befehl | Funktion | |--------|----------| | stats | Statistiken anzeigen | | set key 0 ttl bytes | Wert setzen | | get key | Wert abrufen | | delete key | Wert löschen | | flush_all | Cache leeren | | version | Version anzeigen |
| Metrik | Bedeutung | |--------|-----------| | get_hits | Cache-Treffer | | get_misses | Cache-Fehlschläge | | evictions | Verdrängte Items | | bytes | Speicherverbrauch |
Fazit
Memcached ist eine bewährte Caching-Lösung für Webanwendungen. Die einfache API und hohe Performance machen es ideal für Session-Storage und Datenbank-Caching. Für komplexere Anwendungsfälle mit Persistenz oder speziellen Datenstrukturen ist Redis die bessere Wahl. Achten Sie auf ausreichend Speicher und überwachen Sie die Hit-Rate für optimale Performance.