Episode ini membahas siklus hidup savepoint dan kompatibilitas versi, cara melakukan job upgrades dan migrasi state, strategi rollback dan recovery drills, serta menguji restore savepoint di environment staging.

Mengubah job yang sedang berjalan adalah momen paling menegangkan bagi seorang data engineer: satu kesalahan dan state hilang, agregasi keliru, atau data terduplikasi. Episode 16 ini menghilangkan ketegangan itu. Savepoint adalah alat kalian untuk meng-upgrade, migrasi, dan rollback job tanpa kehilangan state.
Kita akan membedah siklus hidup savepoint, kompatibilitas antar versi Flink, cara melakukan job upgrades dengan perubahan kode, strategi rollback, serta praktik menguji restore di staging. Di akhir episode, kalian bisa mengganti versi job produksi dengan percaya diri.
Savepoint dibuat secara manual dan bisa dikelola lewat CLI:
./bin/flink savepoint <jobId> /tmp/savepoints
./bin/flink list -s
./bin/flink savepoint -d /tmp/savepoints/savepoint-<id>./bin/flink savepoint mengambil snapshot state, ./bin/flink list -s mendaftar semua savepoint yang dikenali cluster, dan ./bin/flink savepoint -d menghapus yang tidak diperlukan lagi. Simpan savepoint di lokasi yang tahan lama — di produksi biasanya object storage.
Savepoint adalah snapshot sadar yang dibuat untuk upgrade dan migrasi, sedangkan checkpoint adalah snapshot otomatis untuk recovery setelah kegagalan. Karena dibuat manual dan disimpan lama, savepoint menjadi titik rollback yang andal — sekaligus artefak yang harus dijaga dengan baik.
Flink menjamin kompatibilitas savepoint untuk versi yang masih dalam rentang dukungan. Prinsip penting:
state.savepoints.dir: s3://flink-state/savepointsstate.savepoints.dir menetapkan direktori default agar seluruh job memakai lokasi yang konsisten dan tahan lama.
Saat kode berubah — misalnya menambah field ke ValueState — Flink mencoba melakukan migrasi otomatis. Jika perubahan tidak kompatibel (misalnya mengganti tipe data), restore akan gagal dengan exception. Solusinya: gunakan jenis state yang toleran perubahan (MapState), atau lakukan migrasi dua tahap dengan job perantara.
Agar state terhubung dengan benar setelah kode berubah, beri setiap operator stateful uid yang stabil:
source
.map(new ParseOrder()).uid("parse-order")
.keyBy(Order::getUserId)
.process(new Aggregator()).uid("aggregate")
.sinkTo(sink);.uid("aggregate") memberi nama permanen pada operator. Tanpa uid, Flink mengandalkan urutan operator yang bisa berubah setelah refactor — state bisa tertukar. uid adalah kebiasaan yang wajib untuk semua job yang mungkin di-upgrade.
./bin/flink savepoint <jobId> /tmp/savepoints
./bin/flink run -d -s /tmp/savepoints/savepoint-<id> target/app-v2.jarLangkahnya: buat savepoint dari versi lama, lalu jalankan JAR baru dengan flag -s menunjuk savepoint itu. Setelah verifikasi bahwa job v2 berjalan benar, baru cancel job v1. Urutan ini memastikan tidak ada downtime pemrosesan.
Jika upgrade gagal, kembalikan dari savepoint terakhir yang sehat:
./bin/flink run -d -s /tmp/savepoints/savepoint-<sehat> target/app-v1.jarPraktik ini hanya berhasil jika savepoint diambil sebelum perubahan. Karena itu, jadikan "savepoint sebelum upgrade" sebagai aturan wajib, bukan opsional.
Jangan menunggu insiden untuk menguji recovery. Lakukan drill terjadwal di staging:
./bin/taskmanager.sh stop
./bin/flink list -a./bin/taskmanager.sh stop mematikan satu TaskManager untuk menguji pemulihan. Jika job restart otomatis dan state kembali utuh, mekanisme fault tolerance kalian bekerja.
Setiap upgrade wajib diuji di staging dengan skenario: restore dari savepoint yang dibuat di produksi, lalu bandingkan metrik (misalnya total agregat) antara sebelum dan sesudah. Perbedaan angka berarti migrasi state bermasalah — temukan sebelum menimpa produksi.
uid stabil.Episode 16 menjadikan upgrade sebagai prosedur yang tenang: memahami siklus hidup savepoint, menghormati kompatibilitas versi, menjaga identity operator dengan uid, menerapkan alur upgrade dan rollback yang teruji, serta melakukan recovery drills di staging.
Inti yang harus dibawa pulang:
uid yang stabil menghubungkan state dengan benar setelah kode berubah.Di episode 17 selanjutnya kita akan membahas advanced streaming patterns — stateful joins, stream-stream joins, dan temporal joins, hopping windows dan sessionization, iterative streaming dengan feedback loops, serta hybrid batch dan stream processing. Di sinilah teknik-teknik canggih Flink dipertemukan.