AWS DMS: risolvere i colli di bottiglia della CDC tra MongoDB e S3
Il Contesto
Si aveva la necessità di trasferire una collection MongoDB su di un bucket Amazon S3, effettuando un caricamento iniziale (Full Load) seguito dalla replicazione continua delle modifiche (Change Data Capture, CDC), per alimentare un Data Warehouse separato. A tale scopo, era stata configurata una task AWS DMS (Database Migration Service) con sorgente MongoDB e target S3, in modalità Full load + CDC.
Il Problema
Dopo il completamento con successo della fase di Full Load e l’inizio della CDC, la task risultava procedere all’apparenza correttamente. Tuttavia, nessun file relativo alla CDC veniva prodotto nel bucket target e le metriche di latenza dal sorgente e dal target mostravano una crescita costante. I log della task non evidenziavano errori espliciti e l’utilizzo di CPU e memoria nell’istanza di replica era del tutto contenuto.
Prima anaisi e tentativo di risoluzione
Prima analisi e tentativo di risoluzione
Dopo un confronto con il supporto AWS — che ha confermato che la task leggeva le modifiche sul sorgente ma non le applicava sul target, senza errori evidenti — si è notato dalle metriche un elevato numero di IOPS (Input/Output Operations Per Second) effettuate sul disco dell'istanza di replica, prevalentemente in scrittura.
Le istanze di DMS utilizzano dischi di tipo gp2, ovvero di tipo burstable, le cui performance di I/O sono legate alla dimensione (forniscono una baseline di 3 IOPS per GB, con un minimo di 100 e la possibilità di raggiungere i 3000 IOPS per brevi periodi).
Per l’istanza interessata si è visto un uso di circa 1000 IOPS all’avvio della task, per poi assestarsi attorno a 170 IOPS in scrittura, poco sopra la soglia dei 150 IOPS garantiti dal disco di 50 GB presente:
Il disco è stato quindi allargato a 350 GB per garantire una baseline di IOPS maggiore (1050 IOPS), in linea con il carico osservato. A seguito della modifica, la task ha iniziato a produrre i primi file nel bucket S3. Tuttavia, la latenza diminuiva troppo lentamente, con momenti in cui tornava persino a salire:
Ulteriori analisi e azioni correttive (La Root Cause)
Sono state effettuate ulteriori indagini sulle metriche, dalle quali è emersa una discrepanza fondamentale: l’elevato numero di IOPS in scrittura (corrispondente a un volume di circa 13 MB/s scritti su disco) non era giustificato dal basso carico di rete, fermo a circa 300 KB/s. Questo ha suggerito che la mole di scritture su disco non fosse legata alla migrazione dei dati in sé.
Analizzando a fondo i comportamenti, si è scoperto che la task generava decine di messaggi di log al secondo classificati come warning, i quali indicavano solamente l’avanzamento della stream position relativa alla lettura dal sorgente:
2025-12-12T08:16:40 [SOURCE_CAPTURE ]W: Stream position is now '1765458140,144'. (change_streams_capture.c:505)
Per la fase di CDC, DMS utilizza i Change Streams di MongoDB. Questi utilizzano dei resume tokens (o dei timestamp) per tracciare il punto da cui ricominciare a leggere gli eventi in caso di interruzione. Un messaggio di log ha evidenziato che il resume token superava una soglia interna di DMS, costringendo il sistema a utilizzare i timestamp e generando così la valanga di warning:
2026-01-12 11:34:24+00:00 DMS_INTERNAL W Stream position at resumeToken '{ "_data" : "......" }' and timestamp '1768217664,5' exceeds the max stream position size of 257 bytes. Falling back on using timestamp as stream position. change_streams_capture.c 502
È stato modificato il livello di log per il componente SOURCE_CAPTURE, limitandolo ai soli errori. Con questa semplice modifica, la task ha ripreso l’attività con un’efficienza nettamente superiore: le IOPS sono crollate e la task si è allineata con il sorgente in brevissimo tempo. Il collo di bottiglia era causato unicamente dall'enorme mole di log scritti sul disco gp2.
Punti chiave e Lezioni Apprese
- Monitoraggio dei dischi gp2: DMS utilizza dischi gp2. È fondamentale monitorare le metriche di I/O, poiché il comportamento burstable può creare colli di bottiglia silenti anche se CPU, RAM e rete sono scariche.
- Correlazione delle betriche: il confronto tra throughput di rete e throughput su disco è stato vitale per capire che il problema non derivava dai dati migrati. Mai guardare una metrica in isolamento.
- Bilanciamento tra logging e performance: un livello di log troppo verboso può saturare le risorse di I/O di un disco, degradando drasticamente le performance dell'intero processo di replica.
Il dato più impressionante dell'intervento è la discrepanza tra ciò che transitava in rete e ciò che veniva scritto su disco.
Riduzione del throughput anomalo: prima dell'intervento, il sistema generava 13 MB/s di scritture su disco a fronte di soli 300 KB/s di dati reali trasferiti in rete. Questo significa che il logging generava un overhead del 4200% (circa 43 volte il peso dei dati reali). L'intervento ha azzerato questa discrepanza, riportando il rapporto Rete/Disco a 1:1.
Crollo delle IOPS: da una media costante di 170 IOPS in scrittura (che saturava la baseline del disco da 50 GB), il carico è tornato a un livello fisiologico (presumibilmente vicino allo zero o comunque ampiamente sotto i 100 IOPS base), eliminando del tutto il rischio di esaurimento del burst balance.
Ottimizzazione Storage: se dopo il fix avete riportato il disco alle dimensioni originali, avete ottenuto una riduzione dell'allocazione da 350 GB ai 50 GB iniziali. Questo si traduce in un risparmio immediato dell'85% sui costi mensili di quello specifico volume EBS, dimostrando che l'analisi ha evitato uno spreco economico ricorrente.
Quali sono le tue sfide?
Siamo già pronti, possiamo risolverle per ieri!
Contatta subito uno dei nostri tecnici. La tempestività è il nostro forte.