Lambdan sisäosat - Osa 2: Syvemmälle

AWS Lambda Runtime -kirjastojen tutkiminen

Kuva Jim Beaudoin

Palvelimeton kehitys on yksinkertaisesti paras. Kaksoisnapsauta, lähetä koodi ja olet valmis, eikö niin? Useimmat ihmiset ovat mielellään jättäneet sen siihen. Jos et ole suurin osa ihmisistä ja tarvitset tutustumista Lambdaan, tämä artikkeli on tarkoitettu vain sinulle.

Edellisessä artikkelissa saimme kuoren Lambda-säilöön, latasimme Lambdan suoritusympäristön ja löysimme sen komponentit:

  • bootstrap.py - python-koodi, joka kääri käsittelijäämme.
  • awslambda / runtime.so - python-yhteensopiva jaettu objekti bootstrap.py käyttää sitä hyvin, melkein kaikkeen.
  • liblambda * .so - runtime.so puolestaan ​​käyttää muita jaettuja objekteja. Keskitymme liblambdaruntime.so -palveluun, joka vastaa raskaasta nostosta Lambda-logiikan hallinnassa.

Meillä oli myös hauskaa sotkea bootstrap.py: n kanssa. Tällä kertaa rullaamme hihat ja sukellamme Lambda-runtime-ympäristön binaarikirjastoihin. Tutkimme Lambdan laskutusjärjestelmää ja (spoilerihälytys) pidämme hauskaa sekoittaa Lambdan aikakatkaisuja.

”Voi, paikat, joihin olet menossa! On hauskaa tehdä! On pisteitä. On voitettavia pelejä. ”- Dr. Seuss. Kuva: Joshua Earle

Kirjastojen tutkiminen

Kirjastot (liblambda * .so) koostuvat symboleista, joten voit oppia paljon kirjastoista vain käymällä yli symbolien nimet. Lisäksi runtime.so paljastaa suuren osan näistä toiminnoista tuomalla ja kääntämällä ne, joten Python-skripti (tapauksessamme bootstrap.py) voi käyttää joitain niistä. Kuinka kätevää!

Osittainen toimintoluettelo julkaisusta liblambdaruntime.so purettaessa. Kiitos jumala symboleista.

Yksi niistä asioista, joita halusin alun perin todella tarkistaa, oli Lambdan laskutusjärjestelmän kulissien takana, ja katsomalla vain toimintojen nimiä, minulla oli joitain kokeiluja, jotka halusin kokeilla. Mutta ensin - puhutaanpa vähän Lambdan laskutuksesta.

Lambdan laskutus

Lambdalla on aikapohjainen hinnoittelumalli, ja syventämättä kaikkia yksityiskohtia, sen ydin on, mitä kauemmin Lambdalla kestää, sitä enemmän maksat. Kun kutsut lambdaan, voit helposti havaita sen alun ja lopun CloudWatch-lokit, samoin kuin sen keston ja laskutuksen keston.

CloudWatch kirjaa lambdan. Voit nähdä sekä lambdan keston että laskun keston

On kuitenkin monimutkaisempi skenaario. Mieti seuraavaa lambdaa:

Tyypillisessä ajossa tämän lambdan keston tulisi olla pieni (laskutuksen keston tulisi melkein aina olla 100 ms). Mutta mitä tapahtuu ensimmäiselle kutsulle? Tai kylmäkäynnistyksissä (jos moduuli tuodaan uudelleen)?

Lambda kirjaa, kun kylmäkäynti tapahtui. Kesto on paljon pidempi kuin säännöllinen kutsu

Empiiriset testit osoittavat, että ensimmäisen Lambda-kutsun (tai kylmäkäynnistyksen) kesto sisältää alustuksen keston. Mutta halusin tarkistaa, kuinka Lambda toteuttaa tämän.

Kirjastot tuodaan

Bootstrap.py -sovelluksessa kutsutaan seuraaviin toimintoihin, jotka tuodaan binaarikirjastosta:

  • lambda_runtime.recept_start () tai lambda_runtime.recept_invoke () - kun uusi liipaisin on vastaanotettu.
  • lambda_runtime.report_done () - aina, kun lambda tehdään

Nyt saattaa olla hyvä aika antaa lisätietoja viipaloijasta, johon viittasin edellisessä artikkelissa. Leikkurimerkki on Lambdan komponentti, joka vastaa käyttöajan allokoimisesta eri käyttäjälampduille, jotka käyttävät konttia. Nämä toiminnot lähettävät ilmoituksen viipaloijalle (ja muille Lambdan hallintakomponenteille), kun Lambda-suoritukset suoritetaan, tai vastaanottavat tietoja vasta aloitetuista suorituksista.

Joten kun olemme löytäneet puhelut osoitteesta lambda_runtime, ja tiedämme, mikä viipaloija on, jouduin kokeilemaan jotain: tuon itse runtime-kirjaston ja pidin siitä hauskaa! (Nämä kokeet ovat kuinka sain selville tavaroita leikkurilla, lähinnä lukemalla purkamista ja joitain kokeiluja ja virheitä). Testi, jonka haluan jakaa kanssasi, on myös ensimmäinen, jonka yritin: soittamalla lambda_runtime.report_done () Lambdan sisäpuolelta. Tämä on käyttämäni koodi:

Yllättävänä havaitsin, että tämän esimerkin suorittamisen aikana koodini pysähtyi vasta, kun oli tulostanut ”Alku”. Sitten, kun laukaistin lambdani uudelleen, se jatkoi suorittamista tarkalleen siitä kohdasta, josta lähdimme - ja tulostin ”Kun ensin tehty”! (Lisäsin nukkumisen, koska joskus lambdani onnistui vetämään yhden ”tuloksen” ennen kuin viipaloija keskeytti sen). Tämä tapahtui yhä uudelleen, kunnes Lambdan teloitus päättyi.

Cloudwatch-lokit Lambda-suoritusta varten. Huomaa, että meillä on useita pyyntö-tunnuksia samalle Lambdalle!

Joten tämä teki siitä minulle selvän - viipaloija laskuttaa meitä niin kauan kuin Lambdamme saa CPU-ajan. Tämä tarkoittaa, että laskutuskesto koostuu kahdesta osasta:

  1. Moduulin alustusaika (vain ensimmäisessä kutsussa / kylmäkäynnistys)
  2. Todellinen funktion kesto

Lambdan aikakatkaisujen välttäminen

Erittäin viileän lisäksi tällä löytöllä on käytännöllinen (hyvin… käytännöllinen onkin katsojan silmissä, mutta se on ehdottomasti mielenkiintoinen) käyttö: Lambdan aikakatkaisujen käsittely! Mieti seuraavaa lambdaa:

Käynnistin lambdan kerran ja se pysähtyi riville 13. Sitten odotin jonkin aikaa ja käynnistin sen uudelleen. Tuloksena oli, että kontekstiobjektin menetelmä palautui jäljellä olevan ajan 0, mutta lambda ei aikakatkennut! Lambdan aikakatkaisu nollattiin, koska tämä on erilainen kutsu, ja olemme nyt kaksinkertaistaneet Lambdan aikakatkaisun (ja tietysti AWS-laskun)! Hyvä esimerkki tästä voi olla silmukka, joka käsittelee monia tietueita ja joskus aikakatkaisua. Voimme nyt tarkistaa, lähestymmekö aikakatkaisua, ja jos niin, soita lambda_runtime.report_done () ja odottaa seuraavaa laukaista noutaakseen suorituksen juuri siitä kohdasta, jossa keskeytyimme!

Cloudwatch-loki Lambda-kutsusta. Jäljellä oleva aika: 0

Toinen asia, joka tapahtui minulle asiaa käsitellessä, on, että AWS voi toimittaa todellisen ominaisuuden, joka perustuu tähän käyttäytymiseen, jolloin käyttäjä voi keskeyttää lambdansa ja jatkaa samasta paikasta seuraavassa kutsussaan. Tästä voi olla hyötyä paitsi merkittävien tietomäärien käsittelemisessä ja keskellä olevien aikakatkaisujen käsittelemisessä. Toinen käyttötapa voi olla esimerkiksi Lambdan keskeyttäminen odottamalla kallista IO / jotain muuta tehtävän tulosta sen sijaan, että maksat Lambdan käyttämättömästä ajasta! Aiovatko he sen? En tiedä. Onko se erittäin siistiä? Defo.

Kaikella tällä on kuitenkin haittapuoli. Koska tämä on hacky tapa, seuraavat kaksi seuraavaa lambdan kutsut epäonnistuvat Amazonin sisäisen virheen vuoksi. Olen varma, että voidaan myös ratkaista tämä ongelma pienellä vaivalla, mutta toistaiseksi tämä oli minulle tarpeeksi hyvä.

johtopäätös

Olemme oppineet paljon AWS Lambdan sisäisistä. Tutkimme runtime-ympäristön binaarikirjastoja ja Lambdan laskutusjärjestelmää. Tuomme myös Lambdan ajonaikaisen kirjaston ja käytimme sitä aikakatkaisujen käsittelemiseen! AWS: ltä ja muilta valmistajilta on kuitenkin vielä paljon löydettävää. Odotan innolla seuraavia haasteita, jos sinulla on pyyntöjä - kerro minulle!

Olen päivittänyt myös avoimen lähdekoodin kirjaston, joka sisältää suorittamasi kokeilut. Toivottavasti löydät siitä hyödyllisen!

Täällä Epsagonissa kehitämme räätälöityä seurantatyökalua palvelimettomiin sovelluksiin. Käytätkö palvelinta ja oletko kiinnostunut kuulemaan lisää? Vieraile verkkosivuillamme!