Geleneksel Sunucusuz Sistemlerde Soğuk Başlangıç ​​Sorunu

2024'te bir Datadog analizi, üretimdeki Lambda çağrılarının %40'ının 500 ms'yi aşan soğuk başlatmalardan muzdariptir. Python veya Java fonksiyonları için bu sayı 1-3 saniyeye çıkar. Soğuk başlangıç, bir isteğin geldiği andan, isteğin gerçekleştiği ana kadar geçen süredir. fonksiyon aslında onu işlemeye hazır: başlaması için gereken süre bu bir konteyner, çalışma zamanını yükleyin, bağımlılıkları başlatın.

Cloudflare Workers tamamen farklı bir yaklaşım benimsiyor: konteynerler yerine kullanıyor V8 İzolatları. Ölçülebilir sonuç: ortalama başlatma daha az 1ms, terimin geleneksel anlamında sıfır "soğuk başlangıç". Neden aşağı inmeyi gerektirdiğini anlamak V8 motor mimarisini ve süreç izolasyon modelini detaylandırıyor.

Ne Öğreneceksiniz

  • V8 İzolatı nedir ve işletim sistemi işleminden veya Docker kapsayıcısından farkı nedir?
  • Konteynerlerde neden yapısal soğuk başlatma sorunu yaşanıyor ve bunlar kendilerini nasıl gösteriyor?
  • Cloudflare Workers yürütme modeli: istek yönlendirmeden izolasyon havuzuna kadar
  • Snapshot V8: JavaScript başlatma maliyetini ortadan kaldıran teknik
  • Yalıtılmış model sınırlamaları: CPU süresi, bellek, kullanılabilir API'ler
  • Karşılaştırma karşılaştırması: İşçiler vs Lambda vs Lambda@Edge
  • İşçiler ne zaman kullanılmalı ve konteynerler ne zaman doğru seçim olmaya devam ediyor?

Kaplar, Süreçler ve İzolatlar: Bir Taksonomi

İzolatları anlamak için öncelikle neyin yerini aldıklarını anlamalısınız. Her seviye soyutlamanın farklı bir başlangıç maliyeti vardır:

İlkel Yalıtım Tipik başlangıç Bellek yükü Örnekler
VM (hipervizör) Donanım 10-60 saniye 512 MB - 2 GB EC2, GCE, Azure VM
Kapsayıcılar (Linux ad alanları) Çekirdek (gruplar + ad alanları) 100ms - 2s 50-500MB Docker, Lambda, Bulut Koşusu
İşletim Sistemi Süreci Çekirdek (PID, VAS) 10-100ms 10-100 MB Node.js, Python işlemi
V8 İzole Çalışma zamanı (ayrı yığın, paylaşılan bellek yok) < 1ms 1-10 MB Cloudflare Çalışanları, Deno Dağıtımı

Un V8 İzole V8 JavaScript yığınının yalıtılmış bir örneğidir: kendi yığın ayırıcınız, kendi JavaScript nesneleriniz, kendi çöp toplayıcınız. İki izolat JavaScript belleğini paylaşmazlar ve birbirlerine müdahale edemezler. işte bu İşçi güvenliği izolasyonunun temeli, ancak mimari sonucu İzolat oluşturmanın milisaniyeler değil, mikrosaniyeler süren bir işlem olduğunu biliyoruz.

Lambda Neden Soğuk Başlangıçlardan Acı Çekiyor?

Bir kap olmadan "soğuk" (sıcak değil) Lambda işlevine bir istek geldiğinde önceden tahsis edilmiş), AWS'nin şu sırayı yürütmesi gerekir:

# Sequenza di cold start Lambda (Node.js 20)
1. Allocazione risorse compute (EC2/Firecracker VM)      ~50-200ms
2. Download immagine container dal registro              ~50-300ms (dipende dalla dimensione)
3. Setup rete: VPC, ENI attachment (se VPC configurata) ~200-1000ms (!)
4. Avvio runtime Node.js                                 ~30-80ms
5. Caricamento dependencies (node_modules)               ~20-200ms
6. Esecuzione handler initialization code               ~10-500ms
7. Prima invocazione effettiva                           ----------

Totale cold start: 360ms - 2.28 secondi (VPC worst case: fino a 3-5s)

Firecracker (AWS tarafından kullanılan microVM), VM başlatma süresini yaklaşık 125 ms'ye düşürdü, ancak yapısal sorun devam ediyor: her yürütme ortamı yalıtılmış bir kapsayıcıdır her soğuk çalıştırmada sıfırdan başlatılması gereken çekirdek düzeyinde.

V8 İzolatları: İşçi Mimarisi

Cloudflare İşçileri çalışıyor çalışantarafından yayımlanan açık kaynak çalışma zamanı 2022'de Cloudflare. Her PoP (Varlık Noktası, dünya çapında 300'den fazla var) çalıştırılır çalışılan süreçlerden oluşan bir filo. Bir istek geldiğinde:

Sequenza di gestione richiesta in Cloudflare Workers:

1. Richiesta arriva al PoP Cloudflare piu vicino        ~0ms (BGP anycast routing)
2. Routing al processo workerd appropriato               ~0.1ms
3. Lookup/allocation dell'isolate per questo Worker      ~0.5ms (da pool precreato)
4. Esecuzione del fetch handler                          ~0.1ms overhead
5. Risposta

Totale "startup": < 1ms

Kilit nokta 3. adımdadır: Worked bir izolat havuzu önceden başlatılmış. Her izolat İşçi kodunu zaten yüklemiştir sayesinde V8 Anlık Görüntüleri.

V8 Anlık Görüntüleri: Yığın Durumunu Serileştir

V8, "anlık görüntü" adı verilen ikili formatta yığın serileştirmesini destekler. Ne zaman Bir Çalışanı, Cloudflare'i konuşlandırın:

  1. Worker'ın JavaScript kodunu geçici olarak izole ederek çalıştırır
  2. Kodun başlatma işlemini tamamlamasına izin verin (modül değerlendirmesi)
  3. Yalıtılmış yığını ikili anlık görüntü halinde serileştirin
  4. Bu anlık görüntüyü PoP'lara dağıtır
  5. Sıfırdan değil, bu anlık görüntüden (seri durumdan çıkarma) yeni izolatlar oluşturulur
// Il tuo Worker ha questa struttura:
import { Router } from 'itty-router';

// Questo codice viene eseguito durante il "module evaluation"
// e serializzato nello snapshot
const router = new Router();

router.get('/users/:id', async ({ params, env }) => {
  const user = await env.DB.get(`user:${params.id}`);
  return Response.json({ user });
});

// Il fetch handler e il punto di ingresso per ogni richiesta
export default {
  fetch: router.fetch
};

// Quando un isolate viene creato dallo snapshot:
// - router e gia costruito e configurato
// - tutte le route sono gia registrate
// - NON c'e alcun costo di module evaluation per ogni richiesta

Bu Lambda'da olanlardan temel olarak farklıdır: Lambda'da, her soğuk başlatma, tüm modül başlatma kodunu yeniden yürütmelidir. İşçilerde, bu aşama dağıtım sırasında yalnızca bir kez gerçekleşti.

Güvenlik Yalıtımı: V8 Sandbox

Yaygın bir itiraz şudur: "Eğer birden fazla İşçi aynı süreçte çalışıyorsa, nasıl izole edilmişler mi?" Cevap şu: V8 Korumalı Alanı, bir mekanizma çok katmanlı:

V8 Yalıtım Katmanları

  • Yığın ayırma: Her izolatın tamamen ayrı bir yığını vardır. Başka bir izolatın belleğine JavaScript aracılığıyla erişilemiyor.
  • Paylaşılan değiştirilebilir durum yok: Bir İşçinin global değişkenleri diğer Çalışanlar tarafından görülebilir.
  • Kontrollü API'ler: Tehlikeli işlevlere erişim (dosya sistemi, ağ ham, süreç), V8'in kendisi tarafından değil, çalışılan çalışma zamanı tarafından kontrol edilir.
  • Korumalı alan V8: V8, aşağıdakileri engelleyen sanal alan mekanizmaları içerir: İsteğe bağlı makine kodunu yürütmek veya harici belleğe erişmek için JavaScript onun yığınından.
  • Ek süreç izolasyonu: işçi olabilir Mevcut sistem çağrılarını filtrelemek için secmp-bpf ile yapılandırılmıştır.

Model risksiz değil: V8 ayrıştırıcısındaki güvenlik açıkları teorik olarak izolattan kaçışa izin verir. Cloudflare'in bir hata ödül programı var V8'i özel olarak tahsis eder ve düzenli olarak günceller. Yüksek güvenlikli iş yükleri için Cloudflare şunları sağlar: daha sıkı izolasyon yöntemleri.

İzolat Modelinin Sınırlamaları

Soğuk başlatmanın yokluğunun bir maliyeti vardır: Yalıtılmış model, konteynerlerin kullanacağı kısıtlamaları empoze eder. sahip değiller:

Sınır Cloudflare Çalışanları (ücretsiz/ücretli) AWS Lambda'sı
İstek başına CPU süresi 10ms (ücretsiz) / 30s (ücretli, duraklamalı) 15 dakika
Maksimum bellek 128MB 10 GB
Paket boyutu 10 MB (sıkıştırılmış) / 1 MB (ücretsiz) 250MB sıkıştırılmış
Doğrudan TCP Sınırlı (İşçi TCP Soket API'si) Tam erişim
Dosya sistemi Müsait değil /tmp (512MB)
Çalışma zamanı dilleri JavaScript/TypeScript/WASM Herhangi
Node.js uyumluluğu Kısmi (nodejs_compat bayrağı) Tamamlamak

sınırı CPU zamanı anlaşılması gereken en önemli şey: bu bir duvar saati zaman aşımı değil. İşçiler aslında CPU süresini ölçüyor tüketildi. Bir Çalışan çok sayıda eşzamansız G/Ç çağrısı (getirme, KV) yapabilir CPU zamanını tüketir. Sınır yalnızca çalışan JavaScript kodu için geçerlidir.

Karşılaştırma: İşçiler vs Lambda vs Lambda@Edge

Kamuya açık kıyaslamalara ve resmi belgelere (2025) dayanan bir karşılaştırmayı burada bulabilirsiniz:

Metrik Cloudflare Çalışanları AWS Lambda (Node.js) Lambda @ Kenar Vercel Kenar İşlevleri
Soğuk başlatma P50 < 1ms ~200ms ~100ms < 5ms
Soğuk başlatma P99 < 5ms ~1500ms ~500ms < 50ms
Küresel PoP'lar 300+ ~30 bölge ~450 (ancak sınırlı) ~100+
Küresel ortalama gecikme ~10 ms (kenarda) ~50-200ms (bölgesel) ~25-100ms ~30ms
Ücretsiz katmanlar 100K talep/gün 1 milyon talep/ay 1 milyon talep/ay (paylaşılan Lambda) 100 GB-saat/ay

Minimal Çalışan: Uygulama Modelini Anlamak

Açıklananları somut hale getirmek için işte mümkün olan en basit kod bir İşçinin yaşam döngüsünü gösterir:

// worker.ts - formato ES Module (obbligatorio con isolates moderni)

// FASE 1: Module evaluation (eseguita UNA VOLTA, serializzata nello snapshot)
console.log('Questo viene eseguito solo al deploy, non per ogni richiesta');

const CONFIG = {
  version: '1.0',
  region: 'auto',
};

// FASE 2: Export del handler - il punto di ingresso per ogni richiesta
export default {
  // Chiamato per ogni HTTP request
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    // request: la richiesta HTTP
    // env: i binding (KV, R2, D1, secrets, variables)
    // ctx: context per waitUntil() - operazioni post-risposta

    const url = new URL(request.url);
    const path = url.pathname;

    // ctx.waitUntil() permette operazioni asincrone dopo la risposta
    ctx.waitUntil(logRequest(request, env));

    if (path === '/health') {
      return new Response(JSON.stringify({
        status: 'ok',
        config: CONFIG,
        timestamp: Date.now(),
      }), {
        headers: { 'Content-Type': 'application/json' },
      });
    }

    return new Response('Not Found', { status: 404 });
  },
};

async function logRequest(request: Request, env: Env): Promise<void> {
  // Questo viene eseguito dopo che la risposta e gia stata inviata
  // Non blocca il client
  await env.ANALYTICS_KV.put(
    `log:${Date.now()}`,
    JSON.stringify({
      url: request.url,
      method: request.method,
      cf: request.cf, // Informazioni Cloudflare: paese, ASN, datacenter, etc.
    })
  );
}

// Interfaccia per i binding definiti in wrangler.toml
interface Env {
  ANALYTICS_KV: KVNamespace;
  API_KEY: string; // secret
}

Eşzamanlılık Modeli: Bir İzolasyon, Birçok İstek

İnce ama önemli bir husus: Her çağrının bir anlamı olduğu Lambda'dan farklı olarak İşçilerde kendi izole ortamı aynı izolat işleyebilir birden fazla rekabet eden istek. Bu mümkün çünkü JavaScript, olay döngüleriyle tek iş parçacıklıdır, dolayısıyla gerçek bir olay döngüsü yoktur. Paylaşılan durumda eşzamanlılık, ancak G/Ç'ye bağlı istekler çoğaltılabilir.

// ATTENZIONE: stato globale condiviso tra richieste
// In Lambda questo non sarebbe un problema (ogni invocazione ha il suo processo)
// In Workers, piu richieste possono condividere lo stesso isolate

// SBAGLIATO: questo contatore e condiviso tra tutte le richieste
let requestCount = 0;

export default {
  async fetch(request: Request): Promise<Response> {
    requestCount++; // Race condition! Non fare questo.
    return new Response(`Request #${requestCount}`);
  },
};

// CORRETTO: usa ctx.waitUntil() per operazioni post-risposta
// e storage esterno (KV) per contatori condivisi
export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    const count = parseInt(await env.COUNTERS.get('requests') ?? '0') + 1;
    ctx.waitUntil(env.COUNTERS.put('requests', String(count)));
    return new Response(`Requests: ${count}`);
  },
};

İşçilerin Küresel Durumu: Dikkat

Lambda'nın (her çağrının izole edildiği yer) aksine, İşçilerde durum Global JavaScript, dahili eşzamanlı istekler arasında paylaşılabilir aynı izole edilmiş. gereken veriler için her zaman harici depolamayı (KV, D1, R2) kullanın. devam eder veya paylaşılır. Değişmez global değişkenler (yapılandırma, yönlendirici) onlar güvende; Değişken değişkenler tehlikelidir.

Workerd: Açık Kaynak Çalışma Zamanı

Eylül 2022'de Cloudflare onu açık kaynak haline getirdi çalışan (github.com/cloudflare/workerd), İşçilere güç veren çalışma zamanı. Bu onun vardı önemli sonuçlar:

  • Deno Dağıtımı benzer mimariye sahip V8 izolatlarını benimsedi
  • Mini alev (yerel simülatör) v3'ten bu yana dahili olarak Workd'ü kullanıyor
  • Özel ortamlar için şirket içinde çalışan çalıştırabilirsiniz
  • Topluluk çalışma zamanına katkıda bulunabilir ve güvenlik kodunu inceleyebilir
# Architettura workerd (semplificata)

┌─────────────────────────────────────────────────┐
│                  workerd process                │
│                                                 │
│  ┌──────────────┐  ┌──────────────┐            │
│  │  Isolate #1  │  │  Isolate #2  │   ...      │
│  │  (Worker A)  │  │  (Worker B)  │            │
│  │              │  │              │            │
│  │  V8 Heap A   │  │  V8 Heap B   │            │
│  │  (isolato)   │  │  (isolato)   │            │
│  └──────┬───────┘  └──────┬───────┘            │
│         │                 │                    │
│  ┌──────▼─────────────────▼───────┐            │
│  │        I/O Subsystem           │            │
│  │  (fetch, KV, R2, D1, DO, AI)  │            │
│  └───────────────────────────────┘            │
│                                                 │
│  ┌─────────────────────────────────────────┐   │
│  │        Network Layer                    │   │
│  │  (Cloudflare anycast, TLS, HTTP/3)     │   │
│  └─────────────────────────────────────────┘   │
└─────────────────────────────────────────────────┘

İşçiler Ne Zaman Kullanılmamalı?

V8 izolatları her şeyin cevabı değildir. Lambda veya konteynerin olduğu senaryolar var doğru seçim olarak kalmaya devam edin:

  • Uzun CPU yoğunluklu hesaplama: Makine öğrenimi eğitimi, video oluşturma, ses kodlaması. 30 saniyelik CPU süresi ve 128 MB RAM sınırı çok yüksek.
  • JavaScript olmayan kod: İşçiler WebAssembly'ı destekliyor ancak hepsini desteklemiyor diller WASM'de iyi bir şekilde derlenir. Yerel Python, Java, Ruby Lambda'yı gerektirir.
  • Node.js ekosistemini tamamlayın: Birçok npm kütüphanesi yerel Node.js API'lerini kullanır (fs, gelişmiş kripto, arabellek manipülasyonu) Workers'ta mevcut değildir.
  • Karmaşık durum yönetimi: WebSocket oturumlarına ihtiyacınız varsa Çok fazla statüye sahip dayanıklı nesneler için Dayanıklı Nesneleri göz önünde bulundurun (serinin 4. makalesine bakın).
  • Kalıcı Bağlantılar Veritabanı: Çalışanlar bağlantıları sürdüremiyor İstekler arasında kalıcı TCP. Geleneksel veritabanlarında havuz oluşturmak için Hyperdrive'ı kullanın.

Sonuçlar ve Sonraki Adımlar

V8 izolatları yalnızca bir optimizasyonu değil, mimari bir paradigma değişimini temsil ediyor: izolasyon sınırını çekirdek seviyesinden çalışma zamanı seviyesine taşırlar, bu da Çok kiracılı uç bilgi işlem için yeterli güvenlikle milisaniyenin altında önyükleme. Maliyet geleneksel kapsayıcılardan daha kısıtlı bir yürütme ortamıdır.

Çoğu RESTful API'si için kimlik doğrulama ara yazılımı, istekler ve içerik özelleştirme, İşçilerin kısıtlamalarından daha fazlasıdır kabul edilebilir ve gecikmedeki kazanç küresel ve ölçülebilirdir.

Serideki Sonraki Yazılar

  • Madde 2: İlk Cloudflare Çalışanınız — Getirme İşleyicisi, Wrangler and Deploy: üretimde çalışan bir işçiyle konseptten uygulamaya.
  • Madde 3: Edge Kalıcılığı — İşçiler KV, R2 ve D1 SQLite: Workers'ta bulunan her depolama katmanının ne zaman ve nasıl kullanılacağı.
  • Madde 4: Dayanıklı Nesneler — Son Derece Tutarlı Durum e WebSocket: Uçtaki durum bilgisi olan uygulamalar için en güçlü ilkel.