bekprešrTakéBack pressurePokročilý

Definice

Backpressure je mechanismus, kterým pomalejší část systému dává rychlejší části najevo, že má zpomalit, počkat nebo zahodit část práce. Používá se u streamů, front, sítí a event-driven aplikací, aby se nekonečně nehromadila data v paměti a aby přetížení nespadlo až na celý proces.

Kategorie: Softwarový vývojAktualizováno

Nezaměňujte: Backpressure v softwaru znamená řízení toku při přetížení, zatímco ve fyzice a strojírenství může znamenat tlak působící proti proudění kapaliny nebo plynu.

Proč backpressure chrání paměť i latenci

Backpressure se objeví všude tam, kde jedna část systému vyrábí práci rychleji, než ji druhá část dokáže zpracovat. Producentem může být síťové spojení, čtečka souboru, broker zpráv nebo API endpoint. Konzumentem může být databáze, zapisovač na disk, renderer nebo jiná služba. Bez zpětného signálu se data začnou řadit do fronty, fronta roste a paměť se mění v dočasné skladiště nevyřízené práce.

Krátká fronta je užitečná, protože vyhlazuje drobné výkyvy. Nekontrolovaná fronta je nebezpečná, protože zvyšuje latenci a často jen oddaluje pád. Backpressure proto není optimalizační detail, ale součást spolehlivosti: říká, kdy má rychlá strana zpomalit, počkat, snížit paralelismus nebo vědomě odmítnout další vstup.

Signál místo nekonečného bufferu

Backpressure funguje jako dohoda o kapacitě. Konzument neříká jen „zpracovávám“, ale průběžně ukazuje, kolik práce ještě unese. Signál může mít mnoho podob: návratová hodnota false při zápisu do streamu, zaplněný bounded channel, okno v síťovém protokolu, čekání na potvrzení, zpomalený odběr z brokera nebo odpověď HTTP s odmítnutím požadavku.

  • Čekání: producent pozastaví čtení nebo generování dat, dokud se neuvolní kapacita.
  • Omezení rychlosti: systém sníží počet paralelních úloh, velikost batchů nebo frekvenci požadavků.
  • Řízené zahazování: systém zahodí starší, méně důležitá nebo redundantní data, například u telemetrie.
  • Odmítnutí vstupu: služba vrátí jasnou chybu místo toho, aby neomezeně přijímala další práci.

Backpressure ve streamech, TCP a brokerech

Node.js a webové streamy

Streamy používají backpressure velmi viditelně. Zapisující strana dostane informaci, že interní buffer dosáhl hranice, a má počkat na událost nebo promise, která oznámí uvolnění místa. Správně napsaný kód nepokračuje slepě ve volání zápisu, protože tím by obcházel ochranu, kterou stream poskytuje.

TCP a distribuované systémy

TCP řeší podobný problém na úrovni spojení pomocí řízení toku: příjemce oznamuje, kolik dat může přijmout, a odesílatel tomu přizpůsobuje tok bajtů. V distribuovaných aplikacích bývá situace méně elegantní, protože hranice vede přes síť, databázi, message broker a aplikační logiku. Backpressure se proto musí propisovat přes více vrstev, jinak se úzké hrdlo jen přesune na jiné místo.

Kde se backpressure ztrácí

Backpressure často selže na asynchronní hranici, kde kód vytvoří mnoho promise, tasků nebo zpráv bez horního limitu. Dalším častým místem je převod streamu na pole v paměti, protože tím aplikace zahodí průběžné zpracování a začne čekat na celý objem dat. Rizikové jsou také fronty bez limitu, automatické retry bez jitteru a batch joby, které při zpomalení cílové databáze jen zvyšují souběžnost.

Dobrá implementace backpressure má měřitelné limity: velikost fronty, počet rozpracovaných úloh, čas čekání, počet odmítnutí a rychlost zpracování. Monitoring potom ukáže, zda systém skutečně zpomaluje u zdroje, nebo pouze hromadí problém uvnitř procesu.

Příklady z praxe

  1. Node.js stream zapisuje pomaleji než čte

    Aplikace čte velký soubor a komprimovaná data zapisuje do pomalejšího cíle. Metoda zápisu vrátí hodnotu, která říká, že interní buffer je plný, takže kód počká na událost drain. Výsledkem je stabilní spotřeba paměti místo nekontrolovaného hromadění chunků.

    import { once } from 'node:events';
    
    for await (const chunk of source) {
      if (!writable.write(chunk)) {
        await once(writable, 'drain');
      }
    }
    writable.end();
  2. Import do databáze s omezenou frontou

    Importní služba stahuje objednávky z API a ukládá je do databáze, která se při špičce zpomalí. Bounded fronta se zaplní, workers přestanou přebírat další stránky z API a plánovač importu prodlouží interval mezi požadavky. Import trvá déle, ale databáze ani proces neskončí kvůli přetížení.

Časté omyly

MýtusStačí zvětšit buffer a backpressure není potřeba.
Ve skutečnostiVětší buffer pouze odloží okamžik, kdy se přetížení projeví. Backpressure řeší příčinu tím, že zpomaluje zdroj nebo omezuje množství rozpracované práce.
MýtusBackpressure znamená, že konzument posílá chybu.
Ve skutečnostiBackpressure není nutně chybový stav. Backpressure je řídicí signál, který může vést k čekání, zpomalení nebo odmítnutí nové práce podle toho, co systém dokáže bezpečně zvládnout.

Časté dotazy

Je backpressure totéž co rate limiting?
Backpressure a rate limiting řeší příbuzný problém, ale z jiné strany. Backpressure je zpětný signál od pomalého konzumenta k rychlému producentovi a obvykle reaguje na aktuální kapacitu systému. Rate limiting je pravidlo, které omezuje počet požadavků nebo operací za čas, často už na vstupu do služby. V praxi se oba přístupy doplňují: rate limit chrání hranici systému, backpressure chrání vnitřní zpracování.
Co se stane, když aplikace backpressure ignoruje?
Aplikace bez backpressure obvykle nejdřív vypadá rychle, protože přijímá práci bez čekání. Nevyřízené položky se však začnou hromadit v paměti, frontách nebo otevřených spojeních. Následkem bývá rostoucí latence, garbage collection tlak, timeouty, kaskádové retry a nakonec pád procesu nebo zahlcení závislé služby. Backpressure problém neodstraní, ale zabrání tomu, aby se přetížení nekontrolovaně šířilo.
Musí backpressure vždy zastavit producenta?
Backpressure nemusí vždy znamenat úplné zastavení producenta. Backpressure může snížit rychlost čtení, zmenšit batch, omezit souběžnost, dočasně odmítat méně důležitou práci nebo zahazovat data, u kterých je ztráta přijatelná. Správná reakce závisí na doméně: platební transakce se nesmí tiše zahodit, ale opakovaný telemetrický vzorek často ano.
Kde hledat problém s backpressure při ladění pomalého streamu?
Backpressure se při ladění hledá na hranicích mezi rychlým zdrojem a pomalým cílem. Důležité metriky jsou délka fronty, počet rozpracovaných úloh, čas zápisu, čekání na databázi, počet retry a využití paměti. U streamů je užitečné zkontrolovat, zda kód respektuje signál zaplnění bufferu. U workerů je potřeba ověřit, že počet paralelních úloh má pevný horní limit.

Zdroje

  1. Backpressuring in Streams(otevře se v novém okně)Node.js
  2. Streams API(otevře se v novém okně)MDN Web Docs
  3. Transmission Control Protocol (TCP)(otevře se v novém okně)RFC Editor, 2022

Související pojmy

Potřebujete to vyřešit v praxi?

Poradíme, jak na to ve vašem projektu

Vysvětlit pojem je jedna věc, navrhnout kolem něj funkční řešení druhá. Ozvěte se a probereme, co dává smysl u vás.