AWS Lambda: modello di esecuzione e concorrenza

AWS Lambda esegue codice in execution environment effimeri, senza gestire server. Si paga per numero di invocazioni e per durata moltiplicata per la memoria configurata; la CPU scala proporzionalmente alla memoria assegnata. La concorrenza è il numero di richieste servite simultaneamente e per default attinge a un pool condiviso a livello di account (limite soft, elevabile via Service Quotas).

La reserved concurrency assegna a una funzione una quota dedicata: garantisce quella capacità e allo stesso tempo la limita, perché la funzione non supera mai quel valore andando in throttling. È utile per proteggere risorse a valle (es. un database relazionale con poche connessioni) o per isolare funzioni critiche dal resto dell’account. La provisioned concurrency invece pre-inizializza un numero di environment già “caldi”, eliminando i cold start per carichi latency-sensitive; ha un costo aggiuntivo e si abbina spesso ad Application Auto Scaling e agli alias. L’esame DVA-C02 si sostiene in inglese; il passing score è 700/1000.

Event source mapping e trigger

Le sorgenti di eventi si dividono in modalità push (Amazon API Gateway, Amazon S3, Amazon SNS invocano Lambda direttamente) e modalità poll-based gestite dall’event source mapping, dove è Lambda a fare polling del servizio: Amazon SQS, Amazon Kinesis Data Streams, Amazon DynamoDB Streams, Amazon MSK. I parametri chiave sono batch size e batch window (quanti record accumulare, o per quanto tempo, prima di invocare la funzione).

Con SQS standard Lambda scala aumentando i poller in base al carico; con SQS FIFO l’ordine è preservato per message group id. Con Kinesis e DynamoDB Streams l’elaborazione avviene per shard, ordinata, con un parallelization factor (più batch concorrenti per shard) e la partial batch response per non riprocessare l’intero batch in caso di errore su un singolo record. Per la gestione errori si configurano retry, maximum age dei record e una destinazione di scarto (DLQ oppure on-failure destination).

Variabili d’ambiente, layer e dipendenze

Le environment variables passano configurazione al codice senza ricompilare; a riposo sono cifrate e possono usare una chiave KMS dedicata. Non sono il posto giusto per segreti sensibili: per credenziali e API key si usano AWS Secrets Manager o SSM Parameter Store, letti a runtime.

I layer impacchettano dipendenze condivise (librerie, runtime custom, file comuni) riutilizzabili tra più funzioni: fino a 5 layer per funzione, entro il limite complessivo del deployment package unzipped di 250 MB. Per dipendenze molto grandi (ML, binari) conviene la container image, che porta il limite fino a 10 GB. Versioni e alias completano il quadro: $LATEST è mutabile, le versioni pubblicate sono immutabili, e un alias può puntare a una versione con pesi per deployment canary o linear (integrabile con AWS CodeDeploy).

Lambda vs container: ECS, Fargate, ECR

Lambda è ideale per carichi event-driven, brevi e intermittenti, con scaling automatico e zero server da gestire. Ha però vincoli: timeout massimo di 15 minuti e limiti su memoria e storage effimero (/tmp). Quando servono processi long-running, controllo pieno del runtime, protocolli non HTTP o un utilizzo costante e prevedibile, si scelgono i container su Amazon ECS. Con il launch type Fargate non si gestiscono istanze EC2 (serverless per container); con il launch type EC2 si controlla l’host sottostante. Le immagini risiedono in Amazon ECR, usato sia da ECS/Fargate sia dalle container image di Lambda. In sintesi: eventi brevi e sporadici scelgono Lambda; job lunghi, sempre attivi o con dipendenze pesanti/custom scelgono ECS/Fargate.

Trappole tipiche d’esame

  • Job che supera i 15 minuti → soluzione: non è un caso per Lambda; usa ECS/Fargate. La container image su Lambda alza la dimensione a 10 GB ma non il timeout.
  • Cold start su API latency-sensitive → soluzione: provisioned concurrency (environment pre-caldi), non reserved concurrency, che serve invece a limitare/garantire il numero massimo di esecuzioni.
  • Proteggere un database a valle dal sovraccarico → soluzione: reserved concurrency sulla funzione per capparne la concorrenza massima e non esaurire le connessioni.
  • Segreti in environment variables → soluzione: spostali in AWS Secrets Manager o SSM Parameter Store; le env var vanno bene solo per configurazione non sensibile.
  • Ordine dei messaggi garantito → soluzione: SQS FIFO con message group id, oppure Kinesis/DynamoDB Streams (ordine per shard); SQS standard non garantisce l’ordine.
  • Dipendenza condivisa tra molte funzioni → soluzione: un Lambda layer (max 5, entro i 250 MB unzipped), invece di duplicarla in ogni deployment package.