
Zamanlanmış göreviniz bir dosyaya rapor yazıyor. Yoğun bir gün önceki çalışma uzadı ve yeni çalışma başladı. İki süreç aynı dosyaya yazdı ve sonuçta ne birinci ne ikinci raporu okunabilir hâlde kaldı.
Bu yazı, dosya seviyesinde eşzamanlılık kontrolünü ele alıyor.
Ne Olur?
İki sürecin aynı dosyaya yazması öngörülemez sonuçlar üretir:
- Satırlar iç içe geçer.
- İçerik yarım kalır.
- Dosya boyutu tutarsız olur.
- Okuyan taraf bozuk veri alır.
Birinci madde günlük dosyalarında yaygındır ama genellikle zararsızdır. Asıl tehlike ikinci maddedir: yapılandırma veya veri dosyası yazarken kesilen bir işlem, dosyayı hiç okunamaz hâlde bırakır ve uygulamanız bir sonraki açılışta hata verir.
Bu, özellikle sunucu yeniden başlatılırken veya süreç öldürüldüğünde yaşanır.
Dördüncü madde ise sessiz veri hatalarına yol açar. Yarım yazılmış bir dosyayı okuyan kod, eksik veriyi geçerli sanabilir.
Kilit Türleri
| Tür | Davranış |
|---|---|
| Paylaşımlı kilit | Birden fazla okuyucu |
| Özel kilit | Tek yazıcı |
| Bloklayan | Kilit boşalana kadar bekler |
| Bloklamayan | Alamazsa hemen döner |
Dördüncü satır zamanlanmış görevler için doğru tercihtir: kilidi alamayan bir görev beklemek yerine hemen çıkmalıdır — çünkü önceki çalışma hâlâ sürüyorsa yenisinin başlamasına zaten gerek yoktur.
Beklemek, birikmiş süreçler ve sonunda tüketilen kaynaklar demektir.
Üçüncü satır ise sıralı işlem gereken durumlarda kullanılır ama zaman aşımı ile birlikte tanımlanmalıdır.
Tavsiyeli Kilit Tuzağı
Çoğu sistemde dosya kilitleri zorlayıcı değildir:
- Kilit bir işaret gibidir.
- Yalnızca kontrol eden süreçler uyar.
- Kontrol etmeyen yine de yazabilir.
Üçüncü madde çok önemli bir sınırı gösterir: dosya kilidi yalnızca kilidi kontrol eden süreçler arasında çalışır — kilidi hiç sormayan bir program dosyaya rahatça yazar ve kilidin hiçbir koruması olmaz.
Bu nedenle kilit kullanımı tüm ilgili kodda tutarlı olmalıdır.
Elle bir dosyayı düzenlemek veya farklı bir betikle yazmak, korumayı devre dışı bırakır.
Atomik Yazma Deseni
Kilitten daha güvenilir bir yöntem vardır:
- Geçici bir dosyaya yazın.
- Yazma bitince diske aktarın.
- Son adımda hedef adına taşıyın.
Üçüncü adım bu desenin gücüdür: aynı dosya sistemi içindeki bir yeniden adlandırma işlemi atomiktir — okuyan taraf ya eski dosyayı ya yeni dosyayı görür, asla yarım bir dosyayı görmez.
Bu, kilit kullanmadan tutarlılık sağlar ve okuyucuları hiç bekletmez.
İkinci adım ihmal edilmemelidir. Veriyi diske aktarmadan yapılan bir taşıma, ani bir güç kesintisinde boş dosya bırakabilir.
Önemli bir kısıt: geçici dosya ile hedef aynı dosya sisteminde olmalıdır, aksi hâlde taşıma atomik değil kopyalama olur.
Kilit Dosyası Yaklaşımı
Süreçlerin çakışmasını önlemenin klasik yolu:
| Adım | Dikkat |
|---|---|
| Kilit dosyası oluştur | Varsa çık |
| Süreç kimliğini yaz | Kim tutuyor belli olsun |
| İşi yap | - |
| Kilit dosyasını sil | Hata durumunda da |
Dördüncü satırdaki uyarı bu yöntemin zayıf noktasıdır: süreç beklenmedik şekilde ölürse kilit dosyası ortada kalır ve sonraki tüm çalışmalar "zaten çalışıyor" sanıp çıkar — görev sessizce durmuş olur.
Bu, günlerce fark edilmeyen bir arıza türüdür.
Çözüm, kilit dosyasındaki süreç kimliğinin gerçekten çalışıp çalışmadığını kontrol etmektir. Çalışmıyorsa kilit bayat sayılır ve devralınır.
Modern sistemlerde ise işletim sisteminin sunduğu kilit mekanizmaları tercih edilmelidir; süreç öldüğünde kilit otomatik serbest kalır.
Ağ Dosya Sistemlerinde
Kilitleme burada güvenilirliğini kaybeder:
- Kilit protokolü ek bir katmandır.
- Ağ kopmasında durum belirsizleşir.
- Uygulamalar arası tutarlılık zayıftır.
İkinci madde ciddi bir risktir: ağ dosya sistemi üzerinde tutulan bir kilit, bağlantı koptuğunda hem tutulmuş hem serbest sayılabilir ve iki süreç aynı anda kilidi aldığını sanabilir.
Bu nedenle kritik eşzamanlılık kontrolü için ağ dosya sistemi kilitlerine güvenilmemelidir.
Doğru yaklaşım, kilidi veritabanında veya bellek tabanlı bir depoda tutmaktır. Bu sistemler eşzamanlılık için tasarlanmıştır.
Daha İyi Alternatifler
| İhtiyaç | Öneri |
|---|---|
| Tek örnek çalıştırma | Sistem kilidi veya servis yöneticisi |
| Çok sunucuda tek çalıştırma | Dağıtık kilit |
| Sıralı işleme | Kuyruk sistemi |
| Tutarlı dosya yazma | Atomik yeniden adlandırma |
Üçüncü satır çoğu senaryoda en iyi cevaptır: kilit kullanmak yerine işleri bir kuyruğa alıp tek bir işçiyle sırayla işlemek, eşzamanlılık sorununu tamamen ortadan kaldırır — çakışacak iki süreç hiç oluşmaz.
Bu yaklaşım aynı zamanda yeniden deneme ve hata yönetimi de sağlar.
İkinci satır ise çok sunuculu ortamlarda zorunludur. Yerel bir dosya kilidi, diğer sunucudaki süreci hiç görmez.
Birinci satır ise en basit çözümdür ve zamanlanmış görevlerde fazlasıyla yeterlidir.
Kuyruk ve dağıtık kilit servisleri için ek bir bileşen çalıştırmanız gerekir; VDS sunucu çözüm paketleri üzerinde bu servisleri kendi kaynaklarınızla barındırabilirsiniz.
Sonuç
Dosya kilitlerinin en çok yanlış anlaşılan yanı, çoğu sistemde yalnızca kilidi kontrol eden süreçler arasında çalışmasıdır — kilidi sormayan bir program dosyaya rahatça yazar. Tutarlı dosya yazma için kilit yerine atomik yeniden adlandırma kullanın: okuyan taraf ya eski ya yeni dosyayı görür, asla yarım dosyayı görmez. Kilit dosyası yöntemini seçerseniz bayat kilit kontrolünü unutmayın; süreç beklenmedik şekilde ölürse görev sessizce durur ve günlerce fark edilmez.
Sıkça Sorulan Sorular (SSS)
Dosya kilidi tam koruma sağlar mı?
Çoğu sistemde hayır. Kilit bir işaret gibidir ve yalnızca onu kontrol eden süreçler arasında çalışır; kilidi hiç sormayan bir program dosyaya rahatça yazar. Elle düzenleme veya farklı bir betikle yazma korumayı devre dışı bırakır.
Dosyayı bozulmadan nasıl yazarım?
Geçici bir dosyaya yazın, veriyi diske aktarın ve son adımda hedef adına taşıyın. Aynı dosya sistemi içindeki yeniden adlandırma atomiktir — okuyan taraf ya eski ya yeni dosyayı görür, asla yarım dosyayı görmez. Geçici dosya ile hedefin aynı dosya sisteminde olması şarttır.
Zamanlanmış görevim neden hiç çalışmıyor?
Muhtemelen ortada kalmış bir kilit dosyası var. Süreç beklenmedik şekilde öldüğünde kilit dosyası silinmez ve sonraki tüm çalışmalar "zaten çalışıyor" sanıp çıkar. Kilit dosyasındaki süreç kimliğinin gerçekten çalışıp çalışmadığını kontrol edin veya işletim sisteminin kilit mekanizmasını kullanın.
Ağ dosya sisteminde kilitlemeye güvenebilir miyim?
Kritik işler için hayır. Ağ üzerinde tutulan bir kilit, bağlantı koptuğunda hem tutulmuş hem serbest sayılabilir ve iki süreç aynı anda kilidi aldığını sanabilir. Eşzamanlılık kontrolünü veritabanında veya bellek tabanlı bir depoda yapın; bu sistemler bunun için tasarlanmıştır.