Unutarnja lambda - Dio 2: Zalazak dublje

Istraživanje AWS Lambda runtime biblioteka

Fotografiju Jima Beaudoina

Razvoj bez poslužitelja jednostavno je najbolji. Dvaput kliknite, prenesite svoj kôd i gotovi ste, zar ne? Većina ljudi je više nego sretna da to ostavi pri tome. Ako niste većina ljudi i već se bavite nekim istraživanjem Lambde, ovaj članak je samo za vas.

U prethodnom smo članku dobili školjku na Lambda spremnik, preuzeli okruženje za vrijeme izvođenja Lambde i otkrili njegove komponente:

  • bootstrap.py - python kod koji obavija naš rukovatelj.
  • awslambda / runtime.so - zajednički objekt bootstrap.py kompatibilan s pitonom koristi ga za, dobro, gotovo sve.
  • liblambda * .so - zauzvrat, runtime.so koristi druge zajedničke objekte. Fokusirat ćemo se na liblambdaruntime.so, zadužen za dizanje teških sila u upravljanju Lambda logikom.

Zabavili smo se i zabrljali s bootstrap.py. Ovaj put ćemo zasukati rukave i zaroniti u binarne biblioteke okruženja za vrijeme izvođenja Lambde. Istražit ćemo Lambdin sustav naplate i (upozorenje spoilera) i zabaviti se zabrljati s Lambda timeoutima.

Istraživanje biblioteka

Biblioteke (liblambda * .so) su sastavljene sa simbolima, tako da možete mnogo naučiti o knjižnicama ako pređete preko imena simbola. Također, runtime.so otkriva puno ovih funkcija uvozom i zamotavanjem, tako da Python skripta (u našem slučaju bootstrap.py) može koristiti neke od njih. Kako prikladno!

Popis djelomičnih funkcija iz liblambdaruntime.so demontaže. Hvala bogu za simbole.

Jedna od stvari koju sam u početku stvarno želio provjeriti bila je iza kulisa Lambdinog sustava naplate, a samo sam, gledajući imena funkcija, htio pokušati. Ali prvo - porazgovarajmo malo o Lambda naplatama.

Naplata lambde

Lambda ima vremenski model određivanja cijena, i bez uranjanja u sve pojedinosti, suština toga je da što više traje vaš Lambda, više ćete platiti. Kada pozivate Lambda, lako možete uočiti njezin početak i kraj u CloudWatch Dnevniku, kao i njegovo trajanje i trajanje naplate.

CloudWatch bilježi Lambdu. Možete vidjeti i trajanje Lambde i trajanje naplate

Međutim, postoji složeniji scenarij. Razmotrite sljedeće Lambda:

U uobičajenom vožnji, trajanje ove Lambda bi trebalo biti malo (naplaćeno trajanje gotovo uvijek bi trebalo biti 100 ms). Ali što se događa na prvom pozivu? Ili na hladnim startovima (gdje se modul ponovno uvozi)?

Lambda se prijavi kad je došlo do hladnog starta. Trajanje je mnogo veće od redovnog poziva

Empirijski testovi pokazuju da trajanje prvog priziva Lambde (ili hladni početak) sadrži trajanje inicijalizacije. Ali želio sam provjeriti kako Lambda to provodi.

Uvoz knjižnica

U bootstrap.py se pozivi na sljedeće funkcije, uvezene iz binarnih knjižnica:

  • lambda_runtime.receive_start () ili lambda_runtime.receive_invoke () - kad se primi novi okidač.
  • lambda_runtime.report_done () - kad god se radi Lambda

Sad bi moglo biti dobro vrijeme da dam još nekoliko detalja o reznici na koju sam govorio u prethodnom članku. Rezač je komponenta u Lambdi koja je zadužena za raspoređivanje vremena izvođenja za različite korisnike Lambdas-a, koji se vrše na spremniku. Ove funkcije šalju obavijest klizaču (i ostalim komponentama upravljanja Lambda) kada se izvrše Lambda ili primaju informacije o novoinstaliranim pogubljenjima.

Dakle, nakon što smo identificirali pozive od lambda_runtime i znali što je kriška, pokušao sam nešto pokušati: sam uvesti biblioteku runtime-a i zabaviti se s njom! (ovi su eksperimenti pronašli stvari na reznici, uglavnom čitajući rastavljanje i neke pokušaje i pogreške). Test koji želim podijeliti s vama također je prvi koji sam pokušao: nazvati lambda_runtime.report_done () iz moje Lambde. Ovo je kôd koji sam koristio:

Iznenađujuća stvar koju sam otkrio je da je tijekom pokretanja ovog primjera kod zaustavio tek nakon ispisa „Početak“. Zatim, kad sam ponovno pokrenuo svoju Lambdu, nastavio je s izvršenjem točno tamo gdje smo stali i ispisao "Nakon što je prvo učinjeno"! (Dodao sam san, jer je ponekad moj Lambda uspio izvući jedan „otisak“ prije nego što ga je kriška zaustavila). To se događalo iznova i iznova, sve dok se Lambda nije pogubio.

Cloudwatch bilježi za Lambda izvršenje. Napominjemo da imamo nekoliko ID-ova zahtjeva za istog Lambda!

Dakle, to je za mene postalo definitivno - kriška nam naplaćuje sve dok naša Lambda dobije vrijeme za CPU. To znači da se naše naplaćeno trajanje sastoji od dva dijela:

  1. Vrijeme pokretanja modula (samo pri prvom pozivu / hladnom startu)
  2. Naše stvarno trajanje funkcije

Izbjegavanje isteklih vremena

Osim što je vrlo cool, ovo otkriće ima i praktičnu (dobro… praktičnu stvar je u očima promatrača, ali definitivno je zanimljiva) uporabu: rukovanje s Lambda timeoutima! Razmotrite sljedeće Lambda:

Jednom sam pokrenuo Lambdu, a prestao je u liniji 13. Tada sam pričekao neko vrijeme i ponovno je pokrenuo. Rezultat je bio da je preostalo vrijeme povratka metode kontekstnog objekta bilo 0, ali Lambda nije istekla! Vrijeme Lambde je resetirano jer je ovo drugačiji poziv, a sada smo udvostručili istek vremena našeg Lambde (i račun za AWS, naravno)! Na primjer, koristan slučaj za to može biti petlja koja obrađuje mnoge zapise, a ponekad i istekne. Sada možemo provjeriti približavamo li se vremenu i ako je to slučaj, nazvati lambda_runtime.report_done () i čekati sljedeći okidač da pokupimo izvršenje točno od mjesta na kojem smo stali!

Dnevnik Cloudwatch-a iz priziva Lambda. Preostalo vrijeme: 0

Još jedna stvar koja mi se dogodila tijekom rada na problemu je da AWS može pružiti stvarnu značajku koja se temelji na takvom ponašanju, gdje korisnik može suspendirati svoju Lambda i nastaviti s te iste lokacije u sljedećem pozivu. Ovo bi moglo biti korisno ne samo za obradu značajnih količina podataka i rukovanje vremenskim intervalima. Drugi slučaj upotrebe može biti, na primjer, suspendiranje Lambde dok čeka skupo IO / neke druge rezultate zadatka, umjesto da plaćate Lambdino vrijeme u praznom hodu! Hoće li to učiniti? Ne znam. Je li to ultra cool? Defo.

Ipak, postoji slaba strana svega toga. Budući da je ovo šašav način, sljedeća dva sljedeća poziva Lambde neće uspjeti s Amazonovom unutarnjom pogreškom. Siguran sam da se i to može riješiti uz malo truda, ali za sada je to za mene bilo dovoljno dobro.

Zaključak

Naučili smo mnogo o internetskim predmetima AWS Lambda. Istražili smo binarne knjižnice u runtime okruženju i Lambda sustav naplate. Uvezli smo i knjižnicu za vrijeme izvođenja Lambde i koristili je za rješavanje vremenskih ograničenja! No, na AWS-u i drugim dobavljačima još uvijek ima puno toga što će se otkriti. Radujem se sljedećim izazovima, ako imate bilo koji zahtjev - javite mi!

Ažurirala sam i biblioteku otvorenog koda koja sadrži različite eksperimente koje sam provodio. Nadam se da će vam biti korisni!

Ovdje u Epsagonu razvijamo alat za praćenje prilagođen programima bez poslužitelja. Koristite poslužitelj bez poslužitelja i želite više čuti? Posjetite našu web stranicu!