Editörden

Netflix'in gerçek zamanlı dağıtık graf serisinin üçüncü bölümü: ingestion ve depolama bitti, şimdi sorgulama. İçinde her backend mühendisinin tanıdığı bir problem var: ardışık ağ çağrılarının gecikmeyi nasıl yediği.

Günün Kapağı
Netflix Tech Blog 7 Ağustos 202622 dk okuma ileri

Milyar kenarlı grafı 100 ms altında sorgulamak: önce genişlik, async ve tek istek

How and Why Netflix Built a Real-Time Distributed Graph: Part 3 — Querying the graph with gRPC… · Netflix Technology Blog

Netflix'in Real-Time Distributed Graph (RDG) serisinin ilk iki bölümü veriyi grafa dökmeyi (Flink ile ingestion) ve milyarlarca düğüm ve kenarı tek haneli milisaniye gecikmeyle depolamayı anlatmıştı. Bu bölüm asıl soruyu soruyor: sürekli büyüyen milyar kenarlı bir grafı, çok farklı iş yükleri için nasıl 100 ms altında cevaplatırsın? RDG şu an saniyede on binlerce, her biri farklı sorguya hizmet veriyor.

Sorgular iki uçta duruyor. Sığ ve geniş: yüksek hacimli güvenlik aramaları gibi, her adımda çok dallanan, I/O işleyen sorgular. Derin ve dar: “bu hesabın tüm profillerinde Stranger Things izleme geçmişi” gibi, bir adımın sonucunu beklemeden sonrakine geçemeyen, 3-4 adım zincirlenebilen sorgular. Her adım 10 ms ağ süresi tutarsa iki adım bir bayt işlenmeden 20 ms demek.

Tasarım kararları net: tüm çok adımlı mantığı tek bir gRPC isteğine paketlemek; derinlik-öncelikli değil genişlik-öncelikli gezinmek, çünkü her adım bir ağ çağrısı ise bir seviyedeki tüm düğümleri toplu sorgulayıp paralel çağrılarla ilerlemek, yol yol gitmekten çok daha ucuz; ve thread-per-request yerine async çalışmak, çünkü gecikmeyi I/O belirliyor. Genişlik-öncelikli yaklaşımın bedeli bellek: her seviye bellekte tutuluyor, bunu kenar tipi başına sınırlarla yönetilebilir tutuyorlar.

Öne çıkanlar

  • Gecikme bütçesini hop sayısı belirler; ardışık ağ çağrıları toplam süreye doğrusal biner.
  • Genişlik-öncelikli gezinme, bir seviyedeki aramaları toplu ve paralel yapmayı mümkün kılar.
  • Bellek bedeli kenar tipi başına sınırlarla sınırlanıyor: yüksek dallanma seviyesi bile yönetilebilir kalıyor.
  • I/O ağırlıklı serviste thread başına istek yerine async model, boşta bekleyen thread'leri ortadan kaldırıyor.

Neden önemli?

Dağıtık sistemde performansı çoğunlukla algoritma değil, ağ turu sayısı belirler. “Kaç kez ağa çıkıyorum?” sorusu, “işlem kaç adım?” sorusundan daha belirleyicidir.

Sende karşılığı

Bunun en tanıdık hâli JPA'daki N+1 sorgu problemi: bir listeyi çekip her satır için ayrı sorgu atmak, derinlik-öncelikli gezinmenin tam karşılığı. Çözümün adı da aynı: toplu yükleme (JOIN FETCH, IN (...) ile batch). Mobit'teki mesajlaşma ve doküman listelerinde Spring Boot'un SQL loglarını açıp bir ekran için kaç sorgu attığını say; sayı sayfadaki öğe sayısıyla büyüyorsa aynı hatadasın.

Sözlük

breadth-first traversal genişlik-öncelikli gezinme
Grafı yol yol değil seviye seviye dolaşma; aynı seviyedeki tüm düğümleri birlikte işleme.
fan-out dallanma
Bir düğümden çıkan bağlantı (kenar) sayısı; yüksekse sorgu hızla genişler.
async I/O eşzamansız G/Ç
Ağ ya da disk yanıtını beklerken thread'i bloklamayan çalışma modeli.
Orijinali oku