1 poin oleh GN⁺ 2025-12-09 | Belum ada komentar. | Bagikan ke WhatsApp
  • Jepsen memverifikasi durabilitas dan konsistensi sistem messaging terdistribusi NATS JetStream dalam berbagai kondisi gangguan
  • Hasil pengujian menunjukkan kehilangan data dan fenomena split-brain pada kerusakan file (.blk, snapshot) serta simulasi kegagalan daya
  • Secara default JetStream menjalankan fsync setiap 2 menit, sehingga pesan yang baru saja diakui bisa tetap belum tertulis ke disk
  • Crash OS pada satu node saja dapat memicu kehilangan data dan ketidaksesuaian replika
  • Jepsen merekomendasikan agar NATS mengubah default ke fsync=always atau mendokumentasikan risiko kehilangan data secara eksplisit

1. Latar belakang

  • NATS adalah sistem streaming populer untuk memublikasikan dan berlangganan pesan sebagai stream
    • JetStream menggunakan algoritma konsensus Raft untuk mereplikasi data dan menjamin pengiriman minimal satu kali (at-least-once)
  • Dalam dokumentasi, JetStream mengklaim konsistensi linearizable dan selalu tersedia, tetapi menurut teorema CAP kedua kondisi itu tidak dapat dipenuhi secara bersamaan
  • Menurut dokumentasi NATS, stream 3 node dapat menoleransi hilangnya 1 server, dan stream 5 node dapat menoleransi hilangnya 2 server
  • Pesan dianggap “berhasil disimpan” pada saat server mengakui permintaan publish
  • Untuk konsistensi data dibutuhkan mayoritas (quorum) node; pada klaster 5 node, minimal 3 harus berjalan agar pesan baru bisa disimpan

2. Desain pengujian

  • Jepsen melakukan pengujian dengan klien JNATS 2.24.0 dan lingkungan kontainer Debian 12 LXC
    • Sebagian pengujian menggunakan image Docker resmi NATS di lingkungan Antithesis
  • Satu stream JetStream tunggal dikonfigurasi (replikasi 5), lalu disuntikkan gangguan seperti penghentian proses, crash, partisi jaringan, packet loss, dan kerusakan file
  • Menggunakan filesystem LazyFS untuk mensimulasikan kegagalan daya yang menyebabkan hilangnya write yang belum di-fsync
  • Setiap proses memublikasikan pesan unik, lalu setelah pengujian selesai diverifikasi di semua node apakah pesan yang sudah diakui benar-benar ada
  • Jika pesan hanya ada pada sebagian node, kasus itu diklasifikasikan sebagai divergence (ketidaksesuaian replikasi)

3. Hasil utama

3.1 Kehilangan seluruh data pada NATS 2.10.22 (#6888)

  • Ditemukan fenomena seluruh stream JetStream hilang hanya karena crash proses sederhana
  • Setelah muncul error "No matching streams for subject", pemulihan tidak terjadi selama berjam-jam
  • Penyebabnya meliputi pembalikan snapshot leader, penghapusan status Raft, dan lain-lain, lalu diperbaiki pada versi 2.10.23

3.2 Kehilangan data saat file .blk rusak (#7549)

  • Jika file .blk JetStream mengalami error satu bit atau pemotongan (truncation), dapat terjadi kehilangan ratusan ribu write yang sudah diakui
    • Contoh: dari 1.367.069 kasus, 679.153 hilang
  • Bahkan jika hanya sebagian node yang rusak, dapat terjadi kehilangan data skala besar dan split-brain
    • Contoh: pada node n1, n3, n5, kehilangan pesan mencapai 78%
  • NATS sedang menyelidiki masalah tersebut

3.3 Penghapusan seluruh data saat file snapshot rusak (#7556)

  • Jika file snapshot dalam data/jetstream/$SYS/_js_/ rusak, node menilai stream sebagai orphaned lalu menghapus seluruh data
  • Meski hanya sedikit node yang rusak, hal itu dapat membuat mayoritas klaster tidak tercapai dan stream tidak tersedia secara permanen
  • Contoh: node n3, n5 rusak → n3 terpilih sebagai leader lalu menghapus seluruh jepsen-stream
  • Jepsen menyoroti risiko node yang rusak menjadi leader saat pemilihan leader

3.4 Kehilangan data karena konfigurasi default fsync (#7564)

  • Secara default JetStream hanya menjalankan fsync setiap 2 menit, sementara pesan langsung diakui
    • Akibatnya, pesan yang baru saja diakui bisa masih belum tertulis ke disk
  • Saat terjadi kegagalan daya atau crash kernel, pesan yang sudah diakui selama puluhan detik bisa hilang
    • Contoh: dari 930.005 kasus, 131.418 hilang
  • Bahkan kegagalan pada satu node yang terjadi berurutan dapat menyebabkan seluruh stream terhapus
  • Perilaku ini nyaris tidak disebutkan dalam dokumentasi
  • Jepsen merekomendasikan mengubah default ke fsync=always atau menambahkan peringatan eksplisit tentang risiko kehilangan data

3.5 Split-brain akibat satu crash OS (#7567)

  • Hanya dengan kegagalan daya atau crash kernel pada satu node saja, tetap dapat terjadi kehilangan data dan ketidaksesuaian replikasi
  • Dalam struktur leader-follower, jika sebagian node sudah mengakui write yang baru ter-commit di memori lalu terjadi gangguan,
    mayoritas node dapat kehilangan write tersebut dan melanjutkan dengan status baru
  • Dalam pengujian, satu kegagalan daya memicu split-brain yang persisten
    • Terlihat bahwa tiap node kehilangan rentang pesan yang sudah diakui namun berbeda-beda
  • Jepsen mengutip kasus serupa pada Kafka dan menekankan bahwa risiko yang sama juga ada pada sistem berbasis Raft

4. Diskusi dan kesimpulan

  • Masalah kehilangan seluruh data pada 2.10.22 telah diselesaikan di 2.10.23
  • Pada 2.12.1, kehilangan data dan split-brain akibat kerusakan file dan crash OS masih tetap terjadi
  • Saat file .blk dan snapshot rusak, dapat terjadi pesan hilang pada sebagian node atau penghapusan seluruh stream
  • Karena interval default fsync panjang, ada risiko kehilangan data yang sudah diakui saat beberapa node gagal bersamaan
  • Jepsen mengusulkan penggunaan fsync=always atau pemberitahuan risiko yang jelas dalam dokumentasi
  • Klaim JetStream sebagai sistem yang “selalu tersedia” mustahil menurut teorema CAP, sehingga dokumentasi perlu diperbaiki
  • Jepsen menegaskan bahwa keberadaan bug bisa dibuktikan, tetapi ketiadaan masalah keamanan tidak bisa dibuktikan

4.1 Peran LazyFS

  • LazyFS digunakan untuk mensimulasikan hilangnya write yang belum di-fsync
  • Saat kegagalan daya, berbagai error storage seperti kerusakan write parsial (torn write) juga dapat direproduksi
  • Dalam riset terkait When Amnesia Strikes (VLDB 2024), bug serupa juga dilaporkan pada PostgreSQL, Redis, ZooKeeper, dan lainnya

4.2 Tugas ke depan

  • Verifikasi kehilangan pesan pada level konsumer tunggal, urutan pesan, serta jaminan Linearizable/Serializable belum dilakukan
  • Jaminan pengiriman tepat satu kali (exactly-once) juga menjadi topik riset berikutnya
  • Saat menambah atau menghapus node, ditemukan kesalahan dokumentasi dan langkah health check wajib yang hilang (#7545)
  • Prosedur aman untuk perubahan konfigurasi klaster masih belum jelas

Belum ada komentar.

Belum ada komentar.