Dağıtık bir sistemin çöküşü sınırlı görünen bir hatayla başlayabilir, ancak birçok bileşen birbirine bağlı olduğunda hızla bir arıza zincirine dönüşebilir. Yazılım mühendisliği alanında bağımsız danışman olan Sam Newman, yaptığı bir sunumda inşaat mühendisliğindeki zincirleme çöküş (Progressive Collapse) kavramını dijital sistemlerdeki dayanıklılık sorunlarıyla ilişkilendiriyor ve tüm hataları önlemenin mümkün olmadığını, ancak bunların yayılma olasılığının ve etkisinin azaltılabileceğini belirtiyor.
Ronan Point'ten bulut hizmetlerine
Newman, 1968 yılında Londra'nın Canning Town bölgesindeki Ronan Point kulesinde yaşanan kısmi çöküş olayına dönüyor. Mrs. Ivy Hodge'un dairesinde meydana gelen sınırlı bir gaz patlaması, binanın bir bölümünü taşıyan dış duvarın yerinden çıkmasına neden oldu. Patlama noktasının üzerindeki dört kat çöktü ve bunun ardından kulenin bir köşesinin bir bölümü zincirleme bir etkiyle yıkıldı. Dört kişi hayatını kaybetti; olayın 1968 yılında sabah saat altıdan hemen önce gerçekleşmiş olması, kurban sayısının sınırlı kalmasına yardımcı olan bir etkendi.
Yazılım açısından önemli olan, bir bina ile dijital hizmet arasındaki fiziksel benzerlik değil, arıza modelidir: Küçük bir ilk arıza, diğer bileşenlerin bağımlı olduğu bir bileşeni devre dışı bırakır ve böylece zararın kapsamı genişler. Hizmetler, veritabanları, yük dengeleyiciler ve DNS sistemleri arasındaki ilişkiler her zaman bir domino sırası gibi görünür olmadığından, dağıtık sistemlerde bu zinciri anlamak zordur.
Zincirleme arızaya ilişkin dijital örnekler
AWS'nin us-east-1 bölgesindeki ekim ayındaki kesinti sırasında, DynamoDB'nin bir alt bileşeni AWS altyapısı içinde DNS rotalarını güncellerken sorun yaşadı. Plan güncelleme sürecindeki bir hata, Route 53'teki rotaların silinmesine yol açtı; ardından ağ yük dengeleyicileri, işlem gücü, kuyruklar ve EKS dahil olmak üzere bu rotalara bağlı hizmetler çalışmamaya başladı. Bu temel hizmetler başka hizmetler tarafından da kullanıldığından sorun, Alexa, Ring, Slack, Snapchat, Zoom ve Shopify gibi son kullanıcıların karşılaştığı ürün ve şirketlere yayıldı; bazıları kısmen, bazıları ise tamamen etkilendi.
Newman'ın AWS raporuna dayanan açıklamasına göre sistem, DNS değişiklik planları oluşturan bir planlayıcı ve bunları uygulayan birden fazla yürütücü içeriyordu. Planlardan birinin tamamlanması normalden uzun sürdü; ardından başka bir yürütücü tarafından hızla uygulanan başka bir plan oluşturuldu. Eski planın uygulanması daha sonra tamamlandığında, yeni planın oluşturduğu rotaları kaldırdı. Sonuç, DNS girdilerinin silinmesine yol açan bir yarış koşuluydu (Race Condition).
İkinci örnek, kullanılmış otomobiller, motosikletler ve römorklar satan bir siteydi; site, Sauron kod adlı bir uygulama üzerinden on sunucuda çalışıyordu. Uygulama normalde aynı anda 30 ila 60 isteği işliyordu, ancak 800'den fazla istekle karşılaştı. Bağlı sitelerden biri bağlantıları kabul ediyor, ardından yanıt vermeden takılı kalıyordu; uygulama ise isteği sonlandırmadan önce 30 saniye bekliyordu. Bağlantı havuzu tükendi, ardından iş parçacıkları birikti ve işlemciler bunları yönetmek için zaman harcadı; bunun sonucunda sistem tamamen durdu. Kullanıcılar yenileme düğmesine tekrar tekrar basarak yükü daha da artırdı.
Çöküşü azaltmak için üç yol
Newman, tek bir “kök nedene” odaklanmanın aşırı basitleştirmeye yol açtığını düşünüyor. Kıvılcımı önlemek yararlı olabilir, ancak yangının yayılmasına izin veren tüm koşulları ele almaz. Bu nedenle dayanıklılık mühendisliği, arızaların meydana gelme olasılığını kabul eder ve etkilerini üç birbiriyle bağlantılı kategori üzerinden sınırlamaya hazırlanır:
- Riskleri azaltmak: Tehlike kaynaklarını ortadan kaldırmak veya kaynakları tüketme kapasitelerini sınırlamak. AWS olayında bu, sorun çözülene kadar otomatik DNS yönetiminin geçici olarak durdurulmasını ve bileşene yönelik daha iyi testlerin eklenmesini içeriyordu. Sauron uygulamasında ise sistemin kapasitesini aşan isteklerin birikerek çöküşe yol açmasına izin vermek yerine, belirli sayıda isteği kabul etmek ve kapasiteyi aşanları reddetmek için yük boşaltma (Load Shedding) kullanılabilirdi.
- Bileşenleri güçlendirmek: Tek bir bölümün arızasına dayanma kapasitesini çoğaltma, izleme, test ve uygulamayı iyileştirme yoluyla artırmak. Bu, hizmetin yük dengeleyicinin arkasında birden fazla kopyasını çalıştırmak anlamına gelebilir; ancak karar, bileşenin önemi ve maliyetinden ayrı düşünülemez. Sauron uygulaması emeklilik aşamasındaydı ve gelirin yalnızca bir bölümünü temsil ediyordu; bu nedenle ek yedek kopyalar çalıştırmak o dönemde ticari açıdan cazip bir seçenek değildi.
- Bağımlılığı azaltmak: Tek bir bileşenin arızasının sistemin geri kalanına yayılmasını önlemek. Buna Bulkhead'ler, zaman aşımı sınırları, alternatif yollar ve mümkün olduğunda yerel öncelikli tasarımlar dahildir. Sistemin bir bölümü başka bir bölüme ne kadar az bağımlı olursa, arızayı yaymak yerine yalıtmak o kadar mümkün olur.
Teknoloji ekipleri açısından pratikte ne değişiyor?
Dayanıklılık, sistemi otomatik olarak iki bölgede veya iki bulutta çalıştırmak anlamına gelmez. Newman, seçeneklerin yedekleme ve kurtarmadan, verileri çoğaltan ancak altyapının tamamını çalıştırmayan Pilot Light mimarisine, ardından sıcak kurtarmaya ve son olarak iki sitenin aynı anda etkin biçimde çalıştırılmasına kadar uzandığını açıklıyor. Bu seçenekler duruş süresini ve veri kaybını kademeli olarak azaltır, ancak maliyeti ve karmaşıklığı artırır.
Ayrıca siteler arasında çift yönlü eşzamanlamanın, özellikle bunun kendisi için tasarlanmamış mevcut bir uygulamaya sonradan eklendiğinde, basit bir konu olduğunu düşünmemek gerektiği konusunda uyarıyor. Aynı durum çoklu bulut kullanımı için de geçerlidir; bu yaklaşım tek bir sağlayıcıya bağımlılığı azaltabilir, ancak her platform için farklı beceriler ve işletim gerektirir. Aynı kodu AWS ve Azure'da çalıştırmak bağımsızlığı garanti etmeye yetmez, çünkü aynı yazılım kusuru her iki ortamı da devre dışı bırakabilir.
Sonuç
Temel ders, dayanıklılığın hiç arızalanmayan bir ortam aramak değil, bir bölümü arızalandığında sistemin bir bölümünün çalışmaya devam etmesini sağlayacak şekilde tasarlanması olduğudur. Bu nedenle riskler, kapasite sınırları, darboğaz noktaları ve bağımlılık yolları değerlendirilmeli; ardından çoğaltma, yalıtım ve maliyet arasında denge kurulmalıdır. Çok bölgeli veya çok bulutlu çalıştırma gibi kararlar, her sisteme uygun genel bir reçete değil, hizmetin önemine bağlı mühendislik ve ticari seçenekler olmaya devam eder.