Puslapis, kuris atsako per 200 ms į vietinį Redis, trunka keturias sekundes, kai klientas atsiduria už VPN, o serverio skaitikliai lieka neveiklūs. Lėtas žurnalas nerodo nieko virš milisekundės, CPU grafikas plokščias, o instancija be priekaištų aptarnauja kitus klientus. Pasikeitė atstumas, o atstumą daugina tai, kiek kartų jūsų kodas sustoja ir laukia. Pereikite užklausos kelią nuo kliento į išorę ir sprendimas beveik visada yra mažiau nuoseklių laukimų, o ne greitesnis serveris.

Pradėkite nuo kliento, o ne nuo serverio metrikų

Stebėkite kliento procesą tarp pirmosios ir paskutinės komandos. Jei pėdsakas rodo atsakymą, pauzę, o paskui kitą komandą, mokate už visą kelionę pirmyn ir atgal vienai komandai, ir joks serverio derinimas to nepakeis. Lėtas žurnalas čia yra netinkamas įrankis, nes jis registruoja vykdymo laiką ir tyčia neįtraukia komunikacijos I/O. Švarus lėtas žurnalas šalia lėto taško yra kelionės pirmyn ir atgal problemos požymis.

Išmatuokite patį kelią prieš liesdami kodą. redis-cli -h redis.example.internal --latency siunčia pasikartojančius PING ir išspausdina vidutinį užklausos ir atsakymo laiką, o tai jūsų vieno mainų kaina. Padauginkite tai iš nuoseklių komandų skaičiaus viename naudotojo veiksme ir turėsite apatinę ribą taškui.

Suskaičiuokite, kiek kelionių pirmyn ir atgal iš tikrųjų reikia vienam naudotojo veiksmui

Paimkite vieną tašką ir iš eilės išrašykite kiekvieną Redis iškvietimą, įskaitant tuos, kurie paslėpti ORM, sesijos tarpinėje programoje ar funkcijos vėliavėlės paieškoje. Dauguma lėtų taškų padaro dvidešimt ar trisdešimt iškvietimų ten, kur užtektų trijų, o paslėptieji paprastai sudaro daugumą.

Priklausomybių grandinės sulankstyti neįmanoma: jei antrai komandai reikia rakto, kurį grąžina pirmoji, laukimas yra tikras ir vieninteliai variantai yra kitas duomenų modelis arba serverio pusės operacija, išreiškianti visą žingsnį iš karto. Nepriklausomi skaitymai yra kitas atvejis, nes niekas neverčia laukti pirmojo atsakymo prieš siunčiant antrąjį. Pažymėkite kiekvieną iškvietimą kaip priklausomą ar nepriklausomą prieš ką nors keisdami, ir sprendimo forma taps akivaizdi.

Svarbus skaičius yra nuoseklūs laukimai, o ne bendros komandos. Trisdešimt komandų vienoje partijoje vis tiek kainuoja vieną laukimą.

Partijomis darykite tik tas komandas, kurios nepriklauso viena nuo kitos

Dujotiekis sustato nepriklausomas komandas į eilę ir surenka atsakymus iš eilės, paversdamas N laukimų vienu. Dauguma klientų tai siūlo kaip bloką, atgalinį iškvietimą ar konteksto tvarkyklę, o ne atskirą ryšio režimą, todėl patikrinkite API, kurią teikia jūsų įdiegta versija. Nauda auga su kelionės laiku, ir būtent todėl ji svarbi VPN ir beveik nepastebima 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())

Perduokite transaction=False, kai norite tik partijavimo. Pagal numatytąjį klientas apgaubia partiją į MULTI ir EXEC, todėl ji tampa atomine ir pasikeičia, ką kiti klientai gali stebėti skrydžio metu. Atomiškumas yra teisingumo sprendimas, o ne našumo rankenėlė, ir dujotiekis nėra transakcija vien todėl, kad abu mažina keliones.

Skaitykite kiekvieną atsakymą, o ne tik partijos pateikimą. Į eilę įdėta komanda gali grąžinti klaidą, kol partija kaip visuma baigiama, o klientas, kuris išmeta atsakymų sąrašą, nepavykusį rašymą paverčia tyliuoju. Palyginkite atsakymų sąrašo ilgį su į eilę įdėtų komandų skaičiumi.

Išlaikykite ryšį gyvą tarp veiksmų

Kiekvienas naujas ryšys sumoka už vardų paiešką, TCP saitą, TLS saitą ir AUTH, o per VPN kiekvienas jų yra kelionė, kurios negalite partijuoti. Sukurkite klientą kartą vienam procesui ir naudokite jį iš naujo, arba naudokite jūsų bibliotekos teikiamą riboto dydžio baseiną. Prisijungimas iš naujo kiekvienai užklausai yra antra pagal dažnumą šio simptomo priežastis po laukimų komandai.

Laikykite privatų pagrindinio kompiuterio vardą konfigūracijoje, o ne pažodinį adresą. Sertifikato patikra ir paslaugos tapatybė vis dar galioja privačiame tinkle, o IP priskyrimas sugenda tą akimirką, kai tiekėjas pernumeruoja potinklį. Jei vardų paieška yra lėta dalis, taisykite sprendiklio kelią, o ne prisijungimo eilutę.

Nustatykite aiškų lizdo laiko limitą, kad įstrigęs tunelis greitai mesti, o ne pakabintų darbuotoją. Tada patvirtinkite, kad baseinas tikrai naudojamas iš naujo, registruodami ryšių kūrimą kliente.

Nustatykite partijos dydį, kol ji netapo atminties problema

Redis saugo eilėje esančius atsakymus visą partijos laiką, o klientas paskui saugo išanalizuotą rezultatą. Dešimt tūkstančių didelių reikšmių dujotiekis iškeičia tinklo laukimus į atminties šuolius ir ilgas pauzes abiejuose galuose.

Rinkitės partijos dydį pagal atsakymo apimtį, o ne komandų skaičių. Keli šimtai mažų komandų vienoje partijoje paprastai yra patogu, o šimtas kelių kilobaitų naudingosios apkrovos — ne. Skirstykite pagal baitus ir pagal skaičių, ir laikykite kiekvieną partiją vėlavimo biudžete, kurį taškas tikrai turi.

Išmatuokite nuo galo iki galo po pakeitimo: redis-cli -h redis.example.internal --latency-history parodo, ar pats kelias stabilus, o jūsų pačių užklausų laikmatis parodo, ar taškas pagerėjo. Jei taškas vis dar lėtas, o vėlavimo istorija plokščia, likusi kaina yra serverio pusės darbas arba jūsų pačių serializavimas, ir kitas žingsnis yra apdorojimo programos profilis, o ne dar vienas partijavimo pakeitimas.

Susiję straipsniai