Nelle pipeline di streaming distribuite, può essere difficile identificare quale fase specifica, chiamata di servizio esterno o shuffle dei worker causa picchi di latenza utilizzando solo le metriche aggregate. Utilizzando la tracciabilità distribuita di OpenTelemetry in Dataflow, puoi monitorare i singoli elementi end-to-end tra le trasformazioni della pipeline, i confini di rete e i servizi integrati con un unico ID traccia. Questa visibilità ti aiuta a individuare i colli di bottiglia delle prestazioni, ottimizzare i costi di esecuzione della pipeline e risolvere i problemi relativi ai complessi carichi di lavoro di streaming.
Utilizza le seguenti informazioni per attivare, configurare e utilizzare la tracciabilità distribuita OpenTelemetry nelle pipeline Apache Beam.
Casi d'uso
Il tracciamento distribuito in Dataflow è particolarmente utile nei seguenti scenari:
- Carichi di lavoro di streaming:monitora il tempo di elaborazione per elemento e identifica le fasi che introducono picchi di ritardo o latenza.
- Tracciamento delle chiamate di servizi esterni nel codice utente:misura le durate di esecuzione
quando la pipeline chiama database esterni, microservizi o API di AI generativa
all'interno del codice utente (ad esempio in un
DoFn). Ad esempio, puoi misurare il tempo per le chiamate a database esterni (come Spanner o Bigtable), microservizi (utilizzando HTTP o gRPC) o API di AI generativa (come Gemini). Per saperne di più, consulta Scrivere tracce personalizzate in DoFn e Eseguire l'integrazione con le librerie client. - Ottimizzazione di costi e prestazioni:mostra le durate di operazioni specifiche nelle istanze
PTransformcon carico reale per identificare serializzazione inefficiente, query lente o contesa dei thread di lavoro. - Pipeline complesse di agenti e workflow: ottieni visibilità sulle pipeline con più rami, cicli iterativi di agenti e unioni per determinare quale trasformazione o ramo richiede più tempo.
Limitazioni
Il tracciamento distribuito in Dataflow presenta le seguenti limitazioni:
- Questa funzionalità è progettata e verificata solo per le pipeline di streaming.
- Per utilizzare questa funzionalità, devi utilizzare l'SDK Beam per Java (versione 2.76.0 o successive).
- La propagazione del contesto tra le fasi richiede Streaming Java Runner (precedentemente chiamato Runner v1). Portable Runner (precedentemente chiamato Runner v2) reimposta il contesto della traccia ai limiti di rimescolamento.
- La tracciabilità OpenTelemetry integrata nei connettori Beam I/O è supportata solo per i seguenti connettori: Pub/Sub, Apache Kafka e flussi di modifiche in tempo reale Spanner. Per Apache Kafka,
il tracing è supportato solo quando utilizzi direttamente il connettore
KafkaIO. Non è supportato quando utilizzi Managed I/O per Kafka. Altri connettori I/O (ad esempioBigtableIO) non hanno la tracciabilità integrata dei connettori. Per tracciare le operazioni con questi servizi, strumenta le chiamate all'interno del codice utente (ad esempio in unDoFn). - Le operazioni che combinano più elementi in uno non propagano un singolo
contesto di traccia. Sono incluse operazioni come
GroupByKey,CoGroupByKeyeCombine. - Il contesto non viene propagato tra l'impostazione di un timer (
Timer.set()) e l'esecuzione del metodo di callback@OnTimer.
Prerequisiti
Per utilizzare la tracciabilità distribuita in Dataflow, assicurati che il tuo ambiente soddisfi i seguenti requisiti:
- Il tuo lavoro deve soddisfare i seguenti requisiti:
- È una pipeline di streaming
- Utilizza Streaming Java Runner (precedentemente chiamato Runner v1)
- Utilizza la versione 2.76.0 o successive dell'SDK Apache Beam Java
Se esporti le tracce in Cloud Trace, abilita l'API Telemetry (
telemetry.googleapis.com) nel tuo progetto Google Cloud .Ruoli richiesti per abilitare le API
Per abilitare le API, devi disporre dell'autorizzazione
serviceusage.services.enable. Se hai creato il progetto, probabilmente disponi già di questa autorizzazione tramite il ruolo Proprietario (roles/owner). In caso contrario, puoi ottenere questa autorizzazione tramite il ruolo Amministratore utilizzo servizi (roles/serviceusage.serviceUsageAdmin). Scopri come concedere i ruoli.Il service account worker deve disporre del ruolo Agente Cloud Trace (
roles/cloudtrace.agent), che include l'autorizzazionecloudtrace.traces.patch.
Concetti principali
Il tracciamento distribuito si basa sui seguenti concetti di OpenTelemetry:
- Traccia
- Una rappresentazione di una transazione o di un flusso di lavoro completo mentre scorre attraverso un sistema distribuito. Una traccia è composta da uno o più span.
- Intervallo
- Il componente di base di una traccia, che rappresenta una singola unità di lavoro. Ad esempio, l'esecuzione di una trasformazione, una chiamata al metodo o una richiesta RPC.
- Contesto
- Lo stato propagato tra i thread e i limiti delle API. Sono inclusi l'ID traccia e l'ID intervallo.
- Propagatore
- Il meccanismo utilizzato per inserire ed estrarre la rappresentazione del contesto attraverso i confini della rete. Ad esempio, il contesto della traccia W3C.
- Esportatore
- Un componente che invia i dati span raccolti a un backend di tracciamento, ad esempio Cloud Trace o un agente di raccolta OpenTelemetry autogestito.
- Sampler
- Un meccanismo che controlla il volume delle tracce determinando quali tracce vengono registrate ed esportate. Ad esempio, un tasso di campionamento dell'1%.
Abilita il tracciamento OpenTelemetry
Per abilitare il tracciamento OpenTelemetry con le impostazioni predefinite, configura le opzioni della pipeline e gli esperimenti richiesti quando invii il job. L'impostazione predefinita esporta in Cloud Trace con un campionamento dell'1%.
Per modificare i valori predefiniti, consulta Impostare e modificare le proprietà di tracciamento.
Configura le opzioni della pipeline e gli esperimenti quando esegui il job.
Job di template non flessibile
Trasmetti i seguenti flag di esperimento quando invii un job:
--experiments=enable_otel_defaults,element_metadata_supported,disable_portable_worker
Job con modello flessibile
Passa gli esperimenti utilizzando il flag
--additional-experimentsnel comandogcloud:gcloud dataflow flex-template run JOB_NAME \ --template-file-gcs-location=gs://BUCKET_NAME/templates/TEMPLATE_NAME.json \ --additional-experiments="enable_otel_defaults,element_metadata_supported,disable_portable_worker" \ --region=REGIONSostituisci quanto segue:
- JOB_NAME: il nome del job Dataflow.
- BUCKET_NAME: Il bucket Cloud Storage contenente il modello.
- TEMPLATE_NAME: il nome del file Flex Template.
- REGION: la regione Google Cloud in cui vuoi eseguire il job.
Questi esperimenti configurano i seguenti comportamenti:
enable_otel_defaults: configura i valori predefiniti standard di OpenTelemetry, inclusi l'esportatore Cloud Trace e il campionamento all'1%.element_metadata_supported: consente la serializzazione e la propagazione dei metadati (come il contesto della traccia) nelle fasi della pipeline.disable_portable_worker: forza l'utilizzo di Dataflow Streaming Java Runner (precedentemente chiamato Runner v1).
Se utilizzi le versioni 2.76.0 o 2.77.0 dell'SDK Beam per Java, aggiungi le dipendenze OpenTelemetry richieste alla configurazione di compilazione.
A causa di un problema nelle versioni 2.76.0 e 2.77.0, devi aggiungere le seguenti dipendenze al file
pom.xmlper esportare le tracce. Per saperne di più, consulta Gestire le dipendenze della pipeline.<dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-exporter-otlp</artifactId> <version>1.62.0</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.beam</groupId> <artifactId>beam-sdks-java-extensions-opentelemetry-gcp-auth-extension</artifactId> <scope>compile</scope> </dependency>Attiva esplicitamente la tracciabilità OpenTelemetry sui connettori I/O supportati nel codice della pipeline:
Pub/Sub
Per abilitare la tracciabilità durante la lettura o la scrittura in Pub/Sub:
// Reading from Pub/Sub pipeline.apply("ReadFromPubSub", PubsubIO.readMessages() .withEnableOpenTelemetryTracing() .fromSubscription("projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID")); // Writing to Pub/Sub pipeline.apply("WriteToPubSub", PubsubIO.writeStrings() .withEnableOpenTelemetryTracing() .to("projects/PROJECT_ID/topics/TOPIC_ID"));
Sostituisci quanto segue:
- PROJECT_ID: l'ID del tuo Google Cloud progetto.
- SUBSCRIPTION_ID: il nome della sottoscrizione Pub/Sub.
- TOPIC_ID: il nome dell'argomento Pub/Sub.
Dettagli della propagazione del contesto:
- Publisher upstream:quando pubblichi messaggi da un'applicazione esterna, inserisci il contesto di traccia W3C negli attributi del messaggio Pub/Sub. Per ulteriori informazioni, consulta Pub/Sub OpenTelemetry tracing.
- Attributi:Beam prevede e compila i seguenti attributi:
googclient_traceparent: contiene l'intestazionetraceparentdi W3C.googclient_tracestate: contiene l'intestazione W3Ctracestate.
- Per la formattazione dell'intestazione, consulta le specifiche del contesto di traccia W3C.
Apache Kafka
Per abilitare la tracciabilità durante la lettura o la scrittura in Apache Kafka:
// Reading from Kafka pipeline.apply("ReadFromKafka", KafkaIO.<String, String>read() .withEnableOpenTelemetryTracing() // ... additional configuration ); // Writing to Kafka pipeline.apply("WriteToKafka", KafkaIO.<String, String>write() .withEnableOpenTelemetryTracing() // ... additional configuration );
Dettagli della propagazione del contesto:
KafkaIOutilizza le intestazioni dei record Kafka standard per propagare il contesto.- Inserisce le intestazioni conformi alla
specifica W3C Trace Context:
traceparent: identifica il contesto della traccia in entrata.tracestate: Fornisce metadati di routing e filtraggio specifici del fornitore aggiuntivi.
Spanner
Per abilitare la tracciabilità durante la lettura dai flussi di modifiche in tempo reale di Spanner:
pipeline.apply("ReadChangeStream", SpannerIO.readChangeStream() .withSpannerConfig(spannerConfig) .withEnableOpenTelemetryTracing(true) .withChangeStreamName("CHANGE_STREAM_NAME"));
Sostituisci quanto segue:
- CHANGE_STREAM_NAME: il nome della modifica in tempo reale Spanner.
Dettagli sulla creazione dell'intervallo:
- L'attivazione della tracciabilità avvia una nuova traccia e uno nuovo span per ogni record di mutazione del database letto dal lettore Change Data Capture (CDC).
- I cicli di polling del lettore Spanner che non restituiscono nuovi record potrebbero anche produrre intervalli di traccia che possono essere filtrati nell'interfaccia utente di Cloud Trace.
Impostare e modificare le proprietà di tracciamento
Quando specifichi enable_otel_defaults, Dataflow applica le seguenti proprietà predefinite:
| Proprietà | Valore predefinito | Descrizione |
|---|---|---|
otel.traces.exporter |
otlp |
Esporta le tracce utilizzando OpenTelemetry Protocol (OTLP). |
otel.exporter.otlp.endpoint |
https://telemetry.googleapis.com |
Ha come target il ricevitore OTLP di Cloud Trace. |
google.cloud.project |
Il tuo ID progetto | Il progetto Google Cloud in cui sono archiviate le tracce. |
otel.traces.sampler.arg |
0.01 (1%) |
Registra 1 traccia ogni 100. |
otel.service.name |
options.getAppName() |
Il nome del servizio associato agli intervalli, derivato dall'opzione appName della pipeline. |
Per personalizzare la configurazione di OpenTelemetry, trasmetti un elenco di proprietà separate da punto e virgola all'opzione della pipeline --openTelemetryProperties.
L'esempio seguente configura esplicitamente tutte le proprietà predefinite:
--openTelemetryProperties="otel.traces.exporter=otlp;otel.exporter.otlp.endpoint=https://telemetry.googleapis.com;google.cloud.project=PROJECT_ID;otel.traces.sampler.arg=0.01;otel.service.name=CUSTOM_SERVICE_NAME;otel.java.global-autoconfigure.enabled=true"
Impostare un nome servizio personalizzato
Per impostazione predefinita, il nome del servizio di traccia viene derivato dall'opzione appName della pipeline
(--appName=YourPipelineName). Puoi sostituire questo valore impostando la proprietà otel.service.name:
--openTelemetryProperties="otel.service.name=CUSTOM_SERVICE_NAME"
Modificare la frequenza di campionamento e le proprietà
L'impostazione di una frequenza di campionamento più elevata fornisce informazioni di tracciamento più affidabili.
Tuttavia, frequenze di campionamento elevate (ad esempio 1.0 o
always_on) aumentano notevolmente il volume di dati di traccia inviati a
Cloud Trace, il che può aumentare i costi di Google Cloud . Utilizza frequenze di campionamento elevate solo per il debug a breve termine e riducile per i carichi di lavoro di produzione.
L'esempio seguente configura esplicitamente la frequenza di campionamento. In questo caso devi fornire un elenco completo di argomenti:
--openTelemetryProperties="otel.traces.exporter=otlp;otel.exporter.otlp.endpoint=https://telemetry.googleapis.com;google.cloud.project=PROJECT_ID;otel.traces.sampler.arg=0.02;otel.service.name=CUSTOM_SERVICE_NAME;otel.java.global-autoconfigure.enabled=true"
Esportare nei backend di terze parti
Per inviare tracce a un backend di tracciamento gestito esterno o a un raccoglitore OpenTelemetry autogestito anziché a Cloud Trace:
- Ometti il seguente esperimento:
--experiments=enable_otel_defaults. Configura manualmente le proprietà dell'esportatore utilizzando
--openTelemetryProperties:--openTelemetryProperties="otel.traces.exporter=otlp;otel.exporter.otlp.endpoint=http://COLLECTOR_HOST:4317;otel.traces.sampler=parentbased_always_on"
Estensione di autenticazioneGoogle Cloud
Il runtime Beam include un'estensione di Google Cloud autenticazione
che autentica automaticamente le richieste OpenTelemetry Protocol (OTLP)
inviate alle API di Google come telemetry.googleapis.com.
- Quando utilizzi le impostazioni predefinite, l'autenticazione Google Cloud viene attivata automaticamente.
- Quando esporti in endpoint non Google:se
enable_otel_defaultsviene omesso, Beam disattiva l'estensione di Google Cloud autenticazione impostando la proprietà di sistemagoogle.otel.auth.target.signals=none. - Configurazione manuale:puoi impostare la proprietà di sistema
google.otel.auth.target.signalssunone(disattivata) otrace(attivata solo per le tracce).
Scrivere tracce personalizzate in DoFn
Puoi creare intervalli personalizzati all'interno del codice utente, ad esempio all'interno di un DoFn, per misurare operazioni specifiche. Sono incluse chiamate ad API esterne o
logica a elevata intensità di calcolo.
Esempio di implementazione di DoFn
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;
import org.apache.beam.sdk.options.PipelineOptions;
import org.apache.beam.sdk.options.SdkHarnessOptions;
import org.apache.beam.sdk.transforms.DoFn;
public class InvestigateTransactionDoFn extends DoFn<Transaction, RiskAssessment> {
private transient Tracer tracer;
@Setup
public void setup(PipelineOptions options) {
// Obtain the Tracer instance from SdkHarnessOptions
this.tracer = options
.as(SdkHarnessOptions.class)
.getOpenTelemetry()
.getTracer("org.apache.beam.examples.adk.aml");
}
@ProcessElement
public void processElement(@Element Transaction tx, OutputReceiver<RiskAssessment> out) {
// Create and start a custom span as a child of the active context
Span span = tracer.spanBuilder("InvestigateTransactionDoFn:Analyze")
.setAttribute("transaction.id", tx.getId())
.setAttribute("transaction.amount", tx.getAmount())
.startSpan();
// Make the span current in the execution thread
try (Scope scope = span.makeCurrent()) {
// Perform your logic (such as calling an external service)
RiskAssessment assessment = analyzeTransactionWithLLM(tx);
out.output(assessment);
} catch (Exception e) {
// Record exception details and set error status on the span
span.recordException(e);
span.setStatus(StatusCode.ERROR, e.getMessage());
throw e;
} finally {
// Always end the span
span.end();
}
}
private RiskAssessment analyzeTransactionWithLLM(Transaction tx) {
// Application analysis logic
return new RiskAssessment();
}
}
Integrare con le librerie client
Quando un DoFn richiama librerie esterne che supportano anche OpenTelemetry, come le librerie client Google Cloud , configura il client in modo che utilizzi l'istanza OpenTelemetry della pipeline, in modo che gli intervalli secondari si colleghino direttamente alla traccia della pipeline.
Esempio di client Java Spanner
Per eseguire query Spanner manuali all'interno di un DoFn e collegare questi
intervalli alla traccia della pipeline attiva, inizializza SpannerOptions con l'istanza OpenTelemetry della pipeline:
import com.google.cloud.spanner.DatabaseClient;
import com.google.cloud.spanner.DatabaseId;
import com.google.cloud.spanner.ResultSet;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerOptions;
import com.google.cloud.spanner.Statement;
import org.apache.beam.sdk.options.PipelineOptions;
import org.apache.beam.sdk.options.SdkHarnessOptions;
import org.apache.beam.sdk.transforms.DoFn;
public class SpannerEnrichmentDoFn extends DoFn<String, String> {
private transient Spanner spanner;
private transient DatabaseClient dbClient;
private final String instanceId;
private final String databaseId;
public SpannerEnrichmentDoFn(String instanceId, String databaseId) {
this.instanceId = instanceId;
this.databaseId = databaseId;
}
@Setup
public void setup(PipelineOptions pipelineOptions) {
// Build SpannerOptions leveraging the pipeline's active OpenTelemetry instance
SpannerOptions options =
SpannerOptions.newBuilder()
.setOpenTelemetry(pipelineOptions
.as(SdkHarnessOptions.class)
.getOpenTelemetry())
.setEnableEndToEndTracing(true)
.setEnableExtendedTracing(true)
.build();
this.spanner = options.getService();
DatabaseId db = DatabaseId.of(options.getProjectId(), instanceId, databaseId);
this.dbClient = spanner.getDatabaseClient(db);
}
@ProcessElement
public void processElement(@Element String inputId, OutputReceiver<String> out) {
Statement statement = Statement.newBuilder(
"SELECT Details FROM AccountTable WHERE AccountId = @id")
.bind("id").to(inputId)
.build();
// Spanner queries automatically generate child spans linked to the active trace
try (ResultSet rs = dbClient.singleUse().executeQuery(statement)) {
while (rs.next()) {
out.output(rs.getString("Details"));
}
}
}
@Teardown
public void tearDown() {
if (spanner != null) {
spanner.close();
}
}
}
Propagazione del contesto tra le fasi
Nelle pipeline di dati distribuite, il trasferimento del contesto della traccia tra i limiti dei worker e le operazioni di shuffling è essenziale per la visibilità end-to-end.
Quando inserisci Redistribute.arbitrarily() nella pipeline, il contesto di traccia attivo viene serializzato nei metadati dell'elemento, trasmesso attraverso la rete e deserializzato nella VM worker ricevente. In questo modo, la traccia
continua senza interruzioni nelle varie fasi.
L'esempio seguente illustra come il contesto della traccia si propaga nelle fasi della pipeline:
- Estrai contesto:
KafkaIO.read()legge un record in entrata ed estrae il contesto della traccia dalle intestazioni del messaggio. - Elabora e crea intervalli:
DoFn Aelabora l'elemento all'interno di un intervallo di traccia attivo. - Propagate across workers:
Redistribute.arbitrarily()serializes the active trace context into the element metadata and shuffles the element across the network. - Continua la traccia:
DoFn Briceve l'elemento su una VM worker, deserializza il contesto della traccia e continua l'elaborazione con lo stesso ID traccia.
Visualizzare le tracce in Cloud Trace
Dopo aver abilitato la tracciabilità, visualizza le tracce della pipeline nella console Google Cloud :
Nella Google Cloud console, vai alla pagina Esplora tracce.
Nella casella del filtro, filtra per
Service: SERVICE_NAME. Questo SERVICE_NAME corrisponde allaappNamedella pipeline o allaotel.service.nameconfigurata.In alternativa, cerca un ID traccia specifico.
Seleziona una traccia dall'elenco dei risultati per visualizzarne la sequenza temporale dettagliata.
Il grafico della cronologia mostra:
- Runner spans:gli span generati dal runtime di Beam.
Ad esempio,
PubSubIO.ReadeProcessElement. - Span personalizzati:span creati all'interno delle implementazioni di
DoFn. Ad esempio,InvestigateTransactionDoFn:Analyze. Span delle librerie client:span secondari generati da librerie client integrate. Ad esempio, query RPC Spanner.

- Runner spans:gli span generati dal runtime di Beam.
Ad esempio,
Passaggi successivi
- Scopri di più sull'esplorazione e l'analisi delle tracce distribuite nella documentazione di Cloud Trace.
- Trace i messaggi dall'importazione all'elaborazione utilizzando Pub/Sub OpenTelemetry tracing.
- Monitora il throughput della pipeline, l'utilizzo della CPU e i dettagli di esecuzione con l'interfaccia di monitoraggio di Dataflow.
- Visualizza i log operativi e diagnostica gli errori utilizzando i log della pipeline Dataflow.
- Indaga e risolvi i problemi di prestazioni con Risolvi i problemi relativi a job lenti o bloccati e Rileva e risolvi i colli di bottiglia della pipeline.