Önce her ekibe ayrı container, sonra geri dönüş: OpenAI Habitat’ın Cosmos DB’de multi-tenancy yolculuğu
Rapidly scaling online storage to serve over 1 billion ChatGPT users (Part II)
OpenAI ürünlerinin tamamı hızlı ve güvenilir veri erişimine ihtiyaç duyuyor ve bunu Habitat adlı depolama platformu sağlıyor: 40 coğrafi bölgede 1 milyardan fazla kullanıcıya milisaniye cevap, toplamda 500 petabayttan fazla veri. Bu ikinci bölüm, altta yatan depolama bileşeni olan Azure Cosmos DB’nin nasıl ölçeklendiğini anlatıyor. Yolculuk dairesel: tek bir paylaşımlı container → her kullanım için ayrı single-tenant container → tekrar paylaşımlı container (varsayılan olarak).
Cosmos DB’ye kısa giriş. Bir hesap container’ları ve replikasyon politikasını tanımlıyor; her container belirli bir throughput için (RU/s) provision ediliyor; veri logical partition key’e göre shard’lanıyor ve fiziksel partition’lara dağıtılıyor; depolama eşiği ya da throughput ihtiyacı aşılınca fiziksel partition bölünüyor.
Faz I: yerleşik primitive’lere güvenmek. Her hesapta tek bir varsayılan container vardı ve client yükünün geçmesine izin verilip back pressure için logical partition key başına belgelenmiş 10 bin RU/s limitine güvenildi. Üç sorun çıktı. Logical partition key çakışmaları: erken API tercihleriyle partition key seçimi client’lara açılmıştı; user_id ya da workspace_id gibi yaygın key’ler farklı ürün kullanımlarında çakışıyordu. Noisy neighbor: limitler belgelerde logical partition için yazılı, ama fiilen fiziksel partition’da uygulanıyor; logical partition’lar 10 bin RU/s’e ulaşamıyor, fiziksel partition’ı paylaşıyor. Niş bir ürün özelliğinin iş yükü, çekirdek login ve signup akışlarını bozabiliyordu. Weak partition’lar: bir fiziksel partition’ın throughput limiti container’ın toplam provision edilmiş throughput’una bağlı; veri büyüdükçe fiziksel partition’lar bölünüyor, toplam throughput aynı kalıyor ve partition başına etkin limit düşüyor. Blob’a benzer, depolama ağırlıklı kullanımlarda yalnızca veri büyümesi bile, istek hızı sabitken, aktif iş yüklerinin kapasitesini azaltıyor.
Faz II: workload isolation ve single-tenancy. En kritik yeni kullanımlar için ayrı container’lar açıldı; her biri kendi fiziksel partition’larına sahip olduğundan noisy neighbor yalnızca o container’ın içinde kalıyordu. Bu birçok site çapında kesintiyi önledi ama yeni bedeller getirdi. Kararsız toplam büyüme: paylaşımlı container’da yeni bir kullanımın 0’dan 1 milyon QPS’e çıkması toplamı pek oynatmazdı; izole bir container’da bu, tabanın 1.000 katı yük olabiliyordu. Ekipler lansman öncesi container’ı önceden büyütmeyi unutuyor ve lansman gününde SEV odalarında son dakika ölçekleme yapılıyordu. Kapasite planlaması: adanmış container’ların kullanımını izlemek ürün bilgisi gerektiriyordu; yazı, bunun organizasyonel olarak ölçeklenmediğini söylüyor, çünkü her ürün ekibi Cosmos DB provisioning’ine farklı özen gösteriyordu.
Faz III: varsayılan olarak multi-tenancy, veri taşıma yeteneğiyle. Merkezi tek bir planlama ekibi olmayınca çok sayıda ekip kötü planlıyordu. Azure ekibiyle birlikte ilk multi-tenancy sorunlarına mühendislik düzeltmeleri yapıldı: hot key throttling (en sıcak key’ler önce kısılır, bir hot key site çapında etki yaratamaz), request tiering QoS (bulk insert ve veri çıkarma gibi offline iş yüklerine daha düşük öncelik verilir, böylece kısılan onlar olur, son kullanıcıya hizmet eden etkileşimli istekler değil) ve yeni bir serverless mod (her fiziksel partition 10 bin RU/s’e kadar ölçeklenebiliyor ve depolamanın yanı sıra RU kullanımına göre de bölünüyor; container’ları elle izleyip büyütme ihtiyacı kalktı). Sonuç: tek paylaşımlı container’a dönüş, önceden ya da sürekli kapasite planlamasını büyük ölçüde kaldırdı ve izolasyon korundu; sonraki aylarda provisioning ya da noisy neighbor olayı yaşanmadı.
Co-managed servis. OpenAI bu ölçekte yönetilen servislerin ‘daha az yönetilen’ hâle geldiğini söylüyor: paylaşılan testler, paylaşılan dashboard’lar, doğrudan mühendislik kanalları ve yalnızca bu ölçekte görülen hata modellerinin ortak sahipliği. En büyük hesap onlarca petabayt veri saklıyor ve saniyede 20 milyondan fazla sorgu (QPS) sunuyor. 2024 sonundaki bir bölgesel kesintide, en büyük hesapların ikinci bölgeye failover’ının saatler süreceği görüldü; hiçbir taraf bunu o ölçekte test etmemişti. Yaklaşık bir ay sonra bu hesapları eski bölgeye geri alırken (failback) bir connection stampede, eski bölgenin Cosmos DB gateway’ini bunalttı: gateway-mode client’ın failover’ı ele alış biçimindeki bir tuhaflık, tüm client’ların eski bölgeye aynı anda bağlantı açıp istek göndermesine yol açmıştı.
Öne çıkanlar
- Multi-tenancy ve single-tenancy arasındaki seçim bir kez yapılıp kalmaz; organizasyon büyüdükçe doğru cevap değişir.
- Limitler logical düzeyde belgelenmiş olsa da fiilen fiziksel düzeyde uygulanabilir; sürpriz buradan çıkar.
- Her ekibin kendi kapasitesini planlaması, ölçekte tutarsız özen yüzünden başarısız olur.
- Hot key throttling ve request QoS (offline işleri önce kısmak), paylaşımlı sistemi güvenli yapar.
- Failover’ı kendi ölçeğinde test etmeden, geri dönüşün (failback) ayrı bir kesinti riski olduğunu bilemezsin.
Neden önemli?
Multi-tenancy tartışması genelde teoride kalır. Burada tek bir ekibin üç faz boyunca ödediği gerçek bedeller var: noisy neighbor’lar, unutulan pre-scaling, organizasyonel kapasite planlaması ve en sonunda ikisinin dengesini kuran mekanizmalar (throttling, QoS).
Pratikte
Bir veritabanını birden çok özelliğin paylaştığı bir uygulamada üç somut adım: (1) İsteklere bir öncelik etiketi ver (etkileşimli / arka plan) ve arka plan işlerini ayrı bir connection pool’da ve daha düşük eşzamanlılıkla çalıştır. (2) Tek bir tenant’ın ya da kullanıcının veritabanını doyurmasını rate limit ile engelle. (3) Failover ve failback prosedürünü gerçekten bir kez dene; özellikle geri dönerken tüm client’ların aynı anda yeniden bağlanıp bağlanmadığına bak (exponential backoff ve jitter ekle).
Sözlük
- noisy neighbor
- Paylaşılan kaynağı aşırı kullanarak diğer tenant’ları yavaşlatan iş yükü.
- hot key
- Orantısız yüksek trafik alan tek bir partition key’i.
- partition key
- Verinin hangi shard’a gideceğini belirleyen anahtar.
- failover / failback
- Sorun çıkınca ikincil bölgeye geçme ve sorun giderilince eski bölgeye geri dönme.
- connection stampede
- Çok sayıda client’ın aynı anda yeniden bağlanmaya çalışarak hedefi bunaltması.
- RU/s
- Request units per second: Cosmos DB’nin throughput ölçü birimi.