Zum Inhalt springen
Deutsch

Memcached-Cache

MemcachedCache ist die Memcached-gestützte Cache- Implementierung. Verteilter Cache über Pods, geteilt über Prozesse hinweg.

import { MemcachedCache, MemcachedCacheOptions } from 'actor-ts/cache';
const memcachedCacheOptions = MemcachedCacheOptions.create().withServers('memcached-1:11211,memcached-2:11211');
const cache = new MemcachedCache(
memcachedCacheOptions,
);

Zwei Hauptgründe:

  1. Bestehende Memcached-Infrastruktur — dein Team betreibt es bereits.
  2. Reiner Cache-Anwendungsfall — du brauchst Redis’ Extra- Features nicht (Persistenz, Pub/Sub, Scripting, Sorted Sets).

Memcached ist einfacher als Redis — weniger Features, geringerer operativer Footprint, geringerer Speicher-Overhead. Für pures Key-Value-Caching mit TTLs reicht das voll.

type MemcachedCacheOptionsType = {
servers?: string; // kommagetrennt, Default 'localhost:11211'
username?: string;
password?: string;
keyPrefix?: string; // serverseitig, auf jede Operation angewendet
client?: MemcachedClientLike; // vorgefertigter memjs-Client
};

memjs (der zugrunde liegende Client) unterstützt SASL-Auth über username/password. Mehrere Server werden über Hashing verteilt.

Terminal-Fenster
npm install memjs
# oder: bun add memjs
Cache-MethodeMemcached-Implementierung
get/set/deleteDirekte Memcached-Befehle.
incrKombination aus Memcached INCR/ADD.
setIfAbsentMemcached ADD (atomar).
mget/msetParallele Single-Key-Operationen.

mget/mset sind auf Memcached nicht Single-Round-Trip (keine Multi-Key-Befehle). Das Framework parallelisiert die einzelnen Operationen.

AspektMemcachedRedis
Speicher-Overhead pro EintragNiedrigerHöher
Multi-Key-OperationenLangsamer (parallele Single-Key)Schneller (MGET, MSET)
PersistenzKeineRDB / AOF verfügbar
Pub/SubNeinJa
DatentypenNur StringsStrings, Listen, Sets, Hashes, Sorted Sets
Cluster-SupportClientseitiges HashingEingebautes Clustering
ReplikationKeine (oder über Sidecars)Eingebaute Replikation

Für puren Cache: beides funktioniert. Redis gewinnt bei fast allem anderen, was das Framework wollen könnte. Memcached gewinnt bei minimalem operativen Footprint, wenn Caching der einzige Bedarf ist.

// Memcached konfiguriert mit --memory-limit=2048 (MB)
// → LRU-Eviction, sobald voll

Memcacheds Eviction ist LRU, konfiguriert auf der Memcached- Serverebene (nicht vom Cache-Client). Keine clientseitige Eviction-Policy.

Für einen Cache fester Größe ist das okay — Memcached wirft alte Einträge raus, um Platz zu schaffen.

Für alles, was eine Garantie trägt, ist es das nicht. InMemoryCache evictet Einträge ohne Garantie, bevor er ein Lock, einen Rate-Limit-Zähler oder einen Idempotency-Record anfasst; hier gibt es dazu kein Gegenstück, denn die Entscheidung fällt im Server und der Client wird nicht gefragt. Ein von setIfAbsent geschriebener Eintrag kann also mit dem größten Teil seiner TTL verschwinden — ein zweimal vergebenes Lock, ein zurückgesetztes Limit, ein Retry, der seinen Handler erneut ausführt — und nichts in der API meldet es. Dimensioniere die Memcached-Instanz für die Garantien, die sie hält, halte sie von einem Key-Raum fern, den Aufrufer aufzählen können, und siehe was Eviction schützt und was nicht für die Grundlage der Garantie. Das ist unabhängig von der Topologie-Gefahr weiter unten: die braucht einen Server, der dazu- oder wegkommt, diese hier nur Speicherdruck.

memjs hält seinen eigenen Connection-Pool; das Framework verwaltet ihn nicht direkt. Tune über memjs-Optionen, falls nötig (meist sind die Defaults okay).