8 dk

Eric Brewer'ın CAP Düşüncesi: Dağıtık Sistemler Neden Taviz Verir

Eric Brewer'in CAP teoremini pratik bir zihinsel model olarak öğrenin: tutarlılık, kullanılabilirlik ve ağ bölünmelerinin dağıtık sistem kararlarını nasıl şekillendirdiğini.

Eric Brewer'ın CAP Düşüncesi: Dağıtık Sistemler Neden Taviz Verir

Neden CAP Başvurulan Bir Zihinsel Model Oldu

Aynı veriyi birden fazla makinede sakladığınızda hız ve hata toleransı kazanırsınız—ama aynı zamanda yeni bir sorun da edinirsiniz: anlaşmazlık. İki sunucu farklı güncellemeler alabilir, mesajlar geç veya hiç gelmeyebilir, ve kullanıcılar hangi replika ile karşılaşırsa farklı cevaplar görebilir. CAP popüler oldu çünkü bu dağınık gerçeği abartmadan konuşmanın net bir yolunu sunuyor.

Eric Brewer, bilgisayar bilimci ve Inktomi'nin kurucularından biri, 2000 yılında başarısızlık altındaki çoğaltılmış sistemler hakkında pratik bir ifadeyle çekirdek fikri sundu. Hızla yayıldı çünkü üretimde takımların zaten yaşadığıyla örtüşüyordu: dağıtık sistemler sadece kapanarak başarısız olmaz; bölünerek başarısız olurlar.

CAP bir özellik listesi değil, bir başarısızlık lensidir

CAP en faydalı olduğunda işler ters gittiğinde—özellikle ağ düzgün davranmadığında—ortaya çıkar. Sağlıklı bir günde birçok sistem hem yeterince tutarlı hem de yeterince kullanılabilir görünebilir. Gerçek sınama, makinelerin güvenilir şekilde iletişim kuramadığı ve sistem bölündüğünde okuma/yazma ile ne yapacağınıza karar vermeniz gerektiği zamandır.

Bu çerçeve CAP'in neden başvurulan bir zihinsel model olduğunu gösterir: en iyi uygulamalardan bahsetmez; somut bir soru sorar—bölünme sırasında neyi feda edeceğiz?

Bu makalenin sonunda neyi karar verebileceksiniz

Bu makalenin sonunda şunları yapabilmelisiniz:

  • Gerçek bir CAP senaryosuyla (çoğaltma + olası iletişim kopmaları) karşılaşıp karşılaşmadığınızı tanımlayabilmek.
  • Kasıtlı olarak sisteminizin replikalar anlaşamazken tutarlılığı (herkes aynı gerçeği görsün) mı yoksa kullanılabilirliği (sistem cevap vermeye devam etsin) mi tercih edeceğini seçmek.
  • Bu seçimi ürün etkisiyle bağlamak: kullanıcı ne deneyimler, hangi hataları gösterirsiniz, ve bölünme iyileştiğinde hangi düzeltmelere ihtiyacınız olur.

CAP, “dağıtık zor” lafını savunulabilir bir karara dönüştürdüğü için kalıcıdır.

Kurulum: Replikasyon ve Anlaşmazlık Sorunu

Bir dağıtık sistem, basitçe söylemek gerekirse birbirine benzemeye çalışan çok sayıda bilgisayartır. Farklı raflarda, bölgelerde veya bulut zonlarında birkaç sunucunuz olabilir, ama kullanıcı için bu “uygulama” veya “veritabanı”dır.

Neden veriyi çoğaltıyoruz

Gerçek dünya ölçeğinde paylaşılan sistemi çalıştırmak için genellikle replikasyon yaparız: aynı verinin birden fazla kopyasını farklı makinelerde tutarız.

Replikasyon üç pratik sebepten popülerdir:

  • Ölçek: daha fazla makine daha fazla trafiği kaldırabilir.
  • Performans: kullanıcılara yakın bir kopyadan hizmet verilebilir, gecikme azalır.
  • Güvenilirlik: bir makine ölürse başka bir kopya hizmeti sürdürebilir.

Şu ana kadar replikasyon mantıklı bir kazanım gibi görünüyor. Ama sorun şudur: replikasyon yeni bir iş çıkarır: tüm kopyaları uyumlu tutma.

Temel gerilim: kopyalar anlaşamayabilir

Eğer her replikası her zaman diğerleriyle anında konuşabilseydi, güncellemeleri koordine edip aynı durumda kalabilirlerdi. Ama gerçek ağlar kusursuz değildir. Mesajlar gecikebilir, düşebilir veya hatalı yönlendirilebilir.

İletişim sağlıklı olduğunda replikalar genellikle güncellemeleri değiş-tokuş eder ve aynı durumda birleştirir. Ancak iletişim koptuğunda (geçici olsa bile) gerçeğin iki geçerli görünümlü versiyonuyla karşılaşabilirsiniz.

Örneğin bir kullanıcı gönderi adresini değiştirir. Replika A güncellemeyi alır, replik B almaz. Şimdi sistem basit bir soruyu cevaplamak zorunda: mevcut adres nedir?

Normal çalışma vs. arıza anındaki çalışma

Bu şu farktır:

  • Normal çalışma: replikalar koordine olabilir; anlaşmazlık büyük ölçüde zamanlama meselesidir.
  • Arıza anındaki çalışma: bazı replikalar iletişim kuramaz; anlaşmazlık kaçınılmaz olur.

CAP düşüncesi tam da burada başlar: replikasyon var olduğunda, iletişim kopması altındaki anlaşmazlık bir kenar durumu değil—temel tasarım sorunudur.

CAP Basitçe: C, A ve P

CAP, sistem birden fazla makineye yayıldığında kullanıcıların gerçekten ne hissettiğini modelleyen bir zihinsel çerçevedir. “İyi” veya “kötü” sistemleri tanımlamaz—sadece yönetmeniz gereken gerilimi gösterir.

Tutarlılık (C): en son yazıyı görüyor muyum?

Tutarlılık anlaşma hakkındadır. Bir şeyi güncellerseniz, sonraki okuma (herhangi bir yerden) o güncellemeyi yansıtacak mı?

Kullanıcı açısından bu, “Az önce değiştirdim ve herkes aynı yeni değeri görüyor” ile “bazıları eski değeri bir süre daha görüyor” arasındaki farktır.

Kullanılabilirlik (A): en azından cevap alabiliyor muyum?

Kullanılabilirlik, sistemin isteklere—okuma ve yazmalara—başarılı bir sonuçla yanıt vermesi demektir. “En hızlı” değil, “size hizmet vermeyi reddetmiyor” anlamındadır.

Sorun sırasında (bir sunucu kapandığında, ağda kesinti olduğunda) kullanılabilir bir sistem, cevap vermeye devam eder; hatta biraz eski olabilir ama yanıt verir.

Bölüm Toleransı (P): düğümler konuşamadığında ne olur?

Bir partition (bölünme), ağın bölünmesidir: makineler çalışıyor olabilir ama aralarındaki mesajlar ulaşamıyordur (veya işe yaramayacak kadar geç geliyordur). Dağıtık sistemlerde bunu imkansız sayamazsınız—bölünme olduğunda ne olacağını tanımlamanız gerekir.

Basit bir hikaye: iki mağaza, tek stok

Aynı ürünü satan ve “1 stok” paylaşan iki mağaza düşünün. Müşteri Shop A'da son ürünü alır, Shop A stok = 0 yazar. Aynı anda ağ bölünmesi Shop B'nin bunu duymasını engeller.

Eğer Shop B kullanılabilirliği korursa, bölünme sırasında artık olmayan bir ürünü satabilir (satışı kabul eder). Eğer Shop B tutarlılığı uygularsa, en güncel stoğu doğrulayana kadar satışı reddedebilir (bölünme sırasında hizmeti keser).

Bölünmeler Gerçekte Nedir (ve Neden Gözardı Edemezsiniz)

“Bölünme” sadece “internet kapandı” demek değildir. Sisteminizin bazı parçalarının hala çalışıyor olmasına rağmen güvenilir şekilde konuşamadığı her durumdur.

Replikalı bir sistemde düğümler sürekli mesaj değiş tokuşu yapar: yazmalar, onaylar, heartbeat'ler, lider seçimleri, okuma istekleri. Bir bölünme, bu mesajlar gelmeyi kestiğinde (veya çok geç geldiğinde) ortaya çıkar ve gerçeklik hakkında anlaşmazlık yaratır: "Yazı gerçekleşti mi?" "Kim lider?" "B düğümü canlı mı?"

Bölünmeler iletişim hatalarıdır

İletişim şu karışık şekillerde başarısız olabilir:

  • Paket kaybı nedeniyle retry ve zaman aşımı tetiklenmesi
  • Yönlendirme sorunları nedeniyle trafiğin uzun detour alması veya kaybolması
  • Aşırı yüklü hatlar (veya doygun NIC'ler) nedeniyle uzun gecikmeler
  • Yanlış yapılandırılmış güvenlik duvarları / security group'lar sadece belirli portları veya yönleri engelleyebilir
  • DNS veya servis keşif sorunları düğümlerin birbirini bulmasını engelleyebilir

Önemli nokta: bölünmeler genellikle bozulmadur, temiz bir açık-kapalı durum değil. Uygulama açısından “yeterince yavaş” olmak “kapalı” olmaktan ayırt edilemeyebilir.

Ölçek büyüdükçe bölünmeler kaçınılmazdır

Daha fazla makine, daha fazla ağ, daha fazla bölge ve daha fazla hareketli parça ekledikçe iletişimin bozulabileceği daha çok fırsat ortaya çıkar. Bireysel bileşenlerin güvenilir olması, genel sistemin daha fazla bağımlılık ve çapraz düğüm koordinasyonu olduğu için yine de arıza yaşamasını engellemez.

Sisteminiz yeterince uzun süre çalışır ve yeterince altyapıya yayılırsa, bölünmeler olacaktır—bunu kabul etmek yeterlidir.

Pratikte “bölünmeleri tolere etmek” ne anlama gelir

Bölüm toleransı, sisteminizin bir bölünme sırasında çalışmaya devam edecek şekilde tasarlandığı anlamına gelir—replikalar anlaşamaz veya diğer tarafın ne gördüğünü onaylayamaz olsa bile. Bu bir tercihi zorlar: ya istekleri kabul etmeye devam edip tutarsızlık riskini almak ya da bazı istekleri reddedip/takip eden süre boyunca tutarlılığı korumak.

Ana An: Bölünme Sırasında Tutarlılığı mı Yoksa Kullanılabilirliği mi Seçeceksiniz

Replikasyon olduğunda bölünme sadece bir iletişim kopmasıdır: sisteminizin iki parçası bir süre güvenilir şekilde konuşamaz. Replikalar hâlâ çalışıyor, kullanıcılar hâlâ tıklıyor ve hizmet istek alıyor—ama replikalar en son gerçeğe uzlaşamaz.

CAP gerilimi bir cümlede: bölünme sırasında Tutarlılık (C) veya Kullanılabilirlik (A) önceliklendirilmelidir. Aynı anda her ikisini tam olarak elde edemezsiniz.

Tutarlılığı seçerseniz (C)

"Doğru olmaktansa yanıt vermeyeceğim" dersiniz. Sistem bir isteğin tüm replikaları senkronize tutacağını doğrulayamazsa işlemi başarısız kılmalı veya beklemelidir.

Pratik etkisi: bazı kullanıcılar özellikle veri değiştiren işlemler için hatalar, zaman aşımı veya "tekrar deneyin" mesajları görür. Çifte ücretlendirme riskini almak yerine ödemeyi reddetmeyi tercih etmek ya da fazla rezervasyonu engellemek gibi durumlarda bu yaygındır.

Kullanılabilirliği seçerseniz (A)

"Engellemek yerine yanıtlamayı tercih ederim" dersiniz. Bölünmenin her iki tarafı da koordine edemese bile istekleri kabul etmeye devam eder.

Pratik etkisi: kullanıcılar başarılı yanıtlar alır, fakat okudukları veriler bayat olabilir ve eşzamanlı güncellemeler çakışabilir. Sonrasında uzlaştırmaya güvenirsiniz (birleştirme kuralları, son yazı kazanır, manuel kontrol vs.).

Seçim işlem bazında değişebilir

Bu her zaman tek bir küresel ayar değildir. Birçok ürün strateji karıştırır:

  • Okumalar vs yazmalar: okumaları erişilebilir tutup yazmaları daha katı yapabilirsiniz.
  • Kritik vs önemsiz işlemler: para, kimlik ve envanter için tutarlılığı zorunlu kılarken, akışlar, analiz veya beğeniler için kullanılabilirliği tercih edebilirsiniz.

Ana an, işlem başına neyin daha kötü olduğunu (kullanıcıyı şimdi engellemek mi yoksa daha sonra çakışmayı düzeltmek mi) seçmektir.

Yaygın Yanlış Anlamalar: “İkisini Seçin” Sloganının Ötesi

Test CAP assumptions early
Küçük bir sistem kurup gerçekçi istemci davranışıyla bölüm-benzeri gecikmeyi test edin.

"İkisini seç" sloganı akılda kalıcıdır, ama insanları sık sık yanıltır; CAP'i üç özellikten ikisini sonsuza kadar saklayabileceğiniz bir menü gibi düşünmeye iter. CAP, ağ işbirliği yapmayı bıraktığında ne olduğuyla ilgilidir: bir bölünme (veya benzeri bir durum) meydana geldiğinde, dağıtık sistem her istek için tutarlı cevaplar verip veremeyeceği ile her isteğe yanıt verip veremeyeceği arasında seçim yapmak zorundadır.

Yanlış Anlama 1: “C ve A seçer, bölünmeleri engellerim”

Gerçek dağıtık sistemlerde bölünmeleri kapatabileceğiniz bir ayar yoktur. Sistem makineler, raflar, zonlar veya bölgeler arasında yayıldıysa mesajlar gecikebilir, düşebilir veya garip şekilde yönlendirilebilir. Bu yazılım açısından bir bölünmedir: düğümler olan biteni güvenilir şekilde koordine edemez.

Fiziksel ağ mükemmel olsa bile, GC duraklamaları, gürültülü komşular, DNS aksaklıkları ve hatalı yük dengeleyiciler aynı etkiyi yaratır.

Yanlış Anlama 2: “Bölünmeler nadirdir”

Uygulamalar bölünmeyi net bir ikili olay olarak yaşamazlar. Bunun yerine gecikme sıçramaları ve zaman aşımı yaşarlar. Bir istek 200 ms sonra zaman aşımına uğruyorsa, paketin 201 ms'de ulaşmış olmasıyla hiç ulaşmamış olması arasında uygulama için fark yoktur: uygulama sonraki adımı seçmelidir.

Yanlış Anlama 3: “Sistemler CP ya da AP’dir”

Gerçek sistemler genellikle işletim koşullarına ve yapılandırmaya bağlı olarak çoğunlukla tutarlı veya çoğunlukla kullanılabilir görünür. Zaman aşımları, retry politikaları, quorum boyutları ve "kendi yazını okuma" seçenekleri davranışı kaydırabilir.

Normal koşullarda bir veritabanı güçlü tutarlı görünebilir; stres veya bölge arası aksaklıklarda ise istekleri reddetmeye (tutarlılığı tercih) veya daha eski verileri döndürmeye (kullanılabilirliği tercih) başlayabilir.

CAP, ürünleri etiketlemekten çok, anlaşmazlık olduğunda—özellikle bu anlaşmazlık basit yavaşlıktan kaynaklandığında—verdiğiniz takası anlamaktır.

Aslında Seçebileceğiniz Tutarlılık Seçenekleri

CAP tartışmaları tutarlılığı iki uçluymuş gibi gösterir: ya “mükemmel” ya da “her şey serbest”. Gerçek sistemler, replikalar anlaşamazken veya ağ bağlantısı koptuğunda farklı kullanıcı deneyimleri sunan birkaç garanti seçeneği sunar.

Güçlü tutarlılık (ve arıza sırasında bedeli)

Güçlü tutarlılık (genellikle “linearizable” olarak anılır) demek, bir yazı onaylandığında, daha sonraki her okumanın—hangi replikaya giderse gitsin—o yazıyı dönmesi demektir.

Bedeli: bir bölünme veya replikaların azınlığı ulaşılamaz olduğunda sistem okuma/yazmaları geciktirebilir veya reddedebilir. Kullanıcılar bunu zaman aşımı, "tekrar deneyin" veya geçici salt-okunur davranış olarak görür.

Nihai tutarlılık (ve kullanıcıların fark edebilecekleri)

Nihai tutarlılık şunu vaat eder: eğer yeni güncellemeler durursa, tüm replikalar zamanla uzlaşır. İki kullanıcının tam şu anda aynı şeyi görmesini garanti etmez.

Kullanıcıların fark edebilecekleri: az önce güncellenen bir profil fotoğrafının "geri dönmesi", sayaçların geride kalması veya yeni gönderilen bir mesajın diğer cihazda kısa süre görünmemesi.

Kullanışlı ara garantiler

Tam güçlü tutarlılık talep etmeden daha iyi bir deneyim sağlayabilirsiniz:

  • Kendi yazını okuma: güncellediğinizde kendi verinizin eski sürümünü görmezsiniz.
  • Monoton okumalar: bir kez N sürümünü gördüğünüzde sonra N-1 sürümünü görmezsiniz.
  • Sebep-sonuç (causal) tutarlılık: olay B, A'ya bağlıysa herkes A'yı B'den önce görür.

Bu garantiler insanların düşündüğü şekilde haritalanır ("değişikliklerim kaybolmasın") ve kısmi arızalarda sürdürülmesi genellikle daha kolaydır.

Beklentilere göre tutarlılık düzeyi seçmek

Jargondan çok kullanıcıya verdiğiniz söze göre başlayın:

  • Yanlış okumalar geri dönüşü olmayan zarara yol açıyorsa (para transferi, stok rezervasyonu, izin değişikliği), daha güçlü tutarlılığa eğilin ve geçici kullanılabilirlik kaybını kabul edin.
  • Özellik kısa süreli uyumsuzluk toleranslıysa (beğeniler, görüntüleme sayıları, akış sıralaması), nihai veya sebep-sonuç tutarlılık uygundur.
  • Temel acı kişisel karışıklıksa ("kaydetmiştim—neden göremiyorum?"), kendi yazını okuma ve monoton okumalar öncelikli olsun.

Tutarlılık bir ürün kararıdır: kullanıcı için "yanlış" ne demek olduğunu tanımlayın, sonra o yanlışı önlemek için en zayıf garantiyi seçin.

Kullanılabilirlik: Sadece Uptime Sayısı Değil, Ürün Kararı

Build failure-aware flows
Degrade modunu ve net kullanıcı mesajlarını destekleyen bir API ve UI oluşturun.

CAP'teki kullanılabilirlik övünme metriği değildir (“beş dokuz”). Bu, ağın emin olamadığı durumda kullanıcılara verdiğiniz sözdür.

Hızlı başarı vs doğru başarı

Replikalar uzlaşamadığında genellikle iki seçenek vardır:

  • Hızlı başarı: bir şeyleri hızlıca döndür (bayat olsa bile)
  • Doğru başarı: cevabı ancak güncel olduğuna emin olunca döndür

Kullanıcı bunu "uygulama çalışıyor" ile "uygulama doğru" arasında hisseder. Hiçbiri her zaman üstün değildir; nereyi kabul edilemez hata saydığınız ürüne bağlıdır. Biraz eski bir sosyal akış can sıkıcıdır; bayat bir hesap bakiyesi zararlı olabilir.

"Kapatma" vs "Açık bırakma"

Belirsizlik anında iki yaygın davranış:

  • Kapatma (fail closed): isteği reddet (hata, zaman aşımı, salt-okunur). Doğruluğu korursun ama kullanıcı engellenir.
  • Açık bırakma (fail open): en iyi çaba ile yanıt ver (önbellek, yerel replik, kuyruğa alınmış yazma). Akışı korursun ama tutarsız sonuçlar gösterebilirsin.

Bu teknik bir karardan çok politika kararıdır. Ürün, neyi göstermenin kabul edilebilir olduğunu ve neyin asla tahmin edilemeyeceğini tanımlamalıdır.

Kısmi kullanılabilirlik hâlâ kullanılabilirliktir

Kullanılabilirlik nadiren her şey veya hiçbir şeydir. Bir bölünme sırasında kısmi kullanılabilirlik görebilirsiniz: bazı bölgeler, ağlar veya kullanıcı grupları başarılı olurken diğerleri başarısız olur. Bu bilinçli bir tasarım (lokal replikadan hizmet vermeye devam etmek) veya kazara (yönlendirme dengesizlikleri, düzensiz quorum erişimi) olabilir.

Azaltılmış mod: çekirdeği koruyup riski sınırla

Pratik bir orta yol degrade modudur: riskli işlemleri kısıtlayarak güvenli eylemleri sunmaya devam edin. Örneğin gözatma ve aramaya izin verin, ama geçici olarak “para transferi”, “parola değişikliği” gibi doğruluk gerektiren işlemleri devre dışı bırakın.

Somut Örnekler: CAP Seçimlerini Kullanım Durumlarına Eşleme

CAP soyut geliyor olabilir; onu ağ bölünmesi sırasında kullanıcıların ne deneyimleyeceğine göre haritalayın: sistemin cevap vermeye devam etmesini mi yoksa çakışmayı önlemek için durmasını mı tercih edersiniz?

Envanter ve sipariş: fazla satış riski vs ödeme kesintileri

İki veri merkezi aynı anda sipariş kabul ettiğinde...

Eğer checkout akışını kullanılabilir tutarsanız, her iki taraf da "son ürünü" satabilir ve fazla satış yaşanır. Düşük maliyetli ürünlerde kabul edilebilir olabilir, ama sınırlı ürünlerde can sıkıcıdır.

Tutarlılığı önceleyen davranışta, stok global olarak doğrulanamayınca yeni siparişleri engelleyebilirsiniz. Kullanıcı "sonra deneyin" görür, ama teslim edilemeyecek bir şeyi satmamış olursunuz.

Ödemeler ve bakiyeler: doğruluk-öncelikli desenler

Para klasik olarak "yanlış olmak pahalıdır" alanıdır. Bölünme sırasında iki replik ayrı ayrı çekim kabul ederse hesap negatif olabilir.

Sistemler genellikle kritik yazmalarda tutarlılığı tercih eder: en güncel bakiye doğrulanamıyorsa işlemi reddedin veya geciktirin. Bu, kullanılabilirlik kaybı pahasına doğruluk, denetlenebilirlik ve güven sağlar.

Sohbet, akışlar, analizler: biraz bayat veri kabul edilebilir

Sohbet ve sosyal akışlarda kullanıcılar genellikle küçük tutarsızlıklara tolerans gösterir: mesaj birkaç saniye gecikebilir, beğeni sayısı tutarsız olabilir veya görünüm metriği biraz sonra güncellenebilir.

Burada kullanılabilirliğe dayanmak iyi bir ürün tercihi olabilir—ancak hangi öğelerin "nihai olarak doğru" olduğunu açıkça belirtmeli ve güncellemeleri düzgün bir şekilde birleştirebilmelisiniz.

Özet: takas iş kararıdır

Doğru CAP seçimi, yanlış olmanın maliyetine bağlıdır: geri iadeler, yasal maruz kalma, kullanıcı güveni veya operasyonel kaos. Geçici bayatlığa nerede izin verebileceğinizi ve nerede kapatmanız gerektiğini belirleyin.

Takasınızı Gerçekleştirecek Tasarım Desenleri

Bölünme sırasında ne yapacağınıza karar verdikten sonra bu kararı gerçeğe dönüştürecek mekanizmalara ihtiyacınız var. Bu desenler veritabanlarında, mesaj sistemlerinde ve API'lerde ortaya çıkar—ürün "CAP"i açıkça söylemese bile.

Çoğunluk (Quorum): çoğunluk anlaşması

Quorum basitçe "replikaların çoğu anlaştığında" demektir. 5 kopyanız varsa çoğunluk 3'tür.

Okuma ve/veya yazma için çoğunluğu gerektirerek bayat veya çakışan veri döndürme olasılığını azaltırsınız. Örneğin yazı 3 replikadan onay almalıdır derseniz, iki izole grubun farklı "gerçek"ler kabul etmesi daha zorlaşır.

Takas: hız ve erişim. Çoğunluğa ulaşamazsanız (bölünme veya arızalar yüzünden) sistem işlemi reddedebilir—tutarlılığı kullanılabilirliğe tercih etmiş olursunuz.

Zaman aşımı, yeniden deneme ve backoff algılanan kullanılabilirliği şekillendirir

Birçok kullanılabilirlik sorunu sert arızalar değil, yavaş yanıtlar yüzündendir. Kısa bir zaman aşımı sistemi çevik gösterir, ama yavaş başarıları başarısız sayma riskini artırır.

Yeniden denemeler geçici kusurlardan kurtarabilir; ama agresif yeniden denemeler zaten zorlanan bir hizmeti daha da bunaltabilir. Backoff (yeniden denemeler arasında biraz beklemek) ve jitter (rastgelelik) yeniden denemelerin trafik spike'ına dönüşmesini engeller.

Anahtar, bu ayarları verdiğiniz söze uyacak şekilde hizalamaktır: “her zaman yanıt ver” genellikle daha fazla yeniden deneme ve yedek yol anlamına gelir; “asla yalan söyleme” daha sıkı limitler ve net hatalar demektir.

Farklılaşmaya izin verdiğinizde çakışma işleme

Bölünme sırasında kullanılabilirliği seçerseniz replikalar farklı güncellemeleri kabul eder ve sonrasında uzlaştırma gerekir. Yaygın yaklaşımlar:

  • Last-write-wins (LWW): en yeni zaman damgasına sahip güncellemeyi seç. Basit ama saatler arası uyuşmazlıklarda geçerli değişiklikleri silebilir.
  • Sürüm vektörleri (yüksek seviye): güncellemelerin eşzamanlı mı yoksa ardışık mı olduğunu tespit etmeye yardımcı küçük bir “geçmiş” ekleyin.
  • Birleştirme kuralları: değişiklikleri nasıl birleştireceğinizi tanımlayın (ör. sepet öğeleri birleştir; sayaçlar topla; profilde boş olmayan alanı tercih et). Bu, veri modeline tasarımla entegre edildiğinde en iyi çalışır.

İdempotentlik: yeniden denemeleri güvenli kılma

Yeniden denemeler çoğaltmalara yol açabilir: kartın iki kez çekilmesi veya aynı siparişin iki kez gönderilmesi. İdempotentlik bunu önler.

Yaygın desen, her istekle gönderilen bir idempotentlik anahtarıdır (istek ID'si). Sunucu ilk sonucu saklar ve tekrar eden isteklerde aynı sonucu döndürür—böylece yeniden denemeler kullanılabilirliği artırırken veriyi bozmaz.

Gerçek Hayatta CAP Varsayımlarını Doğrulama

Keep the source yours
Kaynağı üretin, gözden geçirin ve mimarinizin tam kontrolünü elinizde tutmak için dışa aktarın.

Çoğu ekip CAP duruşunu beyaz tahtada “seçer”—sonra üretimde sistemin stres altındayken farklı davrandığını keşfeder. Doğrulama, CAP takaslarının görünür hale geldiği koşulları kasıtlı olarak yaratmak ve sisteminizin tasarladığınız şekilde tepki verdiğini kontrol etmektir.

Bölünmeleri kasıtlı olarak test edin (güvenli şekilde)

Gerçek bir kablo kesimine gerek yok. Bölünmeleri taklit etmek için kontrollü hata enjeksiyonu kullanın:

  • Belirli servisler veya düğümler arasındaki trafiği blackhole yapın (bağlantıları kapatmadan paketleri düşürün) ve sessiz bir bölünme simüle edin.
  • Replika/bölgeler arası portları veya güvenlik grubu kurallarını engelleyerek bağlantıları kesin.
  • Zaman aşımı ve yeniden denemelerin bir bölünme gibi davranması için aşırı gecikme ve paket kaybı ekleyin.
  • Lider izolasyonunu zorlayın (ör. primary'i quorumdan izole edin) ve sistemin "tutarlı" mı yoksa "kullanılabilir" mi davrandığını görün.

Amaç somut sorulara cevap bulmaktır: Yazmalar reddediliyor mu yoksa kabul ediliyor mu? Okumalar bayat mı? Sistem otomatik olarak toparlanıyor mu ve uzlaşma ne kadar sürüyor?

Eğer bu davranışları erken doğrulamak istiyorsanız (hizmetleri birbirine bağlamak için haftalar harcamadan önce), gerçekçi bir prototip hızla kurmak yardımcı olur. Örneğin, Koder.ai kullanan takımlar genellikle küçük bir servis (çoğunlukla Go backend, PostgreSQL ve bir React UI) üreterek retry, idempotentlik anahtarları ve “degrade mode” akışlarını sandbox ortamında test ederler.

CAP acısını ortaya çıkaran izleme sinyalleri

Geleneksel uptime kontrolleri “yanlış ama erişilebilir” davranışı yakalamaz. Şunları izleyin:

  • İşlem türüne göre hata oranları (okuma vs yazma vs koşullu güncelleme)
  • Bayat-okuma göstergeleri (kendi yazını okuma ihlalleri, sürüm/ETag uyuşmazlıkları, gecikme metrikleri)
  • Replika farklılaşması (replikasyon gecikmesi, uygulanamayan yazma sayıları, çakışma oranları)
  • Zaman aşımılar/yeniden denemeler (genellikle ortaya çıkan bölünmenin ilk işareti)

Çalışma kitapçıları ve kullanıcı iletişimi

Operatörlerin bir bölünme olduğunda önceden belirlenmiş eylemlere ihtiyacı vardır: ne zaman yazıları donduracaksınız, ne zaman fail over yapacaksınız, ne zaman özellikleri azaltacaksınız ve yeniden birleştirmenin güvenliğini nasıl doğrulayacaksınız.

Ayrıca kullanıcıya yönelik mesajı planlayın. Tutarlılığı seçtiyseniz mesaj "Güncellemenizi şu an doğrulayamıyoruz—lütfen tekrar deneyin" olabilir. Kullanılabilirliği seçtiyseniz açık olun: "Güncellemeniz birkaç dakika içinde herkese yansıyabilir." Net ifadeler destek yükünü azaltır ve güveni korur.

Günlük Sistem Kararları İçin Pratik CAP Kontrol Listesi

Sistem kararı alırken CAP, teorik bir tartışmadan ziyade “bölünme olursa ne bozulur?” denetimi olarak en yararlıdır. Bir veritabanı özelliği, önbellekleme stratejisi veya replikasyon modu seçmeden önce bu hızlı kontrol listesini kullanın.

1) Kısa CAP kontrol listesi

Sırayla şu soruları sorun:

  • Ne doğru olmalı? (ör. "banka bakiyesi asla negatif olamaz", "envanter fazla satışa izin veremez", "izinler doğru olmalı")
  • Ne ayakta kalmalı? (ör. checkout endpoint, giriş, salt-okunur katalog)
  • Ne geçici olarak bozulabilir? (ör. analiz, öneriler, profil avatarları, "son görülme")

Bir ağ bölünmesi olursa önce bunlardan hangisini koruyacağınızı seçiyorsunuz.

2) Veri tipine ve uç noktaya göre karar verin

"Biz AP sistemiyiz" gibi tek bir küresel ayardan kaçının. Bunun yerine şunları uç nokta başına belirleyin:

  • Veri tipi: para vs beğeni vs log
  • Uç nokta: "sipariş ver" vs "siparişi görüntüle" vs "kargoyu takip et"

Örnek: bir bölünme sırasında payments için yazmaları engelleyip (tutarlılığı tercih) product_catalog okumalarını önbellekten sunabilirsiniz.

3) Kabul edilebilir tutarsızlığı somut terimlerle tanımlayın

Neyi tolere edebileceğinizi örneklerle yazın:

  • Zamana bağlı: "sayaçlar 5–10 dakika geride olabilir"
  • Büyüklük: "düşük talep ürünü için envanter ±1 sapma gösterebilir"
  • Alan seviyesi: "kargo ETA'sı bayat olabilir; sipariş toplamı olamaz"
  • Kullanıcıya görünür ifade: "kesin durum yerine 'beklemede' göster"

Eğer tutarsızlığı açık örneklerle anlatamazsanız, test etmekte ve olayları açıklamakta zorlanırsınız.

4) Çıkarımlar + sonraki okunacaklar

  • Bölünmeler "isteğe bağlı" garantileri zorunlu seçimlere dönüştürür.
  • Bu seçimleri uç nokta bazında açıkça yapın ve kabul edilebilir tutarsızlığı dokümante edin.

İzlemesi faydalı bir sonraki konular: konsensüs, tutarlılık modelleri ve SLO'lar/hata bütçeleri.

SSS

What problem does CAP help engineers reason about?

CAP, iletişim hatası altındaki çoğaltılmış sistemler için bir zihinsel modeldir. Ağ yavaşladığında, paketler kaybolduğunda veya sistem parçalandığında en faydalıdır; çünkü bu durumlarda replikalar güvenilir şekilde uzlaşamaz ve şu ikiden birini seçmeniz gerekir:

  • Tutarlılık: herkes en güncel değeri görür
  • Kullanılabilirlik: sistem başarılı yanıtlar vermeye devam eder

Bu model, “dağıtık zor” lafını somut bir ürün ve mühendislik kararına dönüştürür.

When am I actually in a CAP situation?

Gerçek bir CAP senaryosu için her ikisi de gereklidir:

  • Çoğaltma (aynı veri için birden fazla düğüm okuma/yazma yapabiliyor)
  • Gerçekçi bir iletişim hatası ihtimali (bölünmeler, zaman aşımı, uzun gecikmeler)

Eğer sistem tek bir düğümse veya durum çoğaltılmıyorsa, CAP takasları merkezi bir mesele değildir.

What counts as a network partition in real systems?

Bir partition (bölünme), sistem parçalarının güvenilir şekilde ya da gerekli süre içinde iletişim kuramadığı herhangi bir durumdur—her makine hâlâ çalışıyor olsa bile.

Pratikte “bölünme” şu şekilde görünür:

  • zaman aşımı tetikleyen gecikme spike'ları
  • paket kaybı/blackhole
  • güvenlik duvarı veya yönlendirme hataları
  • aşırı yüklü düğümler

Uygulama açısından “çok yavaş” olmak çoğu zaman “çökmüş” olmakla aynıdır.

What’s the difference between consistency and availability in user terms?

Tutarlılık (C), herhangi bir yerden yapılan okumanın en son onaylanmış yazıyı geri döndürmesi demektir. Kullanıcı bunu “değiştirdim ve herkes aynı şeyi görüyor” şeklinde hisseder.

Kullanılabilirlik (A), her isteğin başarılı bir yanıt alması anlamına gelir (mutlaka en güncel olmayabilir). Kullanıcı bunu “uygulama çalışmaya devam ediyor” şeklinde deneyimler—ancak sonuçlar bayat olabilir.

Bir bölünme sırasında genelde her iki garantiyi aynı anda tüm işlemler için sağlayamazsınız.

Why can’t I just choose consistency and availability and ignore partitions?

Çünkü dağıtık sistemlerde bölünmeler opsiyonel değildir. Eğer durum çoğaltılıyorsa, düğümler koordine olamadığında nasıl davranılacağını tanımlamanız gerekir.

Dolayısıyla “bölünmeleri yok sayayım” diye bir yol yoktur: çoğaltma yaptığınız sürece, iletişim bozulduğunda sistem ya bazı işlemleri reddetmeli/saklamalı (tutarlılığı tercih ederek) ya da en iyi çabayı gösterip sonuçları daha sonra uzlaştırmalıdır (kullanılabilirliği tercih ederek).

What does a consistency-first (CP) choice look like during a split?

Tutarlılığı tercih ederseniz genellikle şunları yaparsınız:

  • uzlaşma doğrulanamıyorsa işlemleri reddetmek veya bekletmek
  • okuma/yazma için çoğunluk/quorum gerektirmek
  • zaman aşımı, “tekrar deneyin” mesajları veya geçici salt-okunur moda geçiş

Bu yaklaşım para transferi, envanter rezervasyonu ve izin değişiklikleri gibi yanlış olmak istemediğiniz alanlarda yaygındır.

What does an availability-first (AP) choice look like during a split?

Kullanılabilirliği tercih ederseniz genellikle şunları yaparsınız:

  • bölünmenin her iki tarafı da okumaları/yazmaları kabul etmeye devam eder
  • replikalar geçici olarak farklılaşabilir
  • sonra uzlaştırma yapılır (birleştirme kuralları, çakışma çözümü, manuel inceleme)

Kullanıcı sert hatalar daha az görür, ama veriler bayat olabilir veya idempotentlik yoksa tekrar eden etkiler ortaya çıkabilir.

Can I mix consistency and availability choices by operation?

Evet. Genelde farklı uç noktalar ve veri tipleri için farklı stratejiler benimsenir. Yaygın karışık yaklaşımlar:

  • Okumalar kullanılabilir, yazmalar daha katı (gözatma çalışır; riskli güncellemeler başarısız olabilir)
  • Kritik eylemler kapalı kalır (ödeme, envanter, kimlik) iken düşük riskli özellikler açık kalır (akışlar, analizler)
  • Degrade modu: güvenli işlemleri tut, riskli olanları geçici kapat

Bu, tek bir “biz AP/CP’yiz” etiketinden kaçınmaya yardımcı olur.

What consistency guarantees can I choose besides “strong” vs “eventual”?

Altında yatan seçenekler şunlardır:

  • Güçlü tutarlılık (linearizable): yazı onaylandıktan sonra her okuma o yazıyı görür; parçalanma sırasında bekleme veya reddetme maliyeti vardır
  • Nihai (eventual) tutarlılık: yeni güncellemeler durduğunda replikalar zamanla uzlaşır; anlık okumalarda fark olabilir
  • Ara garantiler:
    • kendi yazını okuma (yaptığınız güncellemeyi görürsünüz)
    • monoton okumalar (bir sürümü gördükten sonra daha eski bir sürüme geri dönmezsiniz)
    • sebep-sonuç tutarlılığı (B olayı A'ya bağlıysa herkes A'yı B'den önce görür)

Kabul edilebilir yanlışlığı önleyecek en zayıf garantiyi seçin.

How do I test and monitor my system’s CAP behavior in practice?

Gerçek koşullarda farklı davranışları görmek için kasıtlı olarak parçalanma koşulları yaratın:

  • staging'de (ve dikkatli olarak production'da) bölünme simülasyonu yapın: belirli hizmetler arası trafiği blackhole yapın, portları veya güvenlik gruplarını engelleyin, aşırı gecikme ve paket kaybı ekleyin
  • doğrulayın: yazmalar reddediliyor mu yoksa kabul ediliyor mu? okumalar bayat mı? kurtarma ve uzlaştırma nasıl işliyor?
  • izleyin: sadece uptime değil; okuma/yazma hata oranları, replika sapması, zaman aşımı ve yeniden deneme sayıları gibi sinyalleri takip edin

Ayrıca bir bölünme olduğunda ne zaman yazıları donduracağınızı, ne zaman failover yapacağınızı ve kullanıcıya ne söyleyeceğinizi içeren çalışma kitapçıkları hazırlayın.

Related posts