Einleitung
- Umsetzung Replikation / Partitionierung in Cassandra
- Architektur: Ring, Gossip, Konsistenzlevel
- Write/Read Path, Compaction, Tombstones
Ring-Architektur
- Consistent Hashing: Token-Ring verteilt Daten auf Nodes
- Jeder Node übernimmt einen Token-Bereich im Ring
- Peer-to-Peer: kein Master, jeder Node gleichwertig
- Client kann jeden Node als Koordinator kontaktieren
- Koordinator leitet Anfragen an die zuständigen Nodes weiter
Virtuelle Nodes (Vnodes)
- Jeder physische Node besitzt mehrere Token-Bereiche (Vnodes)
- Gleichmäßigere Lastverteilung
- Einfacheres Hinzufügen / Entfernen von Nodes
Gossip-Protokoll
- Dezentrales Kommunikationsprotokoll zur Cluster-Koordination
- Jeder Node tauscht periodisch (1 s) Zustandsinformationen mit 1–3 Peers aus
- Informationen verbreiten sich exponentiell schnell im Cluster
Inhalte
- Node-Discovery: neue Nodes werden automatisch bekannt
- Failure Detection: Phi-Accrual-Algorithmus erkennt ausgefallene Nodes
- Cluster State: Token-Bereiche, Rack/Datacenter-Zugehörigkeit, Schema-Version
Replikation
- Replikationsfaktor (RF): Anzahl Kopien jedes Datensatzes
- Koordinator schreibt auf RF Nodes (Replicas)
- Replicas werden durch Token-Ring bestimmt (nächste Nodes im Ring)
Strategien
- SimpleStrategy: nächste RF Nodes im Ring, für Single-DC
- NetworkTopologyStrategy: RF pro Datacenter, Rack-Awareness
Hinted Handoff
- Koordinator speichert Write temporär, wenn Replica nicht erreichbar
- Übertragung erfolgt, sobald der Replica-Node wieder online ist
Konsistenzlevel
Konfigurierbar pro Anfrage (Tunable Consistency)
- ONE: Antwort von 1 Replica genügt (niedrige Latenz, schwache Konsistenz)
- QUORUM: Mehrheit (RF/2 + 1) muss antworten
- ALL: alle Replicas müssen antworten (starke Konsistenz, hohe Latenz)
- LOCAL_QUORUM: Quorum nur im lokalen Datacenter
Starke Konsistenz durch Tuning
- Formel: W + R > RF → starke Konsistenz garantiert
- Beispiel RF = 3: QUORUM Write + QUORUM Read → 2 + 2 > 3 ✓
- Tradeoff: höhere Konsistenz = höhere Latenz = niedrigere Verfügbarkeit
-- Konsistenzlevel in cqlsh setzen
CONSISTENCY QUORUM;
SELECT * FROM messwerte
WHERE sensor_id = 's-001';
Write Path
- 1. CommitLog: Write wird sequenziell auf Disk geschrieben (Crash-Recovery)
- 2. Memtable: Write wird in speicherresidenter Struktur gespeichert
- 3. SSTable: Memtable wird bei Überschreitung eines Schwellwerts auf Disk gespült (Flush)
Eigenschaften
- Alle Schreiboperationen sind append-only und sequenziell → sehr schnell
- Kein direktes Überschreiben von Daten auf Disk
- Updates erzeugen neue Versionen (Timestamp-basiert)
- Deletes schreiben Tombstones (Löschmarkierungen)
Read Path
- 1. Memtable: zuerst wird der aktuelle In-Memory-Puffer geprüft
- 2. Bloom Filter: probabilistische Struktur – prüft, ob Daten in einer SSTable liegen könnten
- 3. Key Cache: speichert Positionen von Partition Keys in SSTables
- 4. SSTable Merge: Daten aus mehreren SSTables werden zusammengeführt
Merge-Strategie
- Neueste Version gewinnt (Timestamp)
- Tombstones überschreiben ältere Werte
Compaction
- SSTables akkumulieren sich über Zeit → Compaction führt sie zusammen
- Entfernt veraltete Versionen und abgelaufene Tombstones
- Reduziert Anzahl der SSTables → schnellere Reads
Strategien
- STCS (Size-Tiered): ähnlich große SSTables werden gemergt, Standard, gut für Writes
- LCS (Leveled): mehrere Level, begrenzte SSTable-Größe, gut für Reads
- TWCS (Time-Window): für Zeitreihendaten, kompaktiert nach Zeitfenstern
Tombstones
- Cassandra überschreibt Daten nie direkt – Deletes schreiben einen Tombstone
- Tombstone = Markierung mit Timestamp, dass Daten gelöscht wurden
- Replicas, die offline waren, erhalten Tombstone beim nächsten Sync
gc_grace_seconds
- Tombstones werden erst nach
gc_grace_seconds (Standard: 10 Tage) endgültig entfernt
- Verhindert, dass gelöschte Daten auf Replicas wieder auftauchen
Problem: zu viele Tombstones
- Reads müssen viele Tombstones überspringen → Latenzprobleme
- Lösungen: TTL statt manuelles Löschen, TWCS, richtiges Partitionierungsschema
-- TTL beim Schreiben setzen
INSERT INTO messwerte
(sensor_id, zeitpunkt, temperatur)
VALUES
('s-001', toTimestamp(now()), 23.5)
USING TTL 86400; -- 1 Tag in Sekunden
-- TTL pro Tabelle konfigurieren
CREATE TABLE logs (
id UUID,
ts TIMESTAMP,
msg TEXT,
PRIMARY KEY (id, ts)
) WITH default_time_to_live = 604800;
-- 7 Tage