Zum Inhalt springen
Deutsch

Cached-Snapshot-Store

CachedSnapshotStore ist ein Decorator — wickle jeden SnapshotStore ein, um einen In-Process-LRU-Cache für Reads hinzuzufügen.

import {
CachedSnapshotStore,
ObjectStorageSnapshotStore,
PersistenceExtensionId,
} from 'actor-ts';
const underlying = new ObjectStorageSnapshotStore({
/* S3-Bucket-Config */
});
const cached = new CachedSnapshotStore({
underlying,
maxEntries: 1_000, // LRU-Größe
ttlMs: 60_000, // optionale TTL
});
system.extension(PersistenceExtensionId).configure({
journal: myJournal,
snapshotStore: cached,
});

Drei Muster:

  1. Langsamer zugrunde liegender Store — Object Storage mit Multi-Hop-Netzwerklatenz, verschlüsselter State mit teurer Entschlüsselung.
  2. Häufige Actor-Churn — Sharded Entities, die ständig passivieren / re-spawnen, jeder Load liest denselben Snapshot erneut.
  3. Recovery-Stürme — Cluster-weiter Neustart, jeder Actor lädt seinen Snapshot auf einmal. Der Cache reduziert redundante Loads, wenn derselbe Snapshot während des Sturms abgefragt wird.

Für lokale SQLite-gestützte Snapshots (Sub-Millisekunden-Reads) fügt der Cache Overhead ohne Nutzen hinzu. Verwende ihn nur, wenn der zugrunde liegende Store messbare Read-Latenz hat.

interface CachedSnapshotStoreSettings {
underlying: SnapshotStore;
maxEntries: number; // LRU-Kapazität
ttlMs?: number; // optionale Expiration
}
FeldWas
underlyingDer echte Snapshot-Store, dem der Cache vorgeschaltet ist.
maxEntriesMaximale gecachte Einträge. LRU-Eviction darüber hinaus.
ttlMsOptional — Cache-Einträge dieses Alters droppen. Nützlich, wenn Snapshots extern gelöscht werden können.
  • loadLatest(pid) — Cache prüfen; bei Hit zurückgeben. Bei Miss vom Underlying laden, das Ergebnis cachen, zurückgeben.
  • save(pid, snapshot) — durch zum Underlying schreiben, dann den Cache aktualisieren.
  • deleteUpTo(pid, seqNr) — durchschreiben, den Cache-Eintrag der pid invalidieren.

Der Cache ist konsistent mit Writes — ein Save gefolgt von loadLatest gibt den gerade gespeicherten Snapshot zurück, niemals einen veralteten Wert.

Für einen langsamen zugrunde liegenden Store (sagen wir 50 ms pro Load) verwandelt der Cache nachfolgende Loads desselben Snapshots in Sub-Mikrosekunden-Operationen. Eine typische Sharded-Entity-Workload sieht 80-95 % Hit-Rate nach Warm-up.

Der Cache selbst ist In-Process — kein geteilter Cache über Nodes. Für einen Cluster aus N Nodes hat jeder seinen eigenen Cache; Misses auf einem frischen Node zahlen die vollen Underlying-Load-Kosten.