Data flow diagram with server stacks

OpenAI 800 Milyon Kullanıcıyı PostgreSQL ile Nasıl Ölçekledi?

Bu yazı, OpenAI’ın ChatGPT gibi yüz milyonlarca kullanıcıya hizmet veren bir sistemi PostgreSQL kullanarak nasıl ölçeklendirdiğini anlatır. Yazıda read replica kullanımı, sorgu optimizasyonu, caching, connection pooling ve sharding gibi tekniklerle büyük ölçekli bir veritabanı mimarisinin nasıl verimli şekilde çalıştırılabildiği sade bir şekilde açıklanmaktadır.

Giriş

Büyük ölçekli sistemler konuşulurken genellikle çok karmaşık mimariler hayal edilir: yüzlerce servis, dağıtık veri tabanları, karmaşık sharding stratejileri… Ancak gerçek dünyada işler çoğu zaman daha sade başlar.

OpenAI’ın paylaştığı bir teknik yazı ve bu yazıyı anlatan video, ChatGPT’nin yüz milyonlarca kullanıcıya ulaşmasına rağmen veri tabanı tarafında oldukça basit bir mimariyle çalıştığını gösteriyor.

Temel yapı şu:

  • 1 adet PostgreSQL primary (yazma) sunucusu
  • 50 adet read replica (okuma kopyası)

İlk bakışta şaşırtıcı gelebilir. Ama aslında bu yaklaşım, modern sistem tasarımında çok önemli bir prensibi hatırlatıyor:

Önce basit başla, sorunlar ortaya çıktıkça ölçeklendir.

Bu yazıda, OpenAI’ın PostgreSQL’i bu ölçekte nasıl kullandığını ve hangi optimizasyonları yaptığını sade bir şekilde anlatacağım.


1. Büyük Sistemler Aslında Basit Başlar

Hiç kimse ilk gününden sharding yapan dağıtık veri tabanı mimarisi ile başlamaz.

Genellikle süreç şu şekilde ilerler:

  1. Basit bir veritabanı kurulur
  2. Kullanıcı sayısı artar
  3. Performans sorunları görülür
  4. Optimize edilir

OpenAI da aynı yolu izlemiş.

Önce:

  • uygulama kodu optimize edilmiş
  • veritabanı parametreleri ayarlanmış
  • sunucu vertical scaling ile büyütülmüş
  • ardından read replica sayısı artırılmış

Çünkü ChatGPT gibi bir sistemde çoğu işlem okuma ağırlıklıdır.


2. Read Replica Stratejisi

Read replica, veritabanının sadece okuma yapan kopyalarıdır.

Yapı şu şekilde çalışır:

Primary DB
   |
   | replication
   |
---------------------------------
|       |       |       |       |
Replica Replica Replica Replica ...

Bu sayede:

  • Okuma yükü dağıtılır
  • Primary veritabanı rahatlar
  • Sistem daha ölçeklenebilir hale gelir

OpenAI bu yapıda 50 read replica kullanıyor.

Bu sayı kulağa çok gibi gelebilir ama milyonlarca kullanıcı için oldukça normal.


3. Yazma Yükü Neden Daha Zordur?

Okuma işlemleri kolay ölçeklenir.

Yeni read replica eklemek genellikle yeterlidir.

Ancak write (yazma) işlemleri çok daha karmaşıktır.

PostgreSQL’de bunun sebeplerinden biri MVCC (Multi-Version Concurrency Control) mekanizmasıdır.

MVCC şu şekilde çalışır:

Bir satır güncellendiğinde:

  • eski satır silinmez
  • yeni bir versiyon oluşturulur

Bu durum iki probleme yol açar:

Write Amplification

Her güncelleme yeni veri üretir.

Read Amplification

Okuma sırasında sistem doğru versiyonu bulmak için birden fazla versiyonu kontrol eder.

Büyük ölçekte bu durum performans sorunlarına yol açabilir.


4. Lazy Write Stratejisi

OpenAI’ın yaptığı önemli optimizasyonlardan biri:

Lazy writes

Yani:

Gerçek zamanlı yapılması gerekmeyen yazma işlemleri toplu olarak yapılır.

Bu yaklaşımın faydaları:

  • veritabanına daha az write gider
  • write işlemleri batch olarak yapılır
  • sistem yükü azalır

Bu aslında performans dünyasında çok önemli bir kuraldır:

Gerçek zamanlı olmak zorunda olmayan hiçbir işlem gerçek zamanlı yapılmamalıdır.


5. Karmaşık SQL Sorgularını Azaltmak

Veritabanı performansını en çok etkileyen şeylerden biri karmaşık join sorgularıdır.

OpenAI’ın blogunda verilen örneklerden biri oldukça dikkat çekici:

Bir sorgu 12 tabloyu join ediyordu.

Bu tür sorgular:

  • CPU tüketimini artırır
  • veritabanını kilitleyebilir
  • diğer istekleri yavaşlatır

Bunun yerine yapılan şey:

  • join yerine birden fazla SELECT
  • bazı mantıkları application layer’a taşımak

Bu sayede:

  • bazı veriler cache’ten gelebilir
  • bazıları read replica’dan
  • veritabanının yükü azalır

6. ORM Sorgularına Körü Körüne Güvenmemek

Modern backend projelerinde ORM kullanmak çok yaygındır.

Ama ORM tarafından üretilen SQL her zaman en verimli SQL değildir.

Bu nedenle yapılan şey:

  • ORM sorgularını analiz etmek
  • gerekirse manuel SQL yazmak
  • indeks kullanımını kontrol etmek

Özellikle şu problem çok yaygındır:

N+1 Query Problemi

Bu problem yüzünden tek bir API çağrısı:

  • 1 sorgu yerine
  • 100+ sorgu çalıştırabilir

Büyük sistemlerde bu fark dramatiktir.


7. Connection Pooling (PgBouncer)

PostgreSQL’de her yeni bağlantı yeni bir process oluşturur.

Bu pahalı bir işlemdir.

Bu yüzden çoğu sistem PostgreSQL’in önüne bir connection pooler koyar.

En yaygın araçlardan biri:

PgBouncer

PgBouncer şu işi yapar:

  • 1000 client bağlantısını kabul eder
  • veritabanına sadece 50 bağlantı açar
  • bağlantıları yeniden kullanır

Bu sayede:

  • bağlantı sayısı kontrol altında kalır
  • latency düşer
  • sistem daha stabil çalışır

8. Cache Kullanımı

ChatGPT gibi sistemler yoğun şekilde cache kullanır.

Ama cache’in bir problemi vardır:

Cache miss

Cache miss olduğunda:

  • tüm istekler veritabanına gidebilir
  • bu da ani yük patlamasına neden olur

Bunu önlemek için kullanılan teknik:

Cache Locking

Mantık şu:

Cache boşsa:

  • sadece 1 istek veritabanına gider
  • diğerleri bekler

Bu sayede veritabanı ani yükten korunur.

Bu yöntem CDN’lerde de kullanılır.


9. Single Point of Failure Nasıl Azaltıldı?

OpenAI mimarisinde:

  • read replica’lar okuma yapar
  • primary yazma yapar

Primary çökerse ne olur?

Bunun için hot standby kullanılır.

Hot standby:

  • aktif trafik almaz
  • primary ile senkronize çalışır
  • primary ölürse hemen devreye girer

Bu sayede sistem tamamen çökmez.


10. Sharding’e Geçiş

OpenAI şu anda bazı iş yüklerini sharded veritabanlarına taşımaya başlamış.

Örneğin:

  • Azure Cosmos DB

Özellikle yeni özellikler için:

  • doğrudan sharded mimari tercih ediliyor

Ama önemli bir detay var:

Eski sistem tamamen terk edilmemiş.

Yani sistem evrimsel olarak büyüyor.


11. Cascading Replication

50 read replica bile bir noktada limit olabilir.

Bunun çözümü olarak düşündükleri yöntem:

Cascading replication

Yapı şu şekilde:

Primary
   |
Intermediate Replica
   |
--------------------------------
|      |      |      |      |
Replica Replica Replica Replica

Yani:

Primary → ara replica → read replica

Bu yöntem sayesinde:

  • primary üzerindeki replication yükü azalır
  • daha fazla replica eklenebilir

Sonuç

OpenAI’ın PostgreSQL mimarisine baktığımızda aslında çok önemli bir ders görüyoruz:

Büyük ölçekli sistemler her zaman karmaşık olmak zorunda değildir.

Doğru optimizasyonlarla:

  • read replica kullanımı
  • query optimizasyonu
  • caching
  • connection pooling
  • lazy writes

gibi tekniklerle tek bir veritabanı bile yüz milyonlarca kullanıcıya hizmet verebilir.

Asıl önemli olan şey:

  • sistemin darboğazlarını anlamak
  • doğru yerde doğru optimizasyonu yapmak

Çoğu zaman “yeni teknoloji” değil, mevcut sistemi doğru kullanmak daha büyük fark yaratır.


Bu yazı “How OpenAI Handles 800 Million ChatGPT Users on a Single PostgreSQL Primary” videosundan ilham alınarak yazılmıştır.

Kaynakça:

Leave a Reply

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir