Monitorare le pipeline con Amazon CloudWatch

Amazon CloudWatch è il servizio centrale di observability per i workload dati su AWS. Raccoglie metrics (numeriche, aggregate nel tempo), logs (output applicativo), permette di creare alarms che scattano su soglia e dashboards per la visione d’insieme. AWS Glue, Amazon EMR, AWS Lambda, Amazon Kinesis e Amazon Redshift pubblicano metriche native: numero di executor, memoria, record processati, età dei dati in stream, code di query.

Distingui bene i ruoli. CloudWatch serve al monitoraggio operativo (performance, errori, saturazione). AWS CloudTrail invece registra le chiamate API a livello di account: serve per l’audit di “chi ha fatto cosa e quando”, non per le performance. Amazon EventBridge consuma gli eventi di cambio stato dei job (es. un job Glue che passa a FAILED) per attivare reazioni event-driven o notifiche, e gestisce lo scheduling. Un pattern tipico è: metrica CloudWatch → Alarm → SNS per l’alert, oppure EventBridge rule → Lambda per il rimedio automatico.

Troubleshooting di job falliti e colli di bottiglia

Per i job Glue (Spark) usa il continuous logging su CloudWatch Logs e la Spark UI per analizzare gli stage. Le cause ricorrenti di fallimento o lentezza sono: data skew (una partizione molto più grande delle altre), spill to disk per memoria insufficiente, errori Out Of Memory, numero di worker inadeguato o timeout. Il rimedio non è quasi mai “aumentare le risorse alla cieca”: spesso serve ripartizionare i dati o correggere la logica di join.

Su Amazon Redshift analizza le query lente tramite le system views (le famiglie SYS_, STL_, SVL_, SVV_). Distribution key e sort key sbagliate provocano data redistribution e scansioni inutili tra i nodi. Il Workload Management (WLM), in particolare l’Automatic WLM, gestisce le code, mentre il Concurrency Scaling assorbe i picchi di concorrenza. Su EMR i log di YARN e dei nodi finiscono su Amazon S3 per l’analisi post-mortem.

Il problema dei small file

Molti file piccoli su S3 degradano le performance: ogni oggetto genera overhead di richiesta, Spark crea un task per file (troppi task minuscoli), e il query planning di Amazon Athena rallenta enormemente. La soluzione è la compaction verso file di dimensione ottimale (indicativamente 128 MB - 1 GB), l’uso di formati columnar come Parquet o ORC, e le tabelle in formato aperto (Apache Iceberg, Hudi) che offrono compaction gestita. A monte, configurare il buffering di Amazon Data Firehose per aggregare gli eventi prima di scrivere evita di generare small file dallo streaming. Evita anche l’over-partitioning: troppe partizioni con pochi dati ciascuna ricreano lo stesso problema.

Ottimizzare costo e performance

Per Athena e Redshift Spectrum il costo dipende dai dati scansionati: partitioning, partition pruning, formati columnar e compressione riducono direttamente il volume letto e quindi la spesa. Su Redshift, i nodi RA3 con managed storage separano compute e storage, Spectrum scarica i dati freddi su S3 e le materialized view accelerano le query ricorrenti. Su Glue, l’Auto Scaling dimensiona i worker sul carico reale e la execution class Flex abbatte i costi dei job batch non urgenti. Su S3, sfrutta storage class e lifecycle policy (con S3 Intelligent-Tiering quando gli accessi sono imprevedibili). Scegli la compressione in base all’obiettivo: Snappy per la velocità, gzip o zstd per il ratio.

Trappole tipiche d’esame

  • Audit di chi ha modificato/lanciato un job → soluzione: è CloudTrail (API-level auditing), non CloudWatch, che invece copre metriche e log operativi.
  • Query Athena lenta e costosa su una tabella con migliaia di small file → soluzione: compaction + Parquet + partitioning; Athena è serverless, non puoi “aggiungere nodi”.
  • Ridurre il costo di Athena → soluzione: il costo dipende dai dati scansionati, non dal numero di query né dalla durata; agisci su formato columnar, compressione e partizioni.
  • Job Glue in OOM o con spill → soluzione: verifica data skew e ripartiziona/abilita Auto Scaling, non limitarti ad alzare le DPU alla cieca.
  • COPY in Redshift lenta da un unico file enorme → soluzione: splitta l’input in più file (multipli del numero di slice) per sfruttare il caricamento parallelo.
  • Batch notturno non time-sensitive per risparmiare → soluzione: Glue Flex execution class o istanze Spot su EMR, non il provisioning standard on-demand.