Powrót do Bloga

Cloudflare Workers KV Instant: Runbook dla odczytów konfiguracji gry w 1,62 ms

Opublikowano 2 października 2026
Cloudflare Workers KV Instant: Runbook dla odczytów konfiguracji gry w 1,62 ms Wygenerowano przy użyciu AI

W skrócie

Sprawdź, jak Workers KV Instant skraca odczyty konfiguracji gry do 1,62 ms i eliminuje problem nieaktualnych danych dzięki replikacji w 256 ms.

Gdy Twój zespół live-ops wypycha krytyczną aktualizację konfiguracji — poprawkę exploita ekonomii, awaryjną zmianę harmonogramu eventu, flagę okna konserwacji — gracze po drugiej stronie planety nie powinni czytać nieaktualnych danych przez 4,38 sekundy. To czas replikacji zapisu p99 dla klasycznego Cloudflare Workers KV. Dla statycznej strony marketingowej — kogo to obchodzi. Dla gry live, w której stawką są prawdziwe pieniądze lub integralność rywalizacji, ta luka propagacyjna to ryzyko.

Cloudflare właśnie ogłosił Workers KV Instant, nowy tryb dla Workers KV napędzany ich wewnętrznym magazynem Quicksilver v2. Ten sam znajomy API get(), put(), list(), delete(). Całkowicie inny silnik pod spodem — ten sam, który obsługuje odczyty konfiguracji dla każdego żądania w globalnej sieci Cloudflare. Efekt: 1,62 ms p99 odczytów i 256 ms p99 replikacji zapisu do ponad 300 lokalizacji edge.

Ten runbook omawia, co się faktycznie zmieniło, jak wykryć, czy Twoja gra trafia na tryby awarii związane z nieaktualną konfiguracją, implementację krok po kroku dla konfiguracji gry hostowanej na edge, twarde limity, które sprawiają, że KV Instant nie nadaje się do niektórych obciążeń, oraz kiedy zarządzany serwis zdalnej konfiguracji ma więcej sensu niż budowanie tego samodzielnie.


Co się faktycznie zmieniło: KV Instant vs KV Classic

Workers KV Classic jest ostatecznie spójny. Zapisujesz klucz, a Cloudflare replikuje go asynchronicznie do swoich lokalizacji edge. W tym oknie czytelnicy mogą otrzymać nieaktualne wartości. Model spójności to „last-write-wins z unieważnianiem cache opartym na TTL”. To działa w przypadku statycznych zasobów i preferencji użytkowników — danych zapisywanych rzadko i tolerujących sekundy nieaktualności.

KV Instant używa Quicksilver v2, wewnętrznego magazynu, który Cloudflare zbudował do dystrybucji własnej konfiguracji. Każde żądanie Cloudflare już dotyka Quicksilver — do reguł routingu, konfiguracji firewalla, progów rate limitu. Jest sprawdzony w boju w skali, do której większość backendów gier nigdy nie zbliży.

Oto konkretne porównanie wydajności:

Metryka KV Instant KV Classic
p99 odczyty (wszystkie) 1.62 ms 287 ms
p99 replikacja zapisu 256 ms 4,380 ms
Mediana replikacji zapisu 107 ms < 1 s (bez dokładności poniżej sekundy)

To poprawa opóźnienia odczytu o 177× i poprawa replikacji zapisu o 17×. Te liczby pochodzą z benchmarków Cloudflare przeprowadzonych we wszystkich ponad 300 lokalizacjach edge.

Dla backendu gry implikacja jest bezpośrednia: możesz czytać konfigurację przy każdym żądaniu gracza — przy logowaniu, starcie meczu, pobieraniu ekwipunku, otwarciu sklepu — a koszt odczytu wynosi poniżej 2 ms nawet na p99. Nie ma TTL, na który trzeba czekać. Nie ma okna spójności cache, w którym Gracz A widzi poprawkę exploita, a Gracz B nie.


Runbook: Wykrywanie problemów z nieaktualną konfiguracją w grze

Zanim cokolwiek zmigrujesz, musisz wiedzieć, czy masz ten problem. Oto tryby awarii, jak je wykrywać i co Cię kosztują.

Tryb awarii 1: Nieaktualne odczyty po wygaśnięciu TTL

Co się psuje: Twój magazyn konfiguracji używa cache opartego na TTL. Flaga funkcji zostaje zaktualizowana, ale gracze w Tokio przez 30–60 sekund nadal czytają starą wartość, dopóki cache na edge nie wygaśnie.

Jak to wykryć:

  • Loguj hash wersji konfiguracji zwracany każdemu klientowi wraz ze znacznikiem czasu zapisu, kiedy konfiguracja była ostatnio aktualizowana.
  • Zapytaj o klientów otrzymujących wersję konfiguracji starszą niż 2 sekundy po zapisie.
  • Zbuduj dashboard: count of (stale_reads) / count (total_reads). Cokolwiek powyżej 0% podczas pusha konfiguracji to okno nieaktualnych odczytów.

Szybki wzorzec zapytania diagnostycznego (dostosuj do swojego stacku logowania):

SELECT
  received_config_version,
  expected_config_version,
  COUNT(*) AS stale_count,
  MAX(received_at - config_updated_at) AS max_staleness
FROM config_read_log
WHERE config_updated_at > NOW() - INTERVAL '1 hour'
  AND received_config_version != expected_config_version
GROUP BY received_config_version, expected_config_version
ORDER BY max_staleness DESC;

Co Cię to kosztuje: Gracze w oknie nieaktualności doświadczają różnych stanów gry. W grze rywalizacyjnej jeden gracz widzi, że exploit jest załatany, a drugi nie. W grze eventowej niektórzy gracze całkowicie tracą okna limitowane czasowo. To problem zaufania.

Tryb awarii 2: Odczyty konfiguracji na ścieżce krytycznej powodujące skoki latencji

Co się psuje: Twój magazyn konfiguracji ma na tyle wysokie opóźnienie odczytu (100–300 ms), że nie stać Cię na odczyt przy każdym żądaniu. Zamiast tego cache'ujesz go po stronie klienta lub w szybkim, ale nieaktualnym lokalnym cache. Cache jest poprawny w 99% przypadków, ale gdy jest błędny, jest bardzo błędny.

Jak to wykryć:

  • Zmierz p50, p95 i p99 latencji wywołania odczytu konfiguracji. Jeśli p99 przekracza 50 ms, jest zbyt wolne do sprawdzania przy każdym żądaniu.
  • Śledź współczynniki trafień cache. Jeśli cache'ujesz konfigurację po stronie klienta, aby uniknąć odwołań do magazynu, już zaakceptowałeś nieaktualność jako kompromis.
  • Monitoruj incydenty, w których zła wartość konfiguracji utrzymuje się po pushu — prześledź to do TTL cache per klient.

Co Cię to kosztuje: Inżynierujesz wokół problemu latencji, który wprowadza problem nieaktualności. Dwa problemy w cenie jednego.

Tryb awarii 3: Amplituda zapisu pod presją incydentu

Co się psuje: Musisz wypchnąć awaryjną aktualizację konfiguracji — wyłączyć funkcję, włączyć tryb konserwacji, oznaczyć zepsutą ekonomię — a zapisy są wolne lub limitowane. Klasyczny Workers KV pozwala na jeden zapis na klucz na sekundę, a replikacja zajmuje sekundy.

Jak to wykryć:

  • Śledź latencję od zapisu do widoczności podczas reagowania na incydent. Jeśli Twój zespół ops liczy na to, że „konfiguracja powinna się propagować w kilka sekund”, a trwa to 10+, Twój magazyn konfiguracji jest wąskim gardłem incydentu.
  • Monitoruj błędy zapisu i odpowiedzi 429 rate-limit podczas pushów o wysokim priorytecie.

Jeśli trafiasz na wszystkie trzy tryby awarii, KV Instant jest wart rozważenia.


Implementacja KV Instant dla konfiguracji gry: krok po kroku

KV Instant jest obecnie w prywatnej becie. Możesz zapisać się przez formularz beta Cloudflare. Implementacja jest prosta, ponieważ API jest identyczne jak w klasycznym Workers KV — różni się tylko tworzenie przestrzeni nazw.

Krok 1: Utwórz przestrzeń nazw KV Instant

Przekaż atrybut mode: "instant" podczas tworzenia przestrzeni nazw:

wrangler kv namespace create "GAME_CONFIG" --mode instant

To generuje binding przestrzeni nazw. Zaktualizuj swój wrangler.toml:

[[kv_namespaces]]
binding = "GAME_CONFIG"
id = "&lt;your-namespace-id>"

Krok 2: Zapisz konfigurację gry

Przestrzenie nazw KV Instant są ograniczone do 10 000 par klucz-wartość przy całkowitym rozmiarze przestrzeni nazw 1 MB. Każdy klucz może mieć do 300 bajtów. To mało — celowo. Jest zaprojektowany dla flag konfiguracyjnych i ustawień, a nie danych graczy.

Strukturyzuj klucze dla warstwy konfiguracyjnej gry:

// In a Cloudflare Worker that manages config
async function updateGameConfig(env) {
  const config = {
    maintenanceMode: false,
    maintenanceMessage: "Servers are updating. Back in 5 min.",
    eventSchedule: {
      currentEvent: "summer_showdown_2025",
      startTime: "2025-07-15T18:00:00Z",
      endTime: "2025-07-22T18:00:00Z",
    },
    economyTuning: {
      xpMultiplier: 1.5,
      goldDropRate: 0.85,
      shopRefreshHours: 6,
    },
    featureFlags: {
      newMatchmaking: true,
      rankedModeV2: false,
      socialLobby: true,
    },
    buildVersion: {
      minimumClient: "1.4.2",
      forceUpdate: false,
    },
  };

  await env.GAME_CONFIG.put("active_config", JSON.stringify(config));
  // Propagates to 300+ edge locations in ~256ms at p99
}

Limit częstotliwości zapisu: Jeden zapis na przestrzeń nazw na sekundę. To ograniczenie projektowe, nie błąd — czyni kolejność aktualizacji deterministyczną. Dla konfiguracji zmieniającej się kilka razy na godzinę (lub na incydent) to nie jest wąskie gardło.

Krok 3: Serwuj konfigurację z edge

Zbuduj Cloudflare Workera, który czyta konfigurację przy każdym żądaniu i serwuje ją klientowi gry:

export default {
  async fetch(request, env, ctx) {
    // Every player request reads fresh config — 1.62ms p99
    const raw = await env.GAME_CONFIG.get("active_config");
    if (!raw) {
      return new Response(JSON.stringify({ error: "config_missing" }), {
        status: 503,
        headers: { "Content-Type": "application/json" },
      });
    }

    const config = JSON.parse(raw);

    // Conditional logic at the edge — maintenance mode check
    if (config.maintenanceMode) {
      return new Response(
        JSON.stringify({
          status: "maintenance",
          message: config.maintenanceMessage,
        }),
        {
          status: 503,
          headers: { "Content-Type": "application/json" },
        }
      );
    }

    // Return relevant config slice for the client
    const clientConfig = {
      event: config.eventSchedule,
      economy: config.economyTuning,
      features: config.featureFlags,
      build: config.buildVersion,
    };

    return new Response(JSON.stringify(clientConfig), {
      headers: {
        "Content-Type": "application/json",
        "Cache-Control": "public, max-age=5", // Short cache for freshness
      },
    });
  },
};

Krok 4: Konsumuj konfigurację w kliencie gry

Po stronie klienta pobierz konfigurację podczas inicjalizacji lub startu sesji. Oto przykład w GDScript dla gry w Godocie:

extends Node

var config_url: String = "https://config.yourgame.com/api/config"
var current_config: Dictionary = {}

func _ready():
    fetch_config()

func fetch_config():
    var http = HTTPRequest.new()
    add_child(http)
    http.request_completed.connect(_on_config_received)
    http.request(config_url)

func _on_config_received(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray):
    if response_code != 200:
        push_warning("Config fetch failed: %d" % response_code)
        return

    var json = JSON.new()
    var parse_result = json.parse(body.get_string_from_utf8())
    if parse_result != OK:
        push_warning("Config parse error")
        return

    current_config = json.data
    _apply_config(current_config)

func _apply_config(config: Dictionary):
    # Apply feature flags
    if config.has("features"):
        if config["features"].get("rankedModeV2", false):
            enable_ranked_mode()
        if config["features"].get("newMatchmaking", false):
            enable_new_matchmaking()

    # Check build version
    if config.has("build"):
        var min_version = config["build"].get("minimumClient", "0.0.0")
        if version_compare(get_app_version(), min_version) &lt; 0 and config["build"].get("forceUpdate", false):
            show_force_update_screen()

    # Apply economy tuning
    if config.has("economy"):
        EconomyManager.set_xp_multiplier(config["economy"].get("xpMultiplier", 1.0))
        EconomyManager.set_gold_drop_rate(config["economy"].get("goldDropRate", 1.0))

    print("Config applied successfully — all players now on same state")

Ponieważ odczyty są poniżej 2 ms i nie ma nieaktualności TTL, możesz wywoływać fetch_config() przy każdym starcie sesji, przy każdym wejściu do kolejki meczu lub przy każdej istotnej akcji klienta, bez martwienia się o narzut latencji czy spójność cache.


Czego KV Instant nie może zrobić (twarde limity)

KV Instant jest potężny w swojej niszy, ale ograniczenia są realne. Oceń je, zanim zdecydujesz się na implementację:

Całkowity rozmiar przestrzeni nazw 1 MB. Nie możesz przechowywać danych graczy, snapshotów rankingów, ekwipunku ani niczego, co rośnie wraz z liczbą graczy. To jest wyłącznie dla konfiguracji i flag obowiązujących globalnie.

Maksymalnie 10 000 par klucz-wartość. Wystarczy dla setek flag funkcji i obiektów konfiguracji. Nie wystarczy dla czegokolwiek per gracz.

Jeden zapis na przestrzeń nazw na sekundę. Jeśli potrzebujesz częstotliwości zapisu poniżej sekundy, to nie jest Twój magazyn. Dla konfiguracji gry aktualizowanej co godzinę lub podczas incydentów to jest w porządku. Do synchronizacji stanu gry w czasie rzeczywistym szukaj gdzie indziej.

Brak wsparcia dla metadanych. getWithMetadata zwraca null. Nie możesz dołączać własnych metadanych do kluczy. Jeśli zależysz od metadanych do wersjonowania lub tagowania, musisz osadzić je w samej wartości.

Brak paginacji w list. Każde wywołanie list zwraca wszystkie pasujące klucze w przestrzeni nazw. Dla 10 000 kluczy to duża odpowiedź. Celowo nazywaj klucze i używaj prefiksów, aby zawęzić wywołania list.

Asymetria kosztów. Pamięć kosztuje 100 USD/MB/miesiąc (vs 0,50 USD/GB/miesiąc dla Classic). Operacje zapisu klasy A kosztują 0,10 USD za sztukę (vs 5,00 USD za milion dla Classic). Te liczby są zaporowe dla obciążeń z częstym zapisem. Ale odczyty kosztują 0,20 USD za milion — 60% taniej niż Classic. Model cenowy jest mocno nachylony w stronę „pisz rzadko, czytaj stale”, co jest dokładnie wzorcem konfiguracji gry.


Najlepsze praktyki dla konfiguracji gry na KV Instant

  1. Celowo nadawaj przestrzenie nazw kluczom. Używaj prefiksów takich jak ff_ dla flag funkcji, econ_ dla strojenia ekonomii, evt_ dla harmonogramów eventów. To sprawia, że wywołania list są skanowalne i pozwala budować UI do zarządzania konfiguracją, które manipulują konkretnymi kategoriami bez czytania całej przestrzeni nazw.

  2. Osadzaj hashe wersji w wartościach. Ponieważ metadane nie są wspierane, umieść pole configVersion wewnątrz każdej wartości konfiguracji. Twój klient może raportować tę wersję w logach i analityce, dając Ci dashboard weryfikacji propagacji w czasie rzeczywistym.

  3. Oddziel konfigurację od stanu. KV Instant przechowuje konfigurację — reguły, flagi, parametry strojenia, harmonogramy. Nie przechowuje stanu — ekwipunków graczy, wyników meczów, rankingów. Zaprojektuj to jako dwa odrębne systemy z osobnymi backendami pamięci. Jeśli Twoja przestrzeń nazw „config” rośnie o więcej niż kilka KB tygodniowo, umieść te dane gdzie indziej.

  4. Obsłuż przypadek 503. Jeśli GAME_CONFIG.get() zwraca null, Twój worker powinien zakończyć się z gracją. Zwróć tryb konserwacji lub kill switch. Brakujący klucz konfiguracji nigdy nie powinien crashować klienta gry. Zbuduj fallback w workerze na edge, nie w kliencie.

  5. Testuj kolejność zapisów pod presją. Jeden zapis na sekundę na przestrzeń nazw oznacza, że współbieżne zapisy będą serializowane. Jeśli dwóch inżynierów wypchnie zmiany konfiguracji w tej samej sekundzie, wygrywa ostatni. Zbuduj kolejkę zmian konfiguracji z jawną kolejnością, zamiast polegać na współbieżnych zapisach.


Kiedy zamiast tego użyć zarządzanego serwisu konfiguracji

Zbudowanie pipeline'u dystrybucji konfiguracji na KV Instant to solidna decyzja inżynieryjna, jeśli Twój zespół ma zasoby, aby utrzymywać workera na edge, UI zarządzania konfiguracją, schemat wersjonowania, logikę pobierania po stronie klienta i procedury reagowania na incydenty. To prawdziwa praca infrastrukturalna — nie trudna indywidualnie, ale sumuje się w harmonogramie wydawniczym.

Dla zespołów, które chcą dystrybucji konfiguracji bez obsługiwania całej hydrauliki, horizOn zapewnia Remote Configuration jako zarządzany serwis. Definiujesz flagi funkcji, ustawienia gry i parametry strojenia przez dashboard lub API, a platforma zajmuje się dystrybucją do klientów gry. Bez workerów na edge do pisania i utrzymywania, bez ograniczeń rozmiaru przestrzeni nazw KV, nad którymi trzeba się zastanawiać — ale też mniejsza kontrola nad silnikiem replikacji i profilem latencji.

Kompromis to klasyczna oś build-vs-buy. KV Instant daje surową wydajność na edge z pełną kontrolą. Zarządzany serwis daje szybszy czas integracji i mniejszą powierzchnię operacyjną. Wybierz na podstawie tego, czy dystrybucja konfiguracji jest kluczową kompetencją Twojego studia, czy kosztem infrastrukturalnym.

Jeśli potrzebujesz wykrywać nieaktualność konfiguracji w rozproszonych klientach gry, wzorce logowania i zapytań z sekcji runbook powyżej działają niezależnie od tego, który backend konfiguracji wybierzesz. Warstwa diagnostyczna jest niezależna od transportu.


Podsumowanie: odczyty konfiguracji, które nadążają za grą

KV Instant to znaczący upgrade dla konkretnego wzorca „małych, krytycznych, czytanych globalnie danych konfiguracyjnych”. Dla backendów gier ten wzorzec mapuje się bezpośrednio na flagi funkcji, strojenie ekonomii, harmonogramy eventów, przełączniki konserwacji i bramki wersji builda.

Te liczby to nie zaokrąglenia marketingowe: 1,62 ms p99 odczytów i 256 ms p99 replikacji zapisu w ponad 300 lokalizacjach edge. API jest identyczne jak w klasycznym Workers KV. Ograniczenia (1 MB, 10 000 kluczy, 1 zapis/sekundę) są dobrze zdefiniowane i odpowiednie dla tego przypadku użycia.

Jeśli Twoja gra obecnie czyta konfigurację ze scentralizowanego magazynu i cache'uje ją po stronie klienta, aby uniknąć latencji, oceń, czy to okno nieaktualności jest nadal akceptowalne. Dla gier rywalizacyjnych i tytułów live-service z tunowaniem ekonomii w czasie rzeczywistym odpowiedź coraz częściej brzmi: nie.

Zapisz się do prywatnej bety KV Instant, skonfiguruj testową przestrzeń nazw z najbardziej wrażliwą na latencję konfiguracją i zmierz uzyskany zapas propagacji. Jeśli liczby zgadzają się z tym, co raportuje Cloudflare, masz jasną ścieżkę do całkowitego wyeliminowania jednej klasy incydentów z nieaktualną konfiguracją.

Potrzebujesz drugiej pary oczu do architektury konfiguracji lub topologii backendu? Sprawdź dokumentację horizOn — platforma obsługuje dystrybucję konfiguracji, raportowanie crashy i zarządzanie sesjami graczy, dzięki czemu możesz skupić się na dostarczaniu rozgrywki zamiast na runbookach infrastrukturalnych.


Źródło: Wprowadzenie Workers KV Instant — napędzanego przez Quicksilver