„Lambda Internals“ - 2 dalis: Giliau

Naršoma „AWS Lambda Runtime“ bibliotekose

Jimo Beaudoino nuotrauka

Programavimas be serverių yra paprasčiausias. Dukart spustelėkite, įkelkite kodą ir viskas baigta, tiesa? Daugeliui žmonių malonu palikti tai. Jei jūs nesate dauguma žmonių, o jums reikia kuo daugiau tyrinėti „Lambda“, šis straipsnis yra kaip tik jums.

Ankstesniame straipsnyje mes gavome apvalkalą prie „Lambda“ talpyklos, atsisiuntėme „Lambda“ runtime aplinką ir atradome jos komponentus:

  • bootstrap.py - python kodas, apimantis mūsų prižiūrėtoją.
  • awslambda / runtime.so - su python suderinamas bendras objektas bootstrap.py jį naudoja, na, beveik viskam.
  • liblambda * .so - runtime.so naudoja kitus bendrinamus objektus. Mes sutelksime dėmesį į liblambdaruntime.so, atsakingą už sunkų kėlimą valdant „Lambda“ logiką.

Mes taip pat smagiai painiojome su bootstrap.py. Šį kartą ketiname susisukti rankoves ir pasinerti į dvejetaines „Lambda“ runtime aplinkos bibliotekas. Mes ištirsime „Lambda“ atsiskaitymo sistemą ir (spoilerio perspėjimas) linksminsimės su „Lambda“ skirtingais laiko tarpais.

„O, kur lankysitės! Čia smagu būti! Yra taškų, kuriuos reikia surinkti. Yra žaidimų, kuriuos reikia laimėti. “- Dr. Seuss. Joshua Earle nuotrauka

Bibliotekų tyrinėjimas

Bibliotekos (liblambda * .so) yra sudarytos iš simbolių, todėl jūs galite daug sužinoti apie bibliotekas tiesiog peržvelgdami simbolių pavadinimus. Be to, „runtime.so“ atskleidžia daug šių funkcijų jas importuodamas ir apvyniodamas, todėl „Python“ scenarijus (mūsų atveju - bootstrap.py) gali naudoti kai kurias iš jų. Kaip patogu!

Dalinių funkcijų sąrašas iš liblambdaruntime.so išardymo. Ačiū dievui už simbolius.

Vienas iš dalykų, kuriuos iš pradžių labai norėjau patikrinti, buvo „Lambda“ atsiskaitymo sistemos užkulisiai, ir tiesiog žvelgdamas į funkcijų pavadinimus turėjau keletą eksperimentų, kuriuos norėjau išbandyti. Bet pirmiausia - pakalbėkime šiek tiek apie „Lambda“ sąskaitų išrašymą.

„Lambda“ atsiskaitymas

„Lambda“ turi kainų nustatymo modelį, pagrįstą laiku, ir nesigilinant į visas detales, tuo ilgesnė jūsų „Lambda“ programa bus paleisti, tuo daugiau mokėsite. Kreipdamiesi į „Lambda“, galite lengvai pastebėti jo pradžią ir pabaigą „CloudWatch“ žurnaluose, taip pat jo trukmę ir sąskaitos pateikimo trukmę.

„CloudWatch“ registruoja „Lambda“. Galite pamatyti ir „Lambda“ trukmę, ir sąskaitos išrašymo trukmę

Tačiau yra sudėtingesnis scenarijus. Apsvarstykite šią Lambda:

Įprastoje serijoje šios „Lambda“ trukmė turėtų būti nedidelė (sąskaitos išrašymo trukmė beveik visada turėtų būti 100 ms). Bet kas nutinka po pirmojo pašaukimo? Ar šaltuoju metu (kai modulis reimportuojamas)?

„Lambda“ žurnalas, kai įvyko šaltasis startas. Trukmė yra daug didesnė nei įprastas kvietimas

Empiriniai testai rodo, kad pirmojo „Lambda“ iškvietimo (arba šaltojo užvedimo) trukmė apima inicijavimo trukmę. Bet aš norėjau patikrinti, kaip „Lambda“ tai įgyvendina.

Bibliotekų importavimas

Bootstrap.py yra kvietimai į šias funkcijas, importuotas iš dvejetainių bibliotekų:

  • lambda_runtime.recept_start () arba lambda_runtime.recept_invoke () - kai gaunamas naujas aktyviklis.
  • lambda_runtime.report_done () - visada, kai daroma „Lambda“

Dabar gali būti tinkamas laikas pateikti daugiau informacijos apie pjaustyklę, apie kurią kalbėjau ankstesniame straipsnyje. Pjaustyklė yra „Lambda“ komponentas, atsakingas už paskirstymo laiko paskirstymą skirtingiems „Lambdas“ vartotojams, dirbantiems ant konteinerio. Šios funkcijos siunčia pranešimą pjaustytuvui (ir kitiems „Lambda“ valdymo komponentams), kai „Lambda“ yra įvykdytos, arba gauna informaciją apie naujai inicijuotas vykdymą.

Taigi, kai nustatėme skambučius iš „lambda_runtime“ ir žinojome, kas yra pjaustyklė, turėjau ką nors, ką tiesiog turėjau išbandyti: pati importuoju vykdymo laiko biblioteką ir linksminuosi su ja! (šie eksperimentai yra tai, kaip aš sužinojau apie pjaustyklę, dažniausiai skaitydama išmontavimą ir kai kuriuos bandymus bei klaidas). Testas, kurį noriu pasidalyti su jumis, taip pat yra pirmasis, kurį bandžiau: paskambinti lambda_runtime.report_done () iš savo „Lambda“. Tai yra kodas, kurį naudojau:

Stebino tai, kad paleidęs šį pavyzdį, mano kodas nustojo galioti tik atspausdinus „Pradžia“. Tada, kai vėl suaktyvinau savo „Lambda“, ji vėl pradėjo vykdyti tiksliai ten, kur mes baigėme - ir išspausdino „Po pirmojo atlikimo“! (Aš pridėjau miego, nes kartais mano „Lambda“ sugebėjo ištraukti vieną „atspaudą“, prieš tai, kai pjaustyklė pristabdė). Tai nutiko vėl ir vėl, kol pasibaigė egzekucija „Lambda“.

„Cloudwatch“ žurnalai, skirti vykdyti „Lambda“. Atkreipkite dėmesį, kad turime keletą užklausų ID dėl tos pačios „Lambda“!

Taigi tai man padarė neabejotiną - pjaustyklė mums išrašo sąskaitą tol, kol mūsų lambda gauna CPU laiką. Tai reiškia, kad mūsų sąskaitos išrašymo trukmė susideda iš dviejų dalių:

  1. Modulio inicijavimo laikas (tik po pirmojo iškvietimo / šaltojo paleidimo)
  2. Mūsų tikroji funkcijos trukmė

Venkite „Lambda“ skirtukų

Be to, kad šis atradimas yra labai šaunus, jis turi ir praktinį (gerai ... praktišką, žiūrinčiojo akimis, tačiau neabejotinai įdomų) naudojimą: „Lambda“ skirtukų laiko tvarkymą! Apsvarstykite šią Lambda:

Kartą įjungiau „Lambda“ ir ji sustojo ties 13 eilute. Tada šiek tiek palaukiau ir vėl suaktyvinau. Rezultatas buvo tas, kad likęs laikas, kurį grąžino kontekstinio objekto metodas, buvo 0, tačiau „Lambda“ nepraleido laiko! „Lambda“ laikas buvo nustatytas iš naujo, nes tai yra skirtingas kvietimas ir mes dabar dvigubai padidinome „Lambda“ skirtąjį laiką (ir, žinoma, mūsų AWS sąskaitą)! Pavyzdžiui, naudingas atvejis gali būti kilpa, apdorojanti daugybę įrašų, o kartais ir praleidžianti laiką. Dabar galime patikrinti, ar artėja laikas, ir jei taip, paskambinkime lambda_runtime.report_done () ir laukime kito trigerio, kuris paims vykdymą ten, kur pristabdėme!

„Cloudwatch“ žurnalas iš „Lambda“ kvietimo. Likęs laikas: 0

Kitas dalykas, kuris man iškilo dirbant su šia problema, yra tas, kad AWS gali pateikti realią savybę, pagrįstą tokiu elgesiu, kai vartotojas gali sustabdyti savo „Lambda“ ir tęsti tą pačią vietą savo kito kvietimo metu. Tai gali būti naudinga ne tik norint apdoroti didelius duomenų kiekius ir tvarkyti skirtukus per vidurį. Kitas naudojimo atvejis gali būti, pavyzdžiui, „Lambda“ laikinas sustabdymas, laukiant brangaus IO / kai kurių kitų užduočių rezultatų, užuot sumokėjus už jūsų „Lambda“ neveikimo laiką! Ar jie tai padarys? Nežinau. Ar tai labai šaunu? Defo.

Vis dėlto visa tai turi trūkumų. Kadangi tai yra apgaulingas būdas, sekantys du sekantys „Lambda“ kvietimai žlugs su „Amazon“ vidine klaida. Esu tikras, kad šią problemą taip pat galima išspręsti šiek tiek pasistengus, tačiau kol kas tai man buvo pakankamai gera.

Išvada

Mes daug sužinojome apie „AWS Lambda“ vidinius darbuotojus. Mes tyrėme dvejetaines bibliotekas vykdymo aplinkoje ir „Lambda“ atsiskaitymo sistemą. Mes taip pat importavome „Lambda“ vykdymo laiko biblioteką ir naudojome ją skirtų laiko taškų tvarkymui! Tačiau dar yra daug ką atrasti ir „AWS“ bei kitiems pardavėjams. Laukiu kitų iššūkių, jei turite kokių nors prašymų - praneškite man!

Taip pat atnaujinau atvirojo kodo biblioteką, kurioje yra įvairių mano atliktų eksperimentų. Tikiuosi, kad jums tai bus naudinga!

Čia, Epsagon, mes kuriame stebėjimo įrankį, pritaikytą pritaikyti be serverių. Naudojate be serverio ir norite sužinoti daugiau? Apsilankykite mūsų svetainėje!