İçeriğe geç
<UK/>

Mimari karar günlüğü

Karar Kayıtları

Sistemlerin ardındaki kararlar: masada ne vardı, ne seçildi ve bedeli neydi. Kısıtları değiştir, cevabın nerede değiştiğini gör.

Kayıtlar

Numaralar kararların alındığı sırayı değil, kanıtların yayımlandığı sırayı izliyor.

ADR-001Kabul edildiGüvenilirlikKanıtların yayım tarihleri –

Yüksek erişilebilirliği hosting platformuna en baştan kurmak

HAProxy'nin önünde yer değiştirebilen bir IP, etcd üzerinde üç düğümlü bir Patroni kümesi, arada PgBouncer: her katman yedekli, her devralma otomatik.

Bağlam

Makdos, Umut'un 2020–2023 arasında kurup işlettiği ticari bir hosting platformuydu. Müşteriler işlerini onun üzerinde yürütüyordu; birkaç dakikalık veritabanı kesintisi kaybolan işlemler, bozulan müşteri panelleri ve çözülmesi günler süren destek talepleri demekti. Hedef %99,9 çalışma süresiydi; yazıya göre bu, planlı bakım dahil yılda yaklaşık 8,7 saatlik kesintiye karşılık geliyor.

Kararın değiştiği yerler

İki kısıt karşı karşıya, diğerleri ayarların gösterdiği yerde. Her kare orada kazanan seçeneği gösteriyor; birini seçersen iki ayar birden o kareye geçer.

Ok tuşlarıyla harita üzerinde gezin; geldiğin her kare iki ayarı birden değiştirir.

Ölçek ve Operasyon olgunluğu kombinasyonlarının her birinde kazanan seçenek
Dalgalı
Yüksek
Sabit
Küçük
Minik
YokElleUyarıNöbetPlatform
  • Yedeği alınan tek bir veritabanı sunucusu
  • Elle devreye alınan bir yedek sunucu
  • Her katmanda yedeklilik
  • Şu anki ayar
  • Kayıttaki bağlam

Kısıtları değiştir

Karar geçerli kalıyor. C · Her katmanda yedeklilik hâlâ 2 puan farkla kazanıyor.

Her ayar, kaydın anlattığı bağlamdan başlıyor. Nokta o seviyeyi gösteriyor: kaynak açıkça söylüyorsa dolu, seviye bu sayfanın kaynaktaki ifadeden çıkardığı bir yorumsa halkalı, hiçbir kuralın devrede olmadığı nötr bir yer tutucuysa içi boş. Her seviyenin altındaki harf, diğer ayarlar olduğu yerde kalırsa orada kazanacak seçeneği gösteriyor.

Ekip büyüklüğü

Kaç kişinin geliştirip işlettiği.

Kayıttaki: Tek ekip (kaynakta yok, nötr yer tutucu). Bu ayarın her seviyesinde geçerli kalıyor.

Operasyon olgunluğu

Canlı sistemi kimin, nasıl ayakta tuttuğu.

Kayıttaki: Kılavuzlar ve nöbet (kaynaktaki ifadeden çıkarıldı: Her çalıştırma kılavuzu (runbook), her kurtarma prosedürü ve her mimari karar belgelendi.). Karar şu seviyelerde değişiyor: Operasyona bakan kimse yok, Gerektikçe, elle

Teslim süresi

Çalışır hâle gelmesine ne kadar süre var.

Kayıttaki: Bir çeyrek (kaynakta yok, nötr yer tutucu). Karar şu seviyede değişiyor: Birkaç gün

Bütçe

Ayrılabilecek para ve iş gücü.

Kayıttaki: Orta (kaynakta yok, nötr yer tutucu). Karar şu seviyede değişiyor: Neredeyse yok

Uyum ve veri denetimi

Denetçilerin, mevzuatın ya da kurum içi politikanın istedikleri.

Kayıttaki: Kurum içi politika (kaynakta yok, nötr yer tutucu). Bu ayarın her seviyesinde geçerli kalıyor.

Ölçek

Kaldırması gereken trafik ya da değişiklik hacmi.

Kayıttaki: Mütevazı (kaynaktaki ifadeden çıkarıldı: Yoğun saatlerde aynı anda yaklaşık 200 kullanıcı ağırlıyorduk; bu, küresel ölçeklere göre devasa değildi). Karar şu seviyede değişiyor: Çok küçük

Masadaki seçenekler

  1. A · Yedeği alınan tek bir veritabanı sunucusu

    Tek bir proxy'nin arkasında tek bir PostgreSQL sunucusu; düzenli yedekler ve bir geri yükleme prosedürü.

    3 puan
    • 3Başlangıç puanıEn az hareketli parça; ama her arıza ya da bakım penceresi müşterinin gördüğü bir kesintiye dönüşüyor, yazının kaçınmaya çalıştığı da tam buydu.kayıttan
    Şu an geçerli olmayan 5 kural
    • +3Ölçek: Çok küçükYalnızca bir avuç kullanıcı varken kısa bir kesinti ve yedekten geri dönüş pek bir şeye mal olmaz.model varsayımı
    • +1Operasyon olgunluğu ≤ Gerektikçe, elleYazı her ek bileşeni bir arıza noktası daha sayıyor; düzenli devralma tatbikatları yoksa daha az bileşen daha güvenli.kayıttan
    • +2Teslim süresi: Birkaç günÇalışmadan önce kurulacak bir şey yok.model varsayımı
    • +2Bütçe: Neredeyse yokBir küme yerine tek makine.model varsayımı
    • −1Uyum ve veri denetimi ≥ Düzenlemeye tabi veriDüzenlemeye tabi veri, son işlemleri kaybetmenin bedelini artırır.model varsayımı
  2. B · Elle devreye alınan bir yedek sunucu

    Birincil sunucu, eşzamansız bir yedeğe akış yapıyor; birincil çökerse biri yedeği birincil yapıyor.

    4 puan
    • 4Başlangıç puanıKurtarma artık geri yüklemeyi beklemiyor ama bir insanı bekliyor; eşzamansız bir yedekte de birincilin çoktan onayladığı son işlemler eksik olabilir.teknik kaynaktan
    Şu an geçerli olmayan 3 kural
    • +2Operasyon olgunluğu ≤ Gerektikçe, elleNöbet tatbikatı olmayan bir ekibe, iyi bilinen tek bir devreye alma adımı uyar.model varsayımı
    • +1Teslim süresi ≤ Birkaç haftaAkış çoğaltmasını kurmak, uzlaşı tabanlı bir kümeden daha hızlı.model varsayımı
    • +1Bütçe ≤ KısıtlıBir küme yerine iki veritabanı makinesi.model varsayımı
  3. C · Her katmanda yedeklilik

    Kayıttaki seçimBurada kazanan

    keepalived sanal bir IP'yi iki HAProxy düğümü arasında taşıyor; Patroni, PostgreSQL'i bir birincil ve iki eşzamanlı yedekle, lider seçimi için üç düğümlü bir etcd kümesiyle çalıştırıyor; PgBouncer bağlantıları kendi sanal IP'sinin arkasında havuzluyor.

    6 puan
    • 6Başlangıç puanıDüğüm arızalarını ve bakımı müşterinin göreceği bir kesinti olmadan atlatıyor: yazının ücretli müşterisi olan bir platform için tartışmaya kapalı saydığı gereksinim.kayıttan
    Şu an geçerli olmayan 6 kural
    • −4Operasyon olgunluğu ≤ Gerektikçe, elleYazı düzenli devralma testini tartışmaya kapalı sayıyor: aylık tatbikatlar her seferinde eksik bir geri çağırma, kaymış bir yapılandırma ya da bir izleme boşluğu buldu. O pratik olmadan ek bileşenler, ek arıza noktalarıdır.kayıttan
    • −4Teslim süresi: Birkaç günPatroni'yi kurmak kolay değildi; yazı arıza senaryolarını test etmeye epey zaman harcandığını anlatıyor.kayıttan
    • −3Bütçe: Neredeyse yokÜç veritabanı düğümü, üç etcd düğümü, ikişer proxy ve havuzlayıcı.model varsayımı
    • −2Ölçek: Çok küçükBir avuç kullanıcı için işletilecek beş bileşen, önledikleri kesintilerden ağır basar.model varsayımı
    • −1Ekip büyüklüğü: Tek kişiHer devralma tatbikatı ve her gece yarısı olayı tek kişinin omzunda kalır.model varsayımı
    • +1Uyum ve veri denetimi ≥ Düzenlemeye tabi veriEşzamanlı yedeklerle Patroni, onaylanmış işlemleri eksik olabilecek bir yedeği birincil yapmaz.teknik kaynaktan

Karar

Yedekliliği en baştan her katmana tasarla: keepalived sanal IP'sinin arkasında aktif-pasif bir HAProxy çifti, lider seçimi için etcd kullanan ve eşzamanlı yedekleri olan Patroni yönetiminde PostgreSQL, kendi sanal IP'sinin arkasında işlem havuzlama modunda PgBouncer; hepsini izleyen Prometheus, Grafana ve Alertmanager.

Sonuçlar

Ne kazandırdı

  • Yazıya göre platform %99,9 çalışma süresi hedefine ulaştı.
  • Devralma her katmanda otomatik: keepalived sanal IP'yi saniyeler içinde taşıyor; yazıya göre Patroni bir yedeği genellikle 10 saniyenin altında birincil yapıyordu.
  • PgBouncer'ın işlem havuzlaması, yazıdaki rakamlarla, platformun ihtiyaç duyduğu veritabanı bağlantısını 300'ün üzerinden 50 civarına indirdi.

Neye mal oldu

  • Birlikte anlaşılması, izlenmesi ve test edilmesi gereken beş bileşen: HAProxy, keepalived, Patroni, etcd ve PgBouncer. Yazı her ek bileşeni bir arıza noktası daha sayıyor.
  • Patroni'nin uç durumları çok sayıda; onları bulmak, birincil düğümü bilerek öldürmeyi ve ağ bölünmelerini canlandırmayı gerektirdi.
  • Eşzamanlı çoğaltma her commit'in bir yedeğin onayını beklemesine yol açıyor; PostgreSQL belgelerine göre bu yanıt süresini artırır.

Sonra ne oldu

  • Düğümlerin bilerek öldürüldüğü aylık arıza tatbikatları; her biri eksik bir geri çağırma, kaymış bir yapılandırma ya da bir izleme boşluğu ortaya çıkardı.
  • Her kurtarma prosedürü için bir kılavuz; böylece gece yarısı bir olay, sıfırdan hata ayıklamak yerine bir kontrol listesini izlemek demekti.
  • Yazının kapanış dersi: yüksek erişilebilirlik sonradan eklenen bir özellik değil, en baştan tasarlanan bir mimari.

Kanıtlar

Teknik kaynak

Patroni'nin eşzamanlı modu, bir yedeğin istemciye onaylanmış olabilecek her işlemi içerdiğinden emin olmadıkça onu birincil yapmaz. Belgeleri, eşzamanlı çoğaltmanın her durumda sıfır kaybı garanti etmediğini de ekliyor; örneğin birincil ile eşzamanlı yedek aynı anda çökerse. PostgreSQL de yedeğin onayını beklemenin her commit'in yanıt süresini artırdığını belirtiyor.

Puanlama nasıl işliyor

Her seçenek gerekçesi yazılı bir başlangıç puanıyla başlıyor. Bir kural, ayarı kendi aralığındayken puan ekliyor ya da düşüyor, ya da seçeneği tamamen eliyor. Oyunda kalan en yüksek puanlı seçenek kazanıyor; beraberlikte kayıttaki karar korunuyor, çünkü değiştirmenin de bir bedeli var. Her şey, bu sayfada okuyabildiğin kurallardan tarayıcında yeniden hesaplanıyor.

“Kayıttan” işaretli kurallar, alıntılanan yazıda, README'de ya da proje sayfasında adı geçen bir ödünleşimi özetliyor. “Teknik kaynaktan” kuralları bağlantısı verilen teknik belgelerden geliyor. “Model varsayımı” kuralları ise “ya şöyle olsaydı” sorularını mümkün kılmak için bu sayfa için yazıldı; ne yaşananlara ne de neyin seçilmesi gerektiğine dair bir iddia. Seviyeler ölçüm değil, sıralı etiketler; kayıttaki bağlamın dışındaki her senaryo varsayımsal.

Biçim ve kaynaklar

Kayıt biçimi: Michael Nygard, “Documenting Architecture Decisions” (2011) (yeni sekmede açılır)