ADR-004: Tüm Restore İşlemlerinde CAS
Durum
Kabul edildi (2026-04-04)
Bağlam
Restore sırasında Consul KV'ye değer yazıyoruz. Okuma ile yazma arasında başka bir process aynı key'i değiştirirse, o değişikliği sessizce ezebiliriz. Bu özellikle production ortamında kabul edilemez.
Örnek senaryo:
- Guardian
config/production/databasekey'ini okuyor (index: 42) - Başka bir process aynı key'i güncelliyor (index: 43)
- Guardian eski değeri yazıyor -> başka process'in değişikliği kayboldu
Karar
Tüm restore işlemleri CAS (Check-And-Set) kullanacak. Consul Transaction API ile atomik batch'ler halinde uygulanacak.
Sonuçlar
Olumlu
- Sessiz üstüne yazma önlenir: Eşlik eden değişiklikler korunur
- Atomik batch'ler: 64 işleme kadar tek transaction'da, tutarlılık sağlar
- Başarısız CAS açık sinyal verir: Çatışma durumu açıkça raporlanır, yeniden deneme yapılabilir
- Dry-run modu: Gerçek restore öncesi nelerin değişeceği tam olarak gösterilir
Olumsuz
- Kör yazmadan daha karmaşık: Ekstra okuma, index takibi ve retry mantığı gerektirir
- CAS çatışmaları yeniden deneme gerektirir: Exponential backoff ile retry döngüleri
- 64 işlem batch limiti: Çok sayıda key için sayfalama (pagination) gerekir
- Kısmi batch hatası: Bir batch başarısız olursa dikkatli durum yönetimi gerekir
Değerlendirilen Alternatifler
| Alternatif | Avantaj | Dezavantaj | Neden seçilmedi |
|---|---|---|---|
| Kör yazma (KVSet) | Çok basit | Tehlikeli -- eşlik eden değişiklikleri sessizce ezer | Veri kaybı riski |
| Session-tabanlı kilitleme | Güçlü tutarlılık | Çok ağır, diğer yazıcıları engeller | Restore için aşırı mühendislik |
| Raft barrier | Kesin sıralama | Sadece Consul iç yapısında mevcut, harici erişim yok | API olarak sunulmuyor |
Teknik Detay
CAS şu şekilde çalışır:
1. Key'i oku: GET /v1/kv/config/production/database
-> Value: {"pool_size": 50}, ModifyIndex: 42
2. Transaction ile yaz:
KV CAS {
Key: "config/production/database"
Value: {"pool_size": 20} // geri yüklenecek değer
Index: 42 // "sadece index hala 42 ise yaz"
}
3a. Başarılı: Index hala 42 idi, değer yazıldı
3b. Başarısız: Index 43 olmuş (başka biri yazmış), CAS reddedildi
-> Tekrar oku, yeni index ile yeniden dene
Guardian, 64 key'e kadar tek bir Consul transaction'ında toplu CAS yapabilir. Daha fazla key varsa birden fazla transaction'a böler. Her batch bağımsız olarak başarılı veya başarısız olabilir.