Prepare and test your skills

Prepare and test your skills

Implementing pipeline logic in Apache Beam and Cloud Dataflow means building unified batch and streaming pipelines where custom transforms, side inputs, and event-time controls handle late-arriving data. Cloud Dataflow (opens in a new tab) is the fully managed Google Cloud service that runs those pipelines at scale, while Apache Beam (opens in a new tab) is the open-source programming model that defines them. The same Beam code can process bounded historical data and unbounded real-time data, so a solution can grow from batch movement to streaming analytics without rewriting logic.
Apache Beam is the portable framework for defining batch and streaming transforms with equal reliability and expressiveness. Beam supports Java, Python, and Go SDKs, multi-language pipelines, and a portability framework for interoperability between SDKs and runners. A pipeline written for Dataflow can later run on Apache Flink or Apache Spark without rewriting code, and highly parallel workloads can embed external binaries such as existing C++ libraries inside the Beam directed acyclic graph (DAG). This design lets teams reuse specialized compute code while keeping pre-processing, task processing, and post-processing in one managed pipeline.
Cloud Dataflow executes Beam pipelines on a pool of Compute Engine worker virtual machines (VMs) that Google provisions and manages. When a job runs, the service allocates workers to run the pipeline in parallel across many VMs, and when the job completes or is cancelled it automatically deletes the VMs. Billing is based on compute resources used, so teams focus on pipeline code instead of managing clusters. Dataflow distributes batch and streaming work, manages autoscaling and dynamic work rebalancing, and provides fault tolerance with geographic redundancy, straggler detection and correction, centralized logging, and built-in exactly-once processing.
Exam tip: Dataflow provides exactly-once processing by default, while at-least-once mode is an option for streaming pipelines that can tolerate duplicates to reduce cost and improve latency.
Transform and enrichment logic in Dataflow is the code that converts raw inputs into the shape, encoding, and business meaning required downstream. Ingested data flows from sources into Beam transforms for cleaning, joining, aggregation, and analysis, then processed results flow to sinks such as BigQuery or Cloud Storage. Because Dataflow parallelizes transforms across workers, high-concurrency reads followed by large fan-out can be absorbed without managing distribution manually. Performance depends on data format, data location, and calls to external services, where splittable formats such as Avro are usually faster than CSV files with embedded newlines or unsplittable compressed files.
Calling external services from a transform adds per-call overhead, so pipelines should batch multiple elements into single requests where possible. Native Beam I/O transforms such as BigQueryIO already perform this batching for streaming inserts. If downstream systems cannot keep up, too much parallel traffic can overwhelm an external service or exhaust its quotas, and autoscaling can increase pressure by adding workers to a slow external-call step.
Windowing and session-analysis primitives in Apache Beam are the constructs that group unbounded streaming records into finite sets for aggregation. The Beam model applies the same windowing concepts to batch and streaming, so fluctuating volumes of real-time data can be ingested, processed, and analyzed with low latency. Streaming pipelines group records by event characteristics such as time windows or sessions before transforms compute results, and triggers with accumulation modes control when results are emitted and how late-arriving data updates them. Dataflow applies these windowed computations in parallel and rebalances work as volume changes, while the monitoring interface shows each stage with progress and execution details.
Sources and sinks define where pipeline data originates and where results land, and Dataflow works best with managed sources and sinks that scale with the pipeline. Pub/Sub (opens in a new tab) provides scalable and durable event ingestion for streaming pipelines, while BigQuery serves as a warehouse sink for ETL, dashboards, and analytics. Dataflow jobs depend on sufficient Compute Engine quota, since insufficient quota can prevent jobs from starting or hinder autoscaling. Pub/Sub quotas are project-based, so publishers and subscribers in different projects receive independent throughput quotas.
Multiple pipelines can read from one Pub/Sub topic by using separate subscriptions, so each Dataflow pipeline pulls and acknowledges messages independently. Deploying each pipeline in its own project with its own service account lets each pipeline use its full project quota instead of sharing one quota. This subscription pattern supports several operational designs:
Highly parallel pipelines, also called embarrassingly parallel workloads, distribute independent tasks across many cores in a grid-computing pattern common in finance, media, and life sciences. Highly parallel workloads (opens in a new tab) keep I/O, analysis, and task output in the same Beam DAG with observability, centralized logging, and exactly-once processing. An end-to-end workload typically follows an ordered flow:
Security and locality controls surround this flow. Dataflow supports customer-managed encryption keys (CMEK), firewall rules for the job network, and deployment into a Virtual Private Cloud (VPC) network. Regional controls (opens in a new tab) determine where workers run and where metadata is stored through the regional endpoint, worker region, and worker zone, while sources, sinks, and temporary files must stay in the permitted region to avoid cross-region movement.
Pipeline development in Dataflow supports code-first, template-based, and interactive approaches. Developers can write code with the Beam SDKs, deploy a Dataflow template that runs a predefined pipeline, or use JupyterLab notebooks to develop and run pipelines iteratively. Google provides a library of templates for common scenarios that can run without Beam programming knowledge, so a developer can create a template once and others can deploy it on demand. Jobs can be submitted through the command-line interface, Java SDK, or Python SDK for execution on the Dataflow runner, with Cloud Storage, Bigtable, BigQuery, and Pub/Sub acting as inputs, outputs, and coordination points.
Cloud Data Fusion, built on the open-source CDAP project, is a fully managed data-integration service for building pipelines through a graphical interface. Data Fusion and Dataflow both support batch and streaming transformations at scale, but they differ in how logic is built and executed:
| Service | Development interface | Execution engine |
|---|---|---|
| Cloud Data Fusion | Graphical UI that connects sources, transformations, sinks, and other nodes into a DAG, with prebuilt plugins for sources, transforms, aggregates, sinks, error collectors, alert publishers, and actions | Planner transforms the DAG into parallel computations run as an Apache Spark job on Managed Service for Apache Spark |
| Cloud Dataflow | Code with Beam Java, Python, or Go SDKs, command-line submission, templates, or notebooks | Serverless Dataflow runner executes Beam jobs with automatic scaling, rebalancing, and fault tolerance |
Choose Cloud Data Fusion when integration can be assembled without code, including reading from a source database with Java Database Connectivity (JDBC) drivers and loading into BigQuery after uploading and configuring the driver. Choose Dataflow when the pipeline needs custom Beam logic for advanced transformation, enrichment, and highly parallel computation at scale.
Developing advanced analytical and SQL logic in BigQuery (opens in a new tab) means expressing large-scale transformations as declarative SQL that runs natively in a serverless warehouse. Declarative logic includes analytical window functions for calculations across rows, stored procedures for multi-step control flow, and SQL or JavaScript user-defined functions (UDFs) for reusable logic. BigQuery compiles queries into parallel stages, moves intermediate data through a distributed shuffle, and returns results from persistent storage, so terabyte to petabyte-scale datasets can be processed without managing clusters.
Declarative query entry points in BigQuery are the interfaces that submit SQL for execution and return results. Queries can be composed and run in the Google Cloud console, run with the bq query command in the bq command-line tool, submitted programmatically through the jobs.query or jobs.insert methods in the BigQuery REST API, or submitted through the BigQuery client libraries. Real-time analytical results can be written to a BigQuery table or exported to downstream systems such as Bigtable or Pub/Sub for time-sensitive actions, real-time machine learning inference, and event-driven pipelines. Because all entry points submit to the same execution service, the same SQL behaves consistently whether run interactively or as part of an automated pipeline.
BigQuery Studio is the development environment for discovering, analyzing, and running inference on data in BigQuery. BigQuery Studio combines interactive and programmatic assets so teams can iterate on logic and then operationalize it:
Saved queries provide reusable analytical logic that can be private and visible only to the creator, shared at the project level and visible to specific principals, or public and viewable by anyone.
Multi-statement queries in BigQuery are sequences of SQL statements that run in order with shared state. Multi-statement queries are often used in stored procedures and support procedural language statements, which let logic define variables and implement control flow across statements. This structure turns declarative SELECT, transformation, and aggregation steps into one procedural unit where later statements depend on variables and results produced by earlier statements. Choose multi-statement queries and stored procedures when analytical logic needs shared state, branching, or repeated execution rather than a single standalone query.
How BigQuery executes analytical SQL is an ordered lifecycle that converts declarative text into parallel work and then into durable results. The lifecycle moves data from query text through parallel workers and intermediate storage before results flow back to the user:
The shuffle tier sits between producer stages and consumer stages, so a consumer stage depends on intermediate data materialized by the prior stage. Dynamic planning depends on runtime stage results, which means the final distribution of work is decided during execution rather than fixed at submission time.
Query concurrency and optimization in BigQuery control how repeated analytical logic performs on shared data under load. BigQuery runs many queries in parallel and can queue queries to run when resources are available, then redistributes resources fairly between new and running queries as queries start and finish. This fair redistribution means performance depends on the number of queries running at a given time rather than submission order, which smooths variance from shared capacity, cached results, and dynamic plan changes. Optimization depends on inspecting the query plan and execution details through the Google Cloud console, INFORMATION_SCHEMA.JOBS views, or the jobs.get REST API method.
If a stage writes much more output than other stages, that pattern signals that filtering should move earlier in the query to reduce data flowing through the shuffle tier. Monitoring and logging extend the same views and audit logs to high-volume and mission-critical workloads, where metrics, metadata views, and audit logs are used to analyze query behavior.
Exam tip: A BigQuery multi-region location does not provide cross-region replication or regional redundancy; data is stored in a single region within the geographic location.
Pricing models and cost controls in BigQuery determine how large-scale analytical logic consumes query-processing capacity. The two models split by how capacity is purchased and billed:
| Model | Capacity basis | Cost basis |
|---|---|---|
| On-demand pricing | Fixed query-processing capacity per project | Pay for data scanned by queries |
| Capacity-based pricing | Purchased dedicated query-processing capacity through reservations | Pay for reserved capacity |
BigQuery enforces project-level quotas on running queries, and cost is further controlled with custom quotas and billing alerts. This creates a direct tradeoff where on-demand cost follows bytes scanned, so reducing scanned data and filtering early lowers cost, while capacity-based cost follows reserved slots, so smoothing concurrency and avoiding queued work improves throughput within the reservation.
Optimizing distributed processing jobs on Cloud Dataproc means running Apache Spark extract-transform-load (ETL) work as parallel, short-lived computations and storing results for efficient analytics. Managed Service for Apache Spark (opens in a new tab) is the serverless Spark runtime where that computation runs, and the cluster exists only while the processing stage runs. The job transforms ingested files into business metrics, then output flows from the Spark job to a data lake in Cloud Storage with metadata in a Hive metastore. Optimization techniques such as caching intermediate data, using broadcast joins for small tables, and repartitioning to resolve data skew maximize cluster efficiency.
Managed Service for Apache Spark is the serverless Spark runtime where distributed ETL computations run during batch processing. Clusters on this service are ephemeral, which means each cluster only exists while the processing stage runs and is deleted when the job ends. Because the cluster is temporary, processing capacity does not sit idle between batches, and recovery after a failure focuses on recovering the data rather than the cluster itself. This model fits batch jobs that can be restarted on a new cluster when needed.
Exam tip: Managed Service for Apache Spark clusters are ephemeral — they exist only while the processing stage runs and are deleted at the end of the job, so batch jobs can be restarted on a new cluster.
Managed Airflow is the orchestration service that controls when an ephemeral Spark cluster starts, what job it runs, and when it is removed. Managed Airflow stores its directed acyclic graph (DAG) files in a Cloud Storage bucket, and the DAG defines the dependency order for validation, cluster creation, job execution, and cleanup. Data flows from the Cloud Storage ingestion bucket to the Spark job only after validation succeeds, and the cluster depends on Managed Airflow for its full lifecycle. The batch orchestration follows an ordered workflow:
This order ensures compute is provisioned only after input data is confirmed present and is released immediately after results are written.
Cloud Data Fusion is a fully managed data-integration service for building batch and streaming pipelines through a graphical interface. A developer connects sources to transformations, sinks, and other nodes in the Cloud Data Fusion UI to form a DAG. When the pipeline is deployed, the Cloud Data Fusion planner transforms this DAG into a series of parallel computations which are then executed as an Apache Spark job on Managed Service for Apache Spark. This path lets teams express parallel logic visually while still using the same ephemeral Spark execution and scaling behavior as code-based jobs.
The data lake phase is the storage stage that receives processed data from the Apache Spark job for analytical workloads. Processed data is commonly stored in Cloud Storage in columnar formats such as Parquet and ORC because these formats allow efficient storage and faster access for analytical workloads. Metadata about the processed data, such as databases, tables, columns, and partitions, flows from the processing stage to the Hive metastore service supplied by Dataproc Metastore, so queries can discover the structure of files stored in Cloud Storage. Keeping the optimized files in Cloud Storage and the structural metadata in Dataproc Metastore separates scalable storage from queryable catalog information.
Processing logic spans three complementary patterns where Dataflow handles custom Beam streaming and batch transforms, BigQuery handles declarative SQL analytics at warehouse scale, and Managed Service for Apache Spark handles ephemeral distributed ETL. Dataflow depends on managed sources such as Pub/Sub and sinks such as BigQuery for elasticity, BigQuery depends on its shuffle tier and dynamic planning for parallelism, and Spark on Managed Service for Apache Spark depends on Managed Airflow for lifecycle control. Choosing among them follows the interface and state needed: Beam code for fine-grained event-time logic, SQL procedures and functions for in-warehouse analytics, and Spark jobs or visual Data Fusion pipelines for short-lived cluster computation.
Apache Beam is the portable open-source programming model that defines unified batch and streaming transforms, while Cloud Dataflow is the fully managed Google Cloud service that executes those pipelines at scale. The same Beam code can process bounded historical data and unbounded real-time data, and Dataflow runs it on managed Compute Engine worker virtual machines with autoscaling, dynamic work rebalancing, and exactly-once processing by default.
Choose Cloud Data Fusion when integration can be assembled without code through a graphical interface that connects sources, transformations, and sinks into a directed acyclic graph (DAG). Choose Cloud Dataflow when the pipeline needs custom Beam logic for advanced transformation, enrichment, and highly parallel computation at scale.
Multiple Cloud Dataflow pipelines can read from one Pub/Sub topic by using separate subscriptions so each pipeline pulls and acknowledges messages independently. Deploying each pipeline in its own project with its own service account lets each pipeline use its full project quota, and unacknowledged messages can be buffered in a subscription for up to 7 days when pipelines stop.
A data engineering team runs a PySpark batch transformation pipeline on an existing Google Cloud Dataproc cluster. The job reads several terabytes of raw logs stored in Google Cloud Storage and joins this massive dataset with a 15 MB dimension table containing account metadata.
During job execution, the team observes two major performance bottlenecks:
How should the team optimize this pipeline for a specific job submission without altering cluster-wide settings?
Submit the job with --properties=spark.hadoop.fs.gs.client.type=HTTP_CLIENT, and persist both the raw logs and dimension table in memory using cache().
Submit the job with --properties=core:fs.gs.client.type=STORAGE_CLIENT to enable gRPC, and invoke repartition() on the dimension table before joining.
Submit the job with --properties=spark.sql.sources.gcs.grpc.enabled=true, and set spark.sql.autoBroadcastJoinThreshold=-1 to force bucketed sort-merge joins.
Submit the job with --properties=spark.hadoop.fs.gs.client.type=STORAGE_CLIENT to enable gRPC for Cloud Storage reads, and apply a broadcast join (broadcast()) on the dimension table in the PySpark logic.
Last updated