Redis over VPN kjennest tregt: færre rundturar per førespurnad
Ein VPN gjer ikkje eit eksternt Redis-kall lokalt. Budsjetter rundturar per førespurnad, bruk tilkoplingar om att og hald pipelines unna transaksjonar.
Ei side som svarar på 200 ms mot ein lokal Redis, brukar fire sekund når klienten sit bak ein VPN, medan teljarane på tenaren står stille. Den treige loggen viser ingenting over ein millisekund, CPU-grafen er flat, og instansen tener andre klientar utan klager. Det som er endra, er avstanden, og det som multipliserer avstanden, er talet på gonger koden din stoppar og ventar. Gå vegen til førespurnaden frå klienten og utover, og løysinga er nesten alltid færre sekvensielle ventetider i staden for ein raskare tenar.
Start ved klienten, ikkje ved målingane til tenaren
Fylg klientprosessen mellom den første og den siste kommandoen. Viss sporet viser eit svar, ein pause og deretter neste kommando, betalar du ein full rundtur per kommando, og inga mengd tenartuning endrar det. Den treige loggen er feil instrument her, fordi han registrerer køyretid og med vilje utelèt kommunikasjons-I/O. Ein rein treig logg ved sida av eit treigt endepunkt er signaturen på eit rundturproblem.
Mål sjølve vegen før du rører koden. redis-cli -h redis.example.internal --latency sender gjentekne PING-ar og skriv ut gjennomsnittleg førespurnads- og svartid, som er kostnaden din per utveksling. Gang det med talet på sekvensielle kommandoar i éi brukarhandling, og du har ei nedre grense for endepunktet.
Tel rundturane som éi brukarhandling faktisk treng
Ta eit enkelt endepunkt og skriv ned kvart Redis-kall i rekkjefylgje, òg dei som er gøymde i ein ORM, ein sesjons-middleware eller eit funksjonsflagg-oppslag. Dei fleste treige endepunkta viser seg å gjere tjue eller tretti kall der tre ville vore nok, og dei gøymde er vanlegvis fleirtalet.
Ei avhengigheitskjede kan ikkje slåast saman: viss den andre kommandoen treng nøkkelen den første returnerer, er ventetida reell, og dei einaste alternativa er ein annan datamodell eller ein tenaroperasjon som uttrykkjer heile trinnet på ein gong. Uavhengige lesingar er ei anna sak, fordi ingenting tvingar deg til å vente på det første svaret før du sender det andre. Merk kvart kall som avhengig eller uavhengig før du endrar noko, og forma på løysinga blir openberr.
Talet som betyr noko, er sekvensielle ventetider, ikkje totale kommandoar. Tretti kommandoar i ein batch kostar framleis éi ventetid.
Batch berre kommandoane som ikkje er avhengige av kvarandre
Ein pipeline set uavhengige kommandoar i kø og samlar svara i rekkjefylgje, og gjer N ventetider til éi. Dei fleste klientar tilbyr det som ein blokk, ein callback eller ein konteksthandsamar i staden for ein eigen tilkoplingsmodus, så sjekk API-et versjonen din leverer. Vinsten skalerer med rundturtida, og det er nettopp difor det betyr noko på ein VPN og knapt merkest på localhost.
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())
Send transaction=False når du berre vil batcha. Som standard pakkar klienten batchen inn i MULTI og EXEC, noko som gjer han atomisk og endrar kva andre klientar kan observere undervegs. Atomisitet er ei avgjerd om rettheit, ikkje ein ytingsknapp, og ein pipeline er ikkje ein transaksjon berre fordi begge reduserer rundturar.
Les kvart svar i staden for berre batchinnsendinga. Ein kommando i kø kan returnere ein feil medan batchen som heilskap blir fullført, og ein klient som kastar svarlista, gjer ei mislukka skriving til ei stille. Samanlikn lengda på svarlista med talet på kommandoar du sette i kø.
Hald tilkopinga i live mellom handlingar
Kvar ny tilkoping betalar for namneoppslag, eit TCP-handtrykk, eit TLS-handtrykk og ein AUTH, og over ein VPN er kvar av dei ein rundtur du ikkje kan batcha bort. Opprett klienten éin gong per prosess og bruk han om att, eller bruk poolen biblioteket ditt tilbyr med avgrensa storleik. Gjenoppkopling per førespurnad er den nest vanlegaste årsaka til dette symptomet etter ventetider per kommando.
Hald det private vertsnamnet i konfigurasjonen i staden for ei bokstaveleg adresse. Sertifikatvalidering og tenesteidentitet gjeld framleis på eit privat nettverk, og fastlåsing av ein IP bryt saman i det augneblunken leverandøren omnummererer eit subnett. Viss oppslaget er den treige delen, reparer resolverstien i staden for tilkoplingsstrengen.
Set ein eksplisitt socket-timeout slik at ein fastlåst tunnel feilar raskt i staden for å hengje ein arbeidar. Stadfest deretter at poolen verkeleg blir brukt om att ved å logge tilkoplingsoppretting i klienten.
Dimensjoner batchen før han blir eit minneproblem
Redis held køa svar i heile batchens varigheit, og klienten held deretter det parsa resultatet. Ein pipeline med ti tusen store verdiar byter nettverksventetider mot minnetoppar og lange pausar i begge endar.
Vel batchstorleik etter svarmengd i staden for kommandotal. Nokre hundre små kommandoar i ein batch er vanlegvis behageleg, medan hundre nyttelaster på fleire kilobyte ikkje er det. Del på bytes så vel som på tal, og hald kvar batch innanfor latensbudsjettet endepunktet faktisk har.
Mål ende-til-ende etter endringa: redis-cli -h redis.example.internal --latency-history viser om vegen sjølv er stabil, og din eigen førespurnadstimer viser om endepunktet vart betre. Viss endepunktet framleis er treigt medan latenshistorikken er flat, er den attverande kostnaden tenararbeid eller din eigen serialisering, og neste steg er ein profil av handteraren i staden for nok ei batch-endring.