Snapshot-Store-Backend
ObjectStorageSnapshotStore ist die Snapshot-Store-
Implementierung, die
Object Storage als
Backing-Schicht verwendet.
import { ObjectStorageSnapshotStore, S3ObjectStorageBackend, PersistenceExtensionId,} from 'actor-ts';
const snapshotStore = new ObjectStorageSnapshotStore({ backend: new S3ObjectStorageBackend({ region, bucket }), compression: { algorithm: 'gzip' }, encryption: { keyRing },});
system.extension(PersistenceExtensionId).configure({ journal: someJournal, snapshotStore,});Snapshots, die von jedem PersistentActor geschrieben werden,
gehen in den S3-Bucket; komprimiert + verschlüsselt gemäß der
Config.
Wann verwenden
Abschnitt betitelt „Wann verwenden“Drei Muster:
- Cluster-weit geteilte Snapshots — Sharded Entities, die zwischen Nodes wandern, brauchen, dass jeder Node den Snapshot jeder Entity laden kann. Object Storage funktioniert; SQLite pro Node nicht.
- Verschlüsselte Snapshots — Server-Side- und/oder Client-Side-Verschlüsselung at rest für Compliance erforderlich.
- Günstiger Snapshot-Storage — Object Storage ist pro GB viel günstiger als SQL-Stores für selten-gelesene-gelegentlich-überschriebene Daten.
Für Single-Node-Deployments ist SqliteSnapshotStore schneller + einfacher.
Konfiguration
Abschnitt betitelt „Konfiguration“interface ObjectStorageSnapshotStoreSettings { backend: ObjectStorageBackend; prefix?: string; // Default 'snapshots/' compression?: CompressionConfig; encryption?: EncryptionConfig;}| Feld | Zweck |
|---|---|
backend | Filesystem- oder S3-Backend. |
prefix | Object-Key-Prefix. Nützlich, um Buckets zu teilen. |
compression | At-Rest-Kompression — siehe Kompression. |
encryption | At-Rest-Verschlüsselung — siehe Verschlüsselung. |
Key-Layout
Abschnitt betitelt „Key-Layout“<prefix>/<persistenceId>/seq-<seqNr>Beispiele:
snapshots/account-42/seq-100snapshots/account-42/seq-200snapshots/account-42/seq-300Das Framework listet Keys unter <prefix>/<persistenceId>/, um
den neuesten Snapshot zu finden.
Für sehr große persistenceId-Räume ist das Listen pro pid in S3
typischerweise schnell (Per-Prefix-Durchsatz). Vermeide es, alle
Entity-Typen unter denselben Prefix ohne Per-pid-Unterordner zu
packen.
Performance
Abschnitt betitelt „Performance“Snapshot-Writes gehen durch das PUT von Object Storage; Reads durch GET. Zahlen für S3 Same-Region:
- Save — 20-50 ms pro Snapshot.
- Load latest — 1 LIST + 1 GET = 30-60 ms.
Für Hot-Path-Snapshot-Laden (häufige Actor-Neustarts) wickle es mit CachedSnapshotStore ein:
const cached = new CachedSnapshotStore({ underlying: new ObjectStorageSnapshotStore({ backend, ... }), maxEntries: 1_000,});Reduziert redundante S3-GETs auf Sub-Mikrosekunden-Cache-Hits.
Per-Actor-Overrides
Abschnitt betitelt „Per-Actor-Overrides“class Account extends PersistentActor<...> { protected compression() { return { algorithm: 'zstd' as const }; } protected encryption() { return { keyRing: accountKeyRing }; }}Per-Actor-Konfiguration gilt für Snapshots auf dieselbe Weise wie für Durable State. Siehe Per-Actor-Policies.
Snapshot-Lifecycle
Abschnitt betitelt „Snapshot-Lifecycle“PersistentActor.persist(event) gelingt ↓ snapshotPolicy() prüfen ↓ wenn true → Snapshot machenbackend.put('snapshots/<pid>/seq-N', serialisierter State)
PersistentActor.preStart ↓ 'snapshots/<pid>/' auflisten, um die neueste seq zu finden ↓ backend.get(latest) → dekodieren → onEvent ab seq+1Das Framework handhabt Snapshot-Saves + -Loads über dieses Layout; du setzt die Policy.
Cleanup alter Snapshots
Abschnitt betitelt „Cleanup alter Snapshots“new ObjectStorageSnapshotStore({ backend, maxSnapshotsPerPid: 5, // die 5 neuesten behalten; ältere löschen});Ohne Cleanup akkumulieren alte Snapshots unbegrenzt.
maxSnapshotsPerPid zu konfigurieren triggert einen Cleanup-Pass
bei jedem Save — nur die N neuesten werden behalten.
Das Framework löscht beim Lesen nicht automatisch — es gibt ein kleines Fenster, in dem alte Snapshots mit neuen koexistieren.
Mischen mit dem Journal
Abschnitt betitelt „Mischen mit dem Journal“{ journal: new SqliteJournal({ path: '...' }), snapshotStore: new ObjectStorageSnapshotStore({ backend }),}Das Journal und der Snapshot-Store sind unabhängig. Häufige Muster:
- SQLite-Journal + ObjectStorage-Snapshots — lokale Event-Rate, geteilte Snapshots für Sharded Entities.
- Cassandra-Journal + ObjectStorage-Snapshots — beide über den Cluster geteilt.
- ObjectStorage alles — wenn S3 dein einziger Storage ist. Langsamer pro Op, aber billig.
Wie geht’s weiter
Abschnitt betitelt „Wie geht’s weiter“- Object Storage im Überblick — das größere Bild.
- Snapshot Stores im Überblick — allgemeine Snapshot-Policy.
- CachedSnapshotStore — Read-Through-Cache.
- Per-Actor-Policies — Per-Actor-Kompression / -Verschlüsselung.