Cost
Mittleres LevelWie senke ich die Kosten meines Flink-Clusters, ohne das Checkpointing zu brechen?
Die Rechnung schnellt nicht wegen eines einzelnen schlechten Jobs in die Höhe — sie kriecht durch ein paar Einstellungen nach oben, die einmal beim Rollout festgelegt und nie wieder überprüft wurden. Hier lohnt sich der erste Blick.
Die Rechnung für einen Flink-Cluster verhält sich anders als die für einen Batch-Job — Sie zahlen für TaskManager, die laufen, egal ob Backpressure herrscht oder nicht, und für Checkpoints, die nach einem Timer auslösen, egal wie viel sich tatsächlich geändert hat. Das macht es weniger zu einem Problem eines einzelnen schlechten Jobs und mehr zu einer Frage von Einstellungen, die seit dem Launch niemand mehr angefasst hat.
1. Das Checkpoint-Intervall ist der Kostenhebel, den niemand überprüft
Jeder Checkpoint bedeutet einen vollständigen Durchlauf durch das State-Backend — bei RocksDB heißt das Disk-I/O plus, bei einem Cloud-Deployment, eine Reihe von PUT-Requests an den Object Store, der state.checkpoints.dir hält. Ein Intervall, das beim initialen Rollout konservativ kurz eingestellt wurde, als niemand den Fortschritt eines unerprobten Jobs riskieren wollte, zahlt diese Kosten unbegrenzt weiter, auch wenn der Job seit Monaten stabil läuft. Eine Vergrößerung von execution.checkpointing.interval senkt diese wiederkehrenden Kosten direkt — der Trade-off sind mehr Daten, die beim nächsten Ausfall neu verarbeitet werden müssen, weshalb es sich lohnt, sich an der tatsächlich akzeptablen Recovery-Zeit zu orientieren, nicht nur daran, wie kurz die Zahl sicher sein kann.
2. Parallelismus für den schlechtesten Tag ausgelegt, jeden Tag bezahlt
Die Anzahl der TaskManager-Slots wird meist einmal festgelegt, anhand einer Schätzung der Spitzenlast, und dann nie wieder angefasst — sodass der Traffic im stationären Zustand für Kapazität bezahlt, die er die meiste Zeit gar nicht nutzt. Reactive Mode oder ein Autoscaler auf Plattformebene können diese Lücke automatisch schließen; auch ohne das reicht ein Vergleich von Backpressure pro Subtask mit den bereitgestellten Slots, um den offensichtlichen Fall zu erkennen: Parallelismus, ausgelegt auf einen Spitzenwert, der zweimal im Jahr vorkommt, aber jeden Tag dazwischen zum vollen Preis läuft.
3. Unbegrenztes State-Wachstum bläht Checkpoints unbemerkt auf
Keyed State, für den nie eine TTL gesetzt wurde, wächst, solange der Job läuft, und jeder Checkpoint muss ihn vollständig serialisieren — sodass Checkpoint-Dauer und Speicherbedarf über Monate hinweg langsam ansteigen, ohne dass ein einzelnes Deployment dafür verantwortlich wäre. Nichts bricht, und genau deshalb bleibt es unbemerkt. Eine TTL zu setzen, die dem tatsächlichen Bedarf der Business-Logik entspricht, ist meist ein größerer Gewinn, als es aussieht — gerade weil damit eine langsame Drift korrigiert wird, nicht ein einzelner falscher Wert.
4. Nicht jeder TaskManager ist ein sicherer Kandidat für Spot
Ob ein TaskManager auf Spot-Kapazität laufen kann, hängt davon ab, was er hält: Ein Job, der sauber aus seinem letzten Checkpoint wiederherstellt, mit genug Recovery-Zeit-Toleranz, um eine Präemption zu überstehen, ist ein guter Kandidat — dasselbe Recovery-Zeit-Budget wie bei Hebel Nummer eins. Ein Job mit großem Keyed State, dessen Wiederaufbau von Grund auf Minuten dauert, ist ein schlechterer Kandidat, da eine Präemption dort mehr kostet, als die Rechenleistung eingespart hätte.
Was opti-pipe aus einem Flink-Metrics-Export liest: Checkpoint-Dauer, Checkpoint-Größe und Backpressure pro Subtask — niemals die Business-Logik Ihres Job-Graphen — um zu zeigen, welcher dieser vier Hebel sich in Ihrem konkreten Deployment tatsächlich lohnt, mit einer konkreten Zahl statt einer Faustregel.
Sehen Sie, wie das bei Ihrer eigenen Pipeline aussieht.
Laden Sie ein echtes Spark-Event-Log, ein dbt run_results.json oder einen Flink-Metrics-Export hoch und erhalten Sie konkrete, vor der Anwendung zu genehmigende Empfehlungen zurück — keine weitere Faustregel.