Database Engineering

Veritabanı Dayanıklılığı ve Failover Testi İçin Kaos Mühendisliği Stratejileri

Bulut-native uygulamaların modern dünyasında veritabanı, birçok mühendisi uykusuz bırakan tek hata noktasıdır. Mikroservisler ve ağ katmanlarına sıklıkla kaos mühendisliği ilkelerini uygularız ancak veritabanı genellikle felaket bir kesintiye kadar test edilmemiş bir kalesi olarak kalır. Bu yaklaşım risklidir. Gerçekten dayanıklı sistemler inşa etmek için, failover mekanizalarının beklendiği gibi çalıştığını, veri bütünlüğünün korunduğunu ve kurtarma sürelerinin Hizmet Seviyesi Hedeflerimizi (SLO) karşıladığını doğrulamak amacıyla veritabanı altyapımıza proaktif olarak hatalar enjekte etmeliyiz.

Neden Veritabanı Kaos Mühendisliği Kritik Öneme Sahip?

Çoğu geliştirme ekibi, her şey çevrimiçi olduğunda sorguların sorunsuz çalıştığını garanti eden "mutlu yol" (happy-path) testlerine odaklanır. Ancak üretim ortamları doğası gereği gürültülüdür. Ağ bölünmeleri, disk G/Ç (I/O) spike'ları ve replika gecikmesi teorik riskler değil; günlük gerçekliklerdir. Bu koşulları bir önizleme (staging) veya gölge ortamda simüle ederek ekipler, son kullanıcıları etkilemeden önce replikasyon mantıklarındaki ve okuma/yazma yönlendirme stratejilerindeki gizli zayıflıkları ortaya çıkarabilir. Amaç üretimi bozmak değil, sistemin kaçınılmaz olarak bozulduğunda zarif bir şekilde toparlanacağına dair güven oluşturmaktır.

Simüle Edilmesi Gereken Temel Hata Senaryoları

Etkili kaos mühendisliği yapılandırılmış bir yaklaşım gerektirir. Rastgele tahribat yerine, kullanılabilirliği ve tutarlılığı etkileyen belirli hata modlarını hedefleyin.

1. Ağ Bölünmesi (Network Partitioning)

Uygulama katmanı ile veritabanı arasında veya birincil ve ikincil replikalar arasında ağ kesintilerini simüle edin. Bu, bağlantı havuzu kütüphanelerinizi ve devre kesicilerinizi (circuit breakers) test eder. Örneğin, PostgreSQL için PgBouncer gibi bir proxy kullanıyorsanız, bir bölünme sırasında aktif işlemleri düşürmeden bağlantı değişimlerini (connection churn) nasıl ele aldığınıza emin olmalısınız.

2. Replika Gecikmesi ve Split-Brain (Beyin Bölünmesi)

Okuma replikalarına yapay olarak gecikme ekleyin. Bu, uygulamanızın eski okumaları (stale reads) işlemesini veya birincil düğüme düşmesini zorlar. Daha tehlikeli olanı, bir failover'dan sonra birincil düğümün hala lider olduğunu düşündüğü "split-brain" senaryolarını test etmektir; bu durum veri sapmasına yol açabilir.

3. Disk G/Ç Doygunluğu

Veritabanı sunucusundaki disk alanını doldurun veya IOPS'yi doygunluğa ulaştırın. Bu, veritabanının kaynak kısıtlamaları altında yoğun yazma yüklerini ne kadar zarif bir şekilde ele aldığını ortaya çıkarır. İstekleri kuyruğa alır mı? Çöker mi? Otomatik ölçeklendirme olayını tetikler mi?

AWS ve Python ile Pratik Uygulama

Bu testleri programlı olarak uygulamak tekrarlanabilirlik sağlar. AWS Fault Injection Simulator (FIS) gibi bir araç veya chaospy kütüphanesi veya basit AWS SDK çağrıları ile özel komut dosyaları kullanmak, kaos üzerinde hassas kontrol sağlar.

Aşağıda, bir veritabanı örneği için kısmi bir ağ kesintisini taklit edebilen bir EC2 ağ arayüzü hatasını simüle etmek için AWS SDK kullanan kavramsal bir Python örneği bulunmaktadır:

import boto3
import time

def simulate_network_latency(db_instance_id, severity="high"):
    """
    AWS ortamında hedef bir veritabanı örneği için ağ bozulmasını veya kesilmesini simüle eder.
    """
    ec2 = boto3.client('ec2', region_name='us-east-1')
    
    # Veritabanı örneğiyle ilişkili ağ arayüzünü bulun
    # Not: Üretimde, bu mantık hassas etiketleme veya ARN araması gerektirir
    response = ec2.describe_network_interfaces(
        Filters=[
            {
                'Name': 'tag:aws:cloudformation:stack-name',
                'Values': ['my-database-stack']
            }
        ]
    )
    
    if response['NetworkInterfaces']:
        interface_id = response['NetworkInterfaces'][0]['NetworkInterfaceId']
        print(f"Hedeflenen Ağ Arayüzü: {interface_id}")
        
        # Bölünmeyi simüle etmek için geçici olarak ağ erişimini durdurun
        # Bu yıkıcı bir işlemdir; otomatik kurtarma planınız olduğundan emin olun
        try:
            ec2.modify_network_interface_attribute(
                NetworkInterfaceId=interface_id,
                Groups=[] # Güvenlik gruplarını ayırarak örneği etkili bir şekilde izole eder
            )
            print("Ağ izolasyonu başlatıldı. Metrikler izleniyor...")
            
            # Tanımlanmış kaos süresi kadar bekleyin
            time.sleep(60)
            
            # Ağı geri yükleyin
            print("Ağ bağlantısı geri yükleniyor...")
            
        except Exception as e:
            print(f"Kaos enjeksiyonu sırasında hata: {e}")

# Simülasyonu çalıştırın
if __name__ == "__main__":
    simulate_network_latency("db-master-instance-id")

Başarıyı ve Kurtarmayı Ölçme

Deneyle çalışmak savaşın sadece yarısıdır. Net başarı kriterleri tanımlamalısınız. Temel metrikler şunlardır:

  • Ortalama Tespit Süresi (MTTD): İzleme sisteminiz (örn. Prometheus, CloudWatch) anormalliği ne kadar hızlı işaretler?
  • Ortalama Kurtarma Süresi (MTTR): Uygulamanın başarılı bir şekilde yeniden bağlanması ve normal işlemlere devam etmesi ne kadar sürer?
  • Veri Kaybı: Herhangi bir işlem replike edilemedi mi? Kritik veritabanları için bu sıfır olmalıdır.

Sonuç

Veritabanları için kaos mühendisliği, hatayı aramakla ilgili değildir; bunun için tasarlamakla ilgilidir. Failover mekanizalarını, replikasyon gecikmesi yönetimini ve bağlantı dayanıklılığını sistematik olarak test ederek veritabanı mühendisleri, sistemlerini kırılgan monolitlerden sağlam, kendini iyileştiren mimarilere dönüştürebilir. Küçük başlayın, deneylerinizi izole edin ve her zaman bir geri alma (rollback) planınız olsun. Önizleme ortamındaki kontrollü bir testin maliyesi, planlanmamış bir üretim kesintisinin maliyetine kıyasla önemsizdir. Kaosu kucaklayın, veritabanınız daha güçlü duracaktır.

Share: