1K'dan 10K RPS'e Karmaşıklık Patlaması
Saniyede 1K istekten 10K'ya ölçeklenmek aynı problemin daha büyük bir versiyonu değil — başka bir problemdir. Bir yıl boyunca sessizce çalışan mimari 10 katta zarifçe bozulmadı; panolarımızın daha önce hiç göstermediği biçimlerde çöktü.
1K RPS'te işe yarayanlar:
- Varsayılan timeout'larla senkron servisler arası çağrılar
- Karmaşık sorgular için veritabanı join'leri
- CloudWatch'a tam debug logları, örnekleme yok
- Basit round-robin yük dengeleme
İlk kırılma: bağlantılar
1K RPS'te, PostgreSQL max_connections değeri 500 iken kabaca 120 veritabanı bağlantısı tutuyorduk — rahat. 4K RPS'i geçince autoscaler pod sayısını üçe katladı, her yeni pod kendi 20 bağlantılık havuzunu açtı ve dakikalar içinde tavana çarptık. Sorgular kuyruğa girdi, gecikme tırmandı ve upstream'deki her şey timeout vermeye başladı. Bu arıza biçimi o kadar yaygın ki kendi yazısını hak etti: veritabanımızı öldüren autoscaler.
İkinci kırılma: zincirleme timeout'lar
Çağrı zincirimiz API → orders → pricing → inventory şeklindeydi; her adımda 30 saniyelik varsayılan timeout ve üç retry vardı. Inventory yavaşlayınca üstündeki her adım retry yaptı ve trafik her seviyede kabaca üçe katlandı — p99 gecikmesini 80 ms'den 10 saniyenin üzerine iten bir retry fırtınası; bu sırada worker thread'ler zaten boğulmakta olan bir bağımlılığı bekleyerek bloke duruyordu.
Üçüncü kırılma: gözlemlenebilirlik faturası
Log hacmi trafikle doğrusal ölçeklenir: 10 kat istek, 10 kat CloudWatch ingestion demekti ve loglama sessizce en büyük ikinci altyapı kalemimiz oldu. Debug seviyesindeki logları %1 oranında örneklemeye geçtik — bizim için doğru oran, çünkü 10K RPS'te bu hâlâ saniyede yaklaşık 100 debug olayı üretir; bir olayı teşhis etmeye fazlasıyla yeter. Hatalar ve uyarılar asla örneklenmez. Örnekleme yüksek hacimli, düşük sinyalli olaylar içindir; doğru oran evrensel bir sabit değil, trafiğinizin bir fonksiyonudur.
Gereken yeni desenler:
- PgBouncer ile connection pooling artı read replica'lar
- Timeout bütçeleri: zincir boyunca aşağı aktarılan deadline'lar, sınırlandırılmış ve jitter'lı retry'lar
- Senkron fan-out yerine ani yükleri emen kuyruk destekli yazmalar
- İstekler uygulama koduna ulaşmadan önce, edge'de rate limiting
- Cache hot key'leri için key-splitting — tek bir tenant'ın session key'i, tek bir Redis shard'ındaki operasyonların üçte birini oluşturuyordu
İçgörü:
Her büyüklük mertebesinde farklı problemler çözüyorsunuz. 1K'da çalışan mimari 10K'da ayakta kalmaz; 10K tasarımı da 100K'da yeni arıza biçimleriyle tanışır. Sizinkileri erkenden bulmanın tek ekonomik yolu, gerçek trafik bunu sizin yerinize yapmadan önce 10 kat yük testi yapmaktır — teslimat hatlarına ve release mühendisliğine tek seferlik değil, kalıcı bir pratik olarak gömdüğümüz türden bir tatbikat.
Ders: Ölçek testi opsiyonel değildir. 10 kat trafik gününüz her zayıflığı bulacak — tek soru, önce sizin bulup bulmayacağınız.
Bu tür olaylar önlenebilir. AWS Yönetilen Hizmetler ekibimiz müşteri ortamlarını yapay zekâ destekli izleme ve nöbetteki kıdemli mühendislerle 7/24 gözetir — böylece bu tür hikâyeler arşivde kalır.