- NATS JetStream dağıtık mesajlaşma sisteminin dayanıklılığını ve tutarlılığını Jepsen, çeşitli arıza senaryolarında doğruladı
- Testlerde dosya bozulması (.blk, snapshot) ve güç kesintisi simülasyonu sırasında hem veri kaybı hem de split-brain durumu meydana geldi
- JetStream varsayılan olarak
fsync işlemini her 2 dakikada bir yaptığından, en son onaylanan mesajların diske yazılmamış halde kalması mümkündür
- Tek bir düğümdeki OS çökmesi bile veri kaybı ve replikasyon tutarsızlığına yol açabilir
- Jepsen, NATS için varsayılan ayarın
fsync=always olarak değiştirilmesini veya veri kaybı riskinin açık bir şekilde belgelenmesini öneriyor
1. Arka Plan
- NATS, mesajları stream olarak yayımlayıp abone olunan popüler bir streaming sistemidir
- JetStream, verileri çoğaltmak için Raft mutabakat algoritmasını kullanır ve en az bir kez (at-least-once) teslimat garantisi sağlar
- JetStream, belgelerinde linearizable tutarlılık ve her zaman kullanılabilirlik iddiası taşısa da, CAP teoremi gereği bu ikisi aynı anda sağlanamaz
- NATS belgelerine göre 3 düğümlü streamler 1, 5 düğümlü streamler ise 2 sunucu kaybına dayanabilir
- Mesajlar, sunucunun
publish isteğini acknowledge ettiği anda “başarıyla kaydedildi” sayılır
- Verinin tutarlı olması için quorum (çoğunluk) düğüm sayısı gerekir ve 5 düğümlü bir kümede yeni bir mesajın kaydedilmesi için en az 3 düğümün aktif olması gerekir
2. Test Tasarımı
- Jepsen, JNATS 2.24.0 istemcisi ve Debian 12 LXC container ortamında testler gerçekleştirdi
- Bazı testlerde Antithesis ortamında resmi NATS Docker image kullanıldı
- Tek bir JetStream stream (replica 5) kuruldu ve süreç durdurma, çökme, ağ bölünmesi, paket kaybı, dosya bozulması gibi arızalar enjekte edildi
fsync edilmemiş yazıların kaybolmasını canlandırmak için LazyFS dosya sistemiyle güç kesintisi simülasyonu yapıldı
- Her süreç benzersiz mesajlar yayımladı ve test bittikten sonra tüm düğümlerde onaylanan mesajların varlığı doğrulandı
- Bir mesajın yalnızca bazı düğümlerde bulunması durumunda divergence (replica tutarsızlığı) olarak sınıflandırıldı
3. Temel Bulgular
3.1 NATS 2.10.22'de Tüm Veri Kaybı (#6888)
- Yalnızca basit bir süreç çökmesiyle JetStream streaminin tümünün kaybolduğu durum tespit edildi
"No matching streams for subject" hatası oluştu ve saatlerce düzeltilmedi
- Nedeni lider snapshot ters yönlendirmesi, Raft durumunun silinmesi vb olarak bulundu ve 2.10.23 sürümünde düzeltildi
3.2 .blk Dosya Bozulmasında Veri Kaybı (#7549)
- JetStream'in
.blk dosyasında tek bit hatası veya truncation (kırpma) oluştuğunda yüz binlerce onaylı yazma kayboldu
- Örn: 1,367,069 üzerinden 679,153 kayıp
- Sadece bazı düğümler bozulsa bile büyük ölçekte veri kaybı ve split-brain görüldü
- Örn:
n1, n3, n5 düğümlerinde en fazla %78 mesaj kaybı
- NATS, bu konuyu inceleme aşamasında
3.3 Snapshot Dosyası Bozulduğunda Tüm Verinin Silinmesi (#7556)
data/jetstream/$SYS/_js_/ içindeki snapshot dosyası bozulduğunda, düğüm streami orphaned (sahipsiz) kabul edip tüm veriyi siliyor
- Sadece birkaç düğüm bozulsa bile küme çoğunluğuna ulaşılamaması ve streamin kalıcı olarak kullanılamaz hale gelmesi oluşuyor
- Örn:
n3, n5 bozulduğunda → n3 lider seçildi ve jepsen-stream tamamen silindi
- Jepsen, lider seçiminde bozulmuş bir düğümün lider olma riskini vurguluyor
3.4 Varsayılan fsync Ayarından Kaynaklanan Veri Kaybı (#7564)
- JetStream varsayılan olarak yalnızca 2 dakikada bir
fsync çalıştırır ve mesajları anında onaylar
- Böylece en yeni onaylı mesajlar diske yazılmamış kalabilir
- Güç kesintisi veya kernel çökmesi durumunda onlarca saniyelik onaylı mesaj kaybı görülür
- Örn: 930,005 üzerinden 131,418 kayıp
- Tekil düğüm arızası ardışık şekilde olsa bile tüm streamin silinmesi mümkündür
- Bu davranış belgelerde neredeyse hiç yer almıyor
- Jepsen,
fsync=always varsayılanının değiştirilmesini veya veri kaybı riskine ilişkin açık uyarı verilmesini tavsiye ediyor
3.5 Tek Bir OS Çökmesi Nedeniyle Oluşan Split-Brain (#7567)
- Tek bir düğümdeki yalnızca güç kesintisi veya kernel çökmesi bile veri kaybı ve replikasyon tutarsızlığına neden olabilir
- Lider-izleyici mimarisinde bazı düğümlerde yalnızca bellekte commit edilmiş bir onay sonrası arıza yaşanırsa,
çoğunluk düğüm kaybı yaşar ve yeni bir duruma geçilir
- Testte tek bir güç kesintisi sonrası süreğen split-brain gözlendi
- Düğüm bazında farklı aralıklarda onaylı mesaj kayıpları görüldü
- Jepsen, benzer bir örneği Kafka'dan alıntılayarak Raft tabanlı sistemlerde de aynı riskin bulunduğunu vurguluyor
4. Tartışma ve Sonuç
- 2.10.22'deki tam veri kaybı sorunu, 2.10.23 ile giderildi
- 2.12.1'de ise dosya bozulması ve OS çökmesi nedeniyle veri kaybı ve split-brain hâlâ gözleniyor
.blk ve snapshot dosyaları bozulduğunda bazı düğümlerde mesaj atlaması veya tüm streamin silinmesi oluşuyor
- Varsayılan
fsync aralığının uzunluğu nedeniyle birden fazla düğüm aynı anda arızalandığında onaylı verinin kaybolma riski devam ediyor
- Jepsen,
fsync=always ayarı veya belgelerde net bir risk notu eklenmesini öneriyor
- JetStream'in “her zaman kullanılabilir” iddiası CAP teoremi açısından imkansız, belge güncellemesi gerekli
- Jepsen ayrıca, hata varlığının kanıtlanabilir ancak güvenliksizlik iddiasının kanıtlanamaz olduğunu belirtiyor
4.1 LazyFS'nin Rolü
- LazyFS kullanılarak
fsync edilmemiş yazıların kaybı simüle edildi
- Güç kesintisi sırasında kısmi yazı bozulması (torn write) gibi farklı depolama hataları tekrarlanabiliyor
- İlgili çalışma When Amnesia Strikes (VLDB 2024)’te, PostgreSQL, Redis, ZooKeeper gibi sistemlerde de benzer hatalar rapor edildi
4.2 Gelecekteki Çalışmalar
- Tekil tüketici seviyesinde mesaj kaybı, mesaj sırası ve linearizable/serializable garantilerinin doğrulaması henüz yapılmadı
- exactly-once teslimat garantisi gelecekteki çalışmaların konusu olacak
- Düğüm ekleme/çıkarma sırasında belge hataları ve zorunlu health check adımının atlanması tespit edildi (#7545)
- Güvenli bir cluster yeniden yapılandırma akışı henüz net değil
Henüz yorum yok.