{"id":8710,"date":"2026-06-17T08:00:00","date_gmt":"2026-06-17T06:00:00","guid":{"rendered":"https:\/\/blog.besharp.it\/?p=8710"},"modified":"2026-06-17T11:19:04","modified_gmt":"2026-06-17T09:19:04","slug":"telemetria-enterprise-su-aws-gestire-backfill-di-dati-massivi-con-ecs-e-databricks-senza-far-esplodere-i-costi","status":"publish","type":"post","link":"https:\/\/blog.besharp.it\/it\/telemetria-enterprise-su-aws-gestire-backfill-di-dati-massivi-con-ecs-e-databricks-senza-far-esplodere-i-costi\/","title":{"rendered":"Telemetria Enterprise su AWS: Gestire backfill di dati massivi con ECS e Databricks senza far esplodere i costi"},"content":{"rendered":"\n

Quando si progetta un’architettura di data ingestion per grandi volumi di dati, la teoria e la pratica spesso si scontrano. Sulla carta, i servizi cloud nativi offrono soluzioni pronte all’uso per qualsiasi scenario; nel mondo reale, ci si trova invece a fare i conti con limiti di throughput, eccezioni impreviste e, soprattutto, con l’impatto economico delle risorse configurate.<\/p>\n\n\n\n

In questo articolo voglio raccontarvi il dietro le quinte di un progetto di ingestion e trasformazione dei dati che abbiamo completato di recente per un nostro cliente, concentrandoci su una sfida architetturale specifica: il recupero dello storico dei dati e la gestione dei costi di AWS Kinesis Firehose.<\/p>\n\n\n\n

Il contesto e l’architettura iniziale<\/h2>\n\n\n\n

Il cliente aveva l’esigenza di centralizzare i dati di telemetria della propria flotta di veicoli aziendali. Questi dati venivano raccolti da un provider esterno e messi a disposizione tramite REST API. L’obiettivo era creare una pipeline capace di catturare questi dati in modalit\u00e0 quasi real-time (una sorta di CDC via API) e standardizzarli per l’analisi avanzata su Databricks.<\/p>\n\n\n\n

La strategia adottata per lo scarico consisteva nell’implementare una serie di servizi logici configurati per effettuare polling continuo sugli endpoint del provider: una volta avviati, questi componenti effettuavano chiamate cicliche per scaricare i dati a flusso continuo, mettendosi in attesa solo quando non risultavano nuovi record da recuperare.<\/p>\n\n\n\n

Per contestualizzare meglio il processo, ecco lo schema dell’architettura che illustra la pipeline descritta nei paragrafi seguenti.<\/p>\n\n\n\n

<\/p>\n\n\n

\n
\"\"<\/figure>\n<\/div>\n\n\n

<\/p>\n\n\n\n

Per l’infrastruttura di calcolo abbiamo deciso di sfruttare le ECS Managed Instances<\/strong>, allora appena uscite.<\/p>\n\n\n\n

Questa funzionalit\u00e0 di Amazon ECS permette di orchestrare ed eseguire container Docker sfruttando una capacit\u00e0 di calcolo dedicata e ottimizzata, integrata direttamente all’interno di un cluster gestito da AWS. Per noi \u00e8 stata la soluzione ideale: ci ha permesso di isolare i microservizi di polling in un ambiente sicuro e circoscritto, mantenendo tutta la flessibilit\u00e0, la scalabilit\u00e0 e la semplicit\u00e0 di gestione tipiche dell’ecosistema AWS.<\/p>\n\n\n\n

Se volete approfondire come funziona questo approccio, date un’occhiata all’articolo del nostro caro collega Damiano: Quando il Serverless gira sui Server: nuove opzioni per AWS Lambda e AWS Fargate con le Managed Instances<\/a>.<\/p>\n\n\n\n

Fin dal giorno uno, l’architettura su ECS \u00e8 stata strutturata per gestire in modo intelligente un mapping di sorgenti dati (divise per country ed entit\u00e0), separando i flussi in base alla frequenza di aggiornamento:<\/p>\n\n\n\n

1. I Servizi Real-time (CDC Long-Running)<\/h4>\n\n\n\n

Per i dati ad alta frequenza che necessitano di un flusso continuo, abbiamo configurato 15 servizi ECS sempre attivi<\/strong>. Questa numerica nasceva dalla combinazione di 5 database diversi divisi per Country (nazioni), ognuno dei quali conteneva 3 entit\u00e0 principali ad alto aggiornamento. Questi container gestivano la Change Data Capture (CDC) costante.<\/p>\n\n\n\n

2. I Task Schedulati (Batch settimanali)<\/h4>\n\n\n\n

Allo stesso tempo, c’erano altre 3 entit\u00e0 che si aggiornavano molto meno frequentemente e che contenevano volumi di dati ridotti. Lasciare dei servizi sempre accesi a fare polling su queste tabelle sarebbe stato uno spreco di risorse. Abbiamo quindi implementato altri 15 task ECS speculari (5 Country x 3 entit\u00e0), ma configurati come task schedulati, eseguiti una volta alla settimana per scaricare i dati e poi spegnersi subito dopo.<\/p>\n\n\n\n

La scelta di Firehose non \u00e8 stata casuale: per lo streaming di dati correnti \u00e8 uno strumento formidabile. Essendo un servizio completamente gestito (serverless<\/em>), si occupa in totale autonomia di scalare la capacit\u00e0 in base al traffico in ingresso, aggregare i dati in memoria (buffering per tempo o per dimensione del file) e scriverli su S3 gi\u00e0 partizionati per data. Questo ci ha permesso di evitare la scrittura di codice custom per la gestione dei file e di azzerare i costi di manutenzione infrastrutturale. <\/p>\n\n\n\n

Finch\u00e9 la pipeline ha elaborato i soli dati correnti, il sistema si \u00e8 dimostrato estremamente stabile ed efficiente.<\/p>\n\n\n\n

Il caricamento dello storico e il collo di bottiglia di Firehose<\/h2>\n\n\n\n

I problemi sono emersi quando, raggiunto lo stato di maturit\u00e0 della pipeline, \u00e8 stato avviato il recupero dello storico dei dati<\/strong>. Parliamo di una mole di dati imponente, quantificabile in decine di miliardi di record per una dimensione complessiva di pi\u00f9 di cento Terabyte di storage occupato.<\/p>\n\n\n\n

Nel momento in cui abbiamo aperto i rubinetti per importare i dati pregressi, l’architettura basata su Firehose ha mostrato i suoi limiti strutturali ed economici sotto carichi massivi:<\/p>\n\n\n\n

    \n
  1. Errori di PartitionCountExceeded<\/strong>: Il volume di richieste e la granularit\u00e0 del partizionamento hanno saturato le quote di Firehose, generando eccezioni e rallentando il processo di ingestion.<\/li>\n\n\n\n
  2. Esplosione dei costi<\/strong>: Firehose addebita i costi in base ai GB di dati elaborati. Applicare questa metrica a decine di Terabyte in un lasso di tempo ristretto ha causato un picco di spesa insostenibile e ingiustificato per dei dati “freddi”.<\/li>\n<\/ol>\n\n\n\n

    La soluzione: Il bypass per i dati massivi<\/h2>\n\n\n\n

    Davanti a questo scenario, abbiamo capito che una pipeline ottimizzata per lo streaming real-time non poteva essere adatta a un caricamento massivo di tipo batch. Abbiamo quindi diviso la strategia di ingestion:<\/p>\n\n\n\n