Redis preko VPN-a djeluje sporo: manje povratnih putovanja po zahtjevu
VPN ne čini udaljeni Redis poziv lokalnim. Planirajte povratna putovanja po zahtjevu, ponovno upotrebljavajte veze i držite pipeline dalje od transakcija.
Stranica koja odgovara za 200 ms prema lokalnom Redis-u traje četiri sekunde kad klijent sjedne iza VPN-a, dok brojači poslužitelja ostaju mirni. Spori dnevnik ne pokazuje ništa iznad milisekunde, grafikon CPU-a je ravan, a instanca poslužuje druge klijente bez pritužbi. Promijenila se udaljenost, a ono što umnožava udaljenost jest broj puta kad se vaš kod zaustavlja i čeka. Prođite putem zahtjeva od klijenta prema van i rješenje je gotovo uvijek manje uzastopnih čekanja, a ne brži poslužitelj.
Pođite od klijenta, a ne od metrika poslužitelja
Promatrajte proces klijenta između prve i posljednje naredbe. Ako trag pokazuje odgovor, stanku, pa sljedeću naredbu, plaćate puno povratno putovanje po naredbi i nikakvo podešavanje poslužitelja to neće promijeniti. Spori dnevnik ovdje je pogrešan alat jer bilježi vrijeme izvršavanja i namjerno isključuje komunikacijski I/O. Čist spori dnevnik uz spor endpoint potpis je problema s povratnim putovanjima.
Izmjerite sam put prije nego što dotaknete kod. redis-cli -h redis.example.internal --latency šalje ponovljene PING-ove i ispisuje prosječno vrijeme zahtjeva i odgovora, što je vaš trošak po razmjeni. Pomnožite to s brojem uzastopnih naredbi u jednoj korisničkoj radnji i imate donju granicu za endpoint.
Prebrojite povratna putovanja koja jedna korisnička radnja stvarno traži
Uzmite jedan endpoint i zapišite svaki Redis poziv redom, uključujući one skrivene u ORM-u, međuprogramu sesije ili traženju značajke. Većina sporih endpointa na kraju napravi dvadeset ili trideset poziva gdje bi tri bila dovoljna, a skriveni su obično većina.
Lanac ovisnosti ne može se sažeti: ako druga naredba treba ključ koji je vratila prva, čekanje je stvarno i jedine su opcije drukčiji model podataka ili poslužiteljska operacija koja izražava cijeli korak odjednom. Neovisna čitanja su drukčiji slučaj jer vas ništa ne prisiljava da čekate prvi odgovor prije slanja drugoga. Označite svaki poziv kao ovisan ili neovisan prije bilo kakve izmjene i oblik rješenja postaje očit.
Broj koji je važan jesu uzastopna čekanja, a ne ukupne naredbe. Trideset naredbi u jednom batchu i dalje stoji jedno čekanje.
U batch stavljajte samo naredbe koje ne ovise jedna o drugoj
Pipeline stavlja neovisne naredbe u red i skuplja odgovore redom, pretvarajući N čekanja u jedno. Većina klijenata nudi to kao blok, povratni poziv ili context manager, a ne kao zaseban način veze, pa provjerite API koji isporučuje vaša instalirana verzija. Dobitak raste s vremenom povratnog putovanja, i upravo zato je važan na VPN-u, a jedva primjetan na localhostu.
import redis
r = redis.Redis(host="redis.example.internal", port=6379, socket_timeout=2)
pipe = r.pipeline(transaction=False)
for key in ("user:1001", "user:1002", "user:1003"):
pipe.get(key)
print(pipe.execute())
Proslijedite transaction=False kad želite samo batchanje. Uz zadano klijent umata batch u MULTI i EXEC, što ga čini atomskim i mijenja što drugi klijenti mogu vidjeti u letu. Atomskost je odluka o ispravnosti, a ne performansni gumb, i pipeline nije transakcija samo zato što oboje smanjuju povratna putovanja.
Čitajte svaki odgovor, a ne samo predaju batcha. Naredba u redu može vratiti grešku dok se batch kao cjelina dovršava, a klijent koji odbaci popis odgovora pretvara neuspjeli upis u tihi. Usporedite duljinu popisa odgovora s brojem naredbi koje ste stavili u red.
Držite vezu živom između radnji
Svaka nova veza plaća razrješavanje imena, TCP rukovanje, TLS rukovanje i AUTH, a preko VPN-a svako je od toga povratno putovanje koje ne možete ukloniti batchanjem. Stvorite klijent jednom po procesu i ponovno ga koristite ili uzmite pool koji nudi vaša biblioteka s ograničenom veličinom. Ponovno povezivanje po zahtjevu drugi je najčešći uzrok ovog simptoma nakon čekanja po naredbi.
Držite privatno ime hosta u konfiguraciji, a ne doslovnu adresu. Provjera certifikata i identitet usluge i dalje vrijede na privatnoj mreži, a prikvačivanje IP-a pada u trenutku kad davatelj prenumerira podmrežu. Ako je razrješavanje spori dio, popravite put resolvera, a ne connection string.
Postavite izričit socket timeout da zaglavljeni tunel brzo padne umjesto da objesi radnika. Zatim potvrdite da se pool stvarno ponovno koristi bilježenjem stvaranja veza u klijentu.
Odredite veličinu batcha prije nego postane problem s memorijom
Redis drži odgovore u redu tijekom cijelog batcha, a klijent nakon toga drži parsirani rezultat. Pipeline od deset tisuća velikih vrijednosti mijenja mrežna čekanja za skokove memorije i duge stanke na oba kraja.
Odaberite veličinu batcha prema količini odgovora, a ne broju naredbi. Nekoliko stotina malih naredbi u jednom batchu obično je udobno, a stotinu višekilobajtnih tereta nije. Dijelite po bajtovima kao i po broju i držite svaki batch unutar proračuna latencije koji endpoint stvarno ima.
Izmjerite od početka do kraja nakon promjene: redis-cli -h redis.example.internal --latency-history pokazuje je li sam put stabilan, a vaš vlastiti mjerač zahtjeva pokazuje je li se endpoint poboljšao. Ako je endpoint još spor dok je povijest latencije ravna, preostali trošak je rad na poslužitelju ili vaša vlastita serijalizacija, a sljedeći je korak profil rukovatelja, a ne još jedna promjena batchanja.