Questo documento spiega come ridurre al minimo l'impatto degli errori dei job per le pipeline batch di grandi dimensioni. I guasti dei workload di grandi dimensioni sono particolarmente impattanti a causa del tempo e del denaro necessari per il ripristino e la correzione. Riprovare queste pipeline da zero quando non riescono è costoso in termini di tempo e denaro.
Per ridurre i costosi errori della pipeline batch, segui le linee guida riportate in questa pagina. Poiché non è sempre possibile evitare completamente gli elementi non riusciti e gli errori della pipeline, le tecniche fornite si concentrano sull'aumento della resilienza, sulla riduzione del costo degli errori e sulla semplificazione del debug e della comprensione degli errori quando si verificano.
Per le best practice generali per le pipeline, consulta Best practice per le pipeline Dataflow.
Eseguire piccoli esperimenti per job di grandi dimensioni
Prima di eseguire un job batch di grandi dimensioni, esegui uno o più job più piccoli su un sottoinsieme del set di dati. Questa tecnica può fornire una stima dei costi e aiutare a trovare potenziali punti di errore.
Stima dei costi
L'esecuzione di esperimenti può fornire un limite inferiore stimato del costo totale di esecuzione del job. In genere, il calcolo del costo del job è cost of test
job*size(full dataset)/size(test dataset). A seconda della pipeline, il costo
può essere scalato in modo superlineare o, meno spesso, sublineare. Tuttavia, questo passaggio
spesso fornisce una buona stima approssimativa del costo del job. Puoi anche provare diverse
dimensioni degli input per ottenere una stima migliore di come vengono scalati i costi. Utilizza queste
informazioni per decidere se procedere con la pipeline esistente o
riprogettarla per ridurre i costi.
Trovare i punti di errore
L'esecuzione di esperimenti può rivelare bug, potenziali punti di errore o potenziali problemi di configurazione ed efficienza. Puoi anche esaminare altre metriche della pipeline, ad esempio le seguenti:
- Se la pipeline utilizza quasi tutta la memoria disponibile, potrebbe riscontrare eccezioni di esaurimento della memoria (OOM) in caso di carico maggiore o con record eccezionalmente grandi. Potresti dover eseguire il provisioning di più memoria per il job finale per evitare questi errori di esaurimento della memoria.
- Se la tua pipeline subisce cali di velocità effettiva, esamina i log della pipeline per determinare il motivo. Potresti trovare un elemento bloccato o una parte del tuo set di dati con prestazioni particolarmente scarse. Puoi elaborare questi punti dati separatamente oppure puoi imporre un timeout durante l'elaborazione degli elementi. Per ulteriori informazioni, consulta la sezione Timeout per i record costosi di questo documento.
- Se la pipeline ha un rendimento molto peggiore in un'attività su Dataflow
rispetto a quello locale, esamina la logica della pipeline per capire il motivo. Ad esempio, se ottieni lo stesso throughput con otto core su Dataflow che con un core in locale, il job potrebbe essere limitato dalla contesa per una risorsa. Se noti che il rendimento
è inferiore alle aspettative, valuta una o più delle seguenti opzioni:
- Esegui altri esperimenti con configurazioni diverse di macchine o software.
- Esegui test in locale con più core contemporaneamente.
- Ispeziona il codice per trovare potenziali colli di bottiglia durante il deployment su larga scala.
Se la pipeline ha suggerimenti per Dataflow, seguili per migliorare le prestazioni.
Utilizza le code di messaggi non recapitabili per gestire dati errati imprevisti
Le pipeline spesso hanno esito positivo sulla maggior parte degli elementi di input, ma non su un piccolo sottoinsieme dell'input. Potresti non rilevare questo problema quando esegui esperimenti di piccole dimensioni, perché questi esperimenti testano solo un sottoinsieme dell'input. Per impostazione predefinita, Dataflow riprova a eseguire questi task non riusciti quattro volte in modalità batch e un numero illimitato di volte in modalità di streaming. In modalità batch, dopo aver raggiunto il limite di tentativi, l'intero job non va a buon fine. In modalità streaming, può bloccarsi a tempo indeterminato.
In molti job, puoi escludere questi elementi non riusciti dalla pipeline e
completare il resto del job utilizzando una coda di messaggi non elaborati. La coda dei messaggi non recapitabili passa i record non riusciti a un output separato
PCollection, che puoi gestire separatamente dall'output principale. Questa
configurazione ti consente di progettare una policy per questi record. Ad esempio, puoi
scriverli manualmente in Pub/Sub, esaminarli e pulirli, quindi
riprocessare i record.
Molte trasformazioni Apache Beam includono il supporto integrato per le code di messaggi non recapitabili.
In Java, puoi accedervi con un oggetto ErrorHandler. In Python, puoi accedervi utilizzando il metodo with_exception_handling. Alcune trasformazioni hanno modi personalizzati per definire le code dei messaggi non recapitabili, che
puoi leggere nella documentazione relativa alla trasformazione. Per ulteriori informazioni,
consulta Utilizzare le code dei messaggi non recapitabili per la gestione degli errori.
Per determinare se il tuo job soddisfa i criteri per una coda di messaggi non recapitabili, consulta la sezione Limitazioni di questo documento.
Limitazioni della coda dei messaggi non recapitabili
Nei seguenti scenari, una coda di messaggi non elaborabili potrebbe non essere utile:
- Errori del ciclo di vita completo del worker o di
DoFn. Se l'elaborazione non va a buon fine per l'intero worker o bundle, una coda di messaggi non recapitabili non può rilevare l'errore. Ad esempio, se la pipeline rileva un'eccezione di esaurimento della memoria (OOM), tutte le attività attive sulla VM hanno esito negativo e vengono riprovate, senza inviare nulla alla coda dei messaggi non recapitabili. - Combinazioni o altre aggregazioni. Se la pipeline esegue calcoli che richiedono la presenza e l'elaborazione di tutti gli elementi di input come parte del risultato, fai attenzione quando utilizzi una coda di messaggi non recapitabili prima di questo passaggio. L'utilizzo di una coda di messaggi non recapitabili esclude parte dei dati di input dal risultato. L'aggiunta di una coda di messaggi non recapitabili potrebbe compromettere la correttezza a favore della tolleranza agli errori.
- Errori nel percorso della coda dei messaggi non recapitabili. Se un elemento non viene inviato
al sink della coda dei messaggi non recapitabili, l'intera pipeline può non riuscire.
Per evitare questo errore, mantieni la logica della coda dei messaggi non recapitabili il più semplice
possibile. Puoi aggiungere un passaggio di attesa (vedi
wait class) per assicurarti che l'input principale termini prima di scrivere gli elementi della coda di messaggi non elaborabili. Questa configurazione potrebbe ridurre le prestazioni e ritardare i segnali di errore della pipeline. - Elementi trasformati parzialmente. Se inserisci una coda dei messaggi non recapitabili a metà della pipeline, la coda dei messaggi non recapitabili potrebbe restituire l'elemento trasformato parzialmente e non avere accesso all'elemento originale. Di conseguenza, non puoi pulire l'elemento ed eseguire nuovamente la pipeline. Potresti invece dover applicare una logica diversa per correlare l'output nella coda dei messaggi non recapitabili all'elemento originale oppure potresti dover interpretare ed elaborare l'elemento trasformato parzialmente. Potrebbe anche generare risultati incoerenti. Ad esempio, se gli elementi vengono inviati lungo due rami di una pipeline e ogni ramo invia elementi che causano eccezioni a una coda di messaggi non recapitabili, un singolo elemento di input potrebbe essere inviato lungo uno, l'altro, entrambi o nessuno dei rami.
Timeout dei record costosi
Le pipeline potrebbero smettere di rispondere durante l'elaborazione di un piccolo sottoinsieme di elementi
più costosi o che raggiungono una limitazione che causa la mancata risposta, ad esempio un
blocco. Per risolvere questo problema, alcune trasformazioni ti consentono di impostare un timeout e di non riuscire
a eseguire gli elementi in timeout in qualsiasi DoFn di codice utente che riscontra questo problema. Ad esempio, puoi utilizzare il metodo with_exception_handling di Python. Quando utilizzi
i timeout con una coda di messaggi non recapitabili, la pipeline può continuare a elaborare gli elementi
integri e fare progressi, mentre puoi rielaborare gli elementi costosi
separatamente. Questa configurazione può comportare un costo in termini di prestazioni.
Per determinare quali operazioni DoFn potrebbero richiedere un timeout, esegui piccoli
esperimenti prima di avviare la pipeline completa.
Abilita la scalabilità automatica verticale
Se non sai quanta memoria richiede il tuo job o ritieni che il tuo job rischi di esaurire la memoria, attiva la scalabilità automatica verticale. Questa funzionalità aiuta a evitare errori di esaurimento della memoria quando le pipeline vengono eseguite su larga scala o quando incontrano elementi eccezionalmente grandi.
Poiché la scalabilità automatica verticale potrebbe aumentare il costo del job e non impedisce tutti gli errori di esaurimento della memoria, devi comunque risolvere i problemi di consumo eccessivo di memoria. La scalabilità automatica verticale richiede anche Dataflow Prime, che presenta limitazioni aggiuntive e un modello di fatturazione diverso.
Utilizzare l'esecuzione speculativa per evitare ritardatari
Per le pipeline batch, puoi attivare l'esecuzione speculativa, una funzionalità per mitigare l'impatto delle attività lente o bloccate. Questi task lenti o bloccati sono noti anche come ritardatari. Questa funzionalità avvia esecuzioni ridondanti o di backup delle attività che richiedono troppo tempo. Viene utilizzata la prima attività completata e l'altra viene annullata, il che può migliorare il tempo di completamento complessivo della pipeline.
L'esecuzione speculativa può aiutare le pipeline a completarsi più rapidamente fornendo un percorso di esecuzione alternativo per gli elementi di lavoro che subiscono ritardi dovuti a macchine di lavoro lente o ad altri problemi temporanei, come bug non deterministici, limitazione delle risorse o problemi di connettività.
Limitazioni e considerazioni
Prima di attivare l'esecuzione speculativa, tieni presente quanto segue:
- Pipeline di streaming:l'esecuzione speculativa non è supportata per le pipeline di streaming.
- Potenziale variazione dei costi: l'impatto sui costi di questa funzionalità è difficile da stimare perché è difficile prevedere i ritardatari e il provisioning delle attività di backup. Ad esempio, mentre un elemento di lavoro di backup consuma risorse aggiuntive, aumentando potenzialmente i costi, il suo completamento anticipato può portare a un risparmio di risorse e a una riduzione dei costi. In entrambi gli scenari, l'impatto complessivo dovrebbe essere minimo.
- Elementi di lavoro a esecuzione prolungata coerenti: l'esecuzione speculativa potrebbe non aiutare in modo significativo con elementi di lavoro a esecuzione prolungata coerenti, come le scorciatoie da tastiera, poiché il problema di base che causa la lentezza persisterebbe.
Per saperne di più sugli elementi in ritardo nei job batch, vedi Risolvere i problemi relativi agli elementi in ritardo nei job batch.
Abilita l'esecuzione speculativa
Per abilitare l'esecuzione speculativa, utilizza l'opzione del servizio Dataflow map_task_backup_mode. Sono disponibili due modalità:
Java
--dataflowServiceOptions=map_task_backup_mode=ON--dataflowServiceOptions=map_task_backup_mode=CAUTIOUS
Python / Go
--dataflow_service_options=map_task_backup_mode=ON--dataflow_service_options=map_task_backup_mode=CAUTIOUS
In modalità ON, viene pianificata un'attività di backup se il runtime previsto dell'attività originale
è circa il 20% più lungo del runtime previsto di una nuova attività.
In modalità CAUTIOUS, viene pianificata un'attività di backup se il runtime previsto dell'attività originale è circa il 70% più lungo del runtime previsto di una nuova attività.
Per verificare che l'esecuzione speculativa sia abilitata, controlla i messaggi di log. Cerca le voci che mostrano l'avvio delle attività di backup. Ciò conferma che l'esecuzione speculativa è attivata. Per visualizzare questi log, vai al riquadro Log dei job per la tua pipeline (Job > scegli il tuo job > sezione Log > Log dei job). Il messaggio del log viene visualizzato nel seguente modo:
Backup issued in step STEP_NAME. ADDITIONAL_INFORMATION.
Soluzioni alternative per le pipeline soggette a errori
Alcune pipeline sono particolarmente soggette a errori. Sebbene sia meglio risolvere la causa di questi errori, per ridurre il costo dei guasti valuta le seguenti opzioni.
Materializzare i risultati intermedi
Le pipeline potrebbero avere una o più trasformazioni particolarmente costose che dominano
il tempo di esecuzione della pipeline. Gli errori della pipeline dopo questa trasformazione possono essere
particolarmente dannosi, perché tutto il lavoro già completato viene perso. Per
evitare questo scenario, valuta la possibilità di scrivere PCollections intermedi generati da
passaggi costosi in un sink come Cloud Storage. Questa configurazione riduce
il costo di un errore. Devi valutare questo vantaggio rispetto al costo dell'esecuzione della scrittura aggiuntiva. Puoi utilizzare questo risultato materializzato in uno dei seguenti modi:
- Dividi la pipeline originale in due pipeline: una che scrive il risultato intermedio e una che lo legge.
- Solo in caso di errore della pipeline, leggi e appiattisci i risultati sia dell'origine originale sia della raccolta intermedia materializzata.
Per assicurarti che queste materializzazioni vengano scritte prima dell'ulteriore elaborazione, aggiungi
un passaggio di attesa (vedi wait
class)
prima di eventuali passaggi di elaborazione successivi.