Interview Prep/Architecture & System Design

Advanced14 min read

Hadoop to Cloud Migration: The Full Story

How to plan, sequence and defend a large on-prem Hadoop to GCP migration — service mapping, migration patterns, validation strategy, and the questions asked about risk and rollback.

If migration is on your résumé, expect 20 minutes on it. Interviewers want the *decision-making*: how you sequenced it, how you proved correctness, and what you would do differently.

Why organisations migrate

  • Coupled storage and compute — scaling one forces you to scale (and pay for) the other
  • Operational burden — cluster upgrades, YARN queue tuning, hardware refresh cycles
  • Elasticity — on-prem is sized for peak and idle the rest of the time
  • Capability gap — managed streaming, ML and BI integration are far ahead in cloud
  • Say the business reason, not just the technical one: faster reporting cycles and lower TCO are what funded the project

The service mapping

On-prem HadoopGoogle CloudHDFSCloud Storage (GCS)Hive / ImpalaBigQueryMapReduce / SparkDataproc or DataflowOozieCloud Composer / DagsterFlume / custom ingestPub/Sub + DataflowYARN capacity queuesBigQuery slot reservations
Component-by-component mapping. Note that the target is not always the obvious like-for-like.

The four migration patterns

PatternMeaningTrade-off
Rehost (lift & shift)Spark/Hive jobs run on Dataproc almost unchangedFastest and lowest risk, but you inherit all the old inefficiency and keep paying for clusters
ReplatformSame logic, cloud-native runtime — Hive SQL rewritten as BigQuery SQLModerate effort, large operational and cost payoff. The usual sweet spot
RefactorRedesign the pipeline and model properlyHighest effort and highest value; reserve for the pipelines that matter most
RetireDelete itTypically 20–30% of legacy jobs have no living consumer — the cheapest win available

Tip — The sequencing answer interviewers want

'I did not migrate in one big bang. I inventoried every job with its consumers and cost, retired what nobody used, rehosted the complex Spark jobs onto Dataproc to de-risk the cutover, and replatformed the SQL-shaped workloads directly into BigQuery — where the real cost and latency wins were. Highest-value, lowest-risk domains went first to build trust.'

The phases

  1. Discovery — inventory every table, job, dependency and consumer. Most teams discover they cannot fully explain their own estate; lineage tooling pays for itself here
  2. Prioritise — score by business value, technical risk and cost. Pick a first domain that is meaningful but survivable
  3. Foundation — landing zone, IAM model, network, cost controls, CI/CD, orchestration, monitoring. Build this before pipeline work
  4. Migrate by domain — one domain end to end, including its consumers and dashboards
  5. Run in parallel — old and new produce output simultaneously; reconcile daily
  6. Cut over — switch consumers, keep the old path warm as rollback
  7. Decommission — only after a defined quiet period with no regressions

Validation: how you prove it is correct

-- Parallel-run reconciliation: compare legacy vs cloud output daily
with legacy as (
  select event_date, cell_site_id,
         sum(total_gb) as gb, sum(dropped_calls) as drops
  from legacy_export.network_kpi_daily
  where event_date = @run_date
  group by 1, 2
),
cloud as (
  select event_date, cell_site_id,
         sum(total_gb) as gb, sum(dropped_calls) as drops
  from core.fct_network_kpi_daily
  where event_date = @run_date
  group by 1, 2
)
select
  coalesce(l.cell_site_id, c.cell_site_id) as cell_site_id,
  l.gb    as legacy_gb,
  c.gb    as cloud_gb,
  abs(coalesce(l.gb, 0) - coalesce(c.gb, 0)) as gb_diff,
  case
    when l.cell_site_id is null then 'MISSING_IN_LEGACY'
    when c.cell_site_id is null then 'MISSING_IN_CLOUD'
    when abs(l.gb - c.gb) > 0.01 then 'VALUE_MISMATCH'
    else 'OK'
  end as status
from legacy l
full outer join cloud c
  on l.event_date = c.event_date
 and l.cell_site_id = c.cell_site_id
where l.cell_site_id is null
   or c.cell_site_id is null
   or abs(l.gb - c.gb) > 0.01;
  • Row counts per partition — the coarse first check
  • Aggregate reconciliation on key business metrics, as above
  • Row-level hashing for critical tables when aggregates are not enough
  • Consumer sign-off — the report owner confirms their numbers match before cutover
  • Automate this as a daily job during the parallel run, not a one-off manual check

Practice questions

QHow did you decide what to migrate first?show

Score the inventory on value, risk and cost, then pick a first domain that proves the pattern without betting the company on it.

  • Retire first — anything with no consumer in the last 90 days; free win and shrinks scope
  • First real domain — high enough value that success is visible, contained enough that failure is survivable, and representative enough that the pattern generalises
  • Defer the pipelines with the most tangled upstream dependencies until the platform foundation is proven
  • Deliberately avoid starting with the single most business-critical system — you want your platform mistakes to happen somewhere recoverable

Likely follow-up: What did you get wrong in the first domain, and what changed after it?

QHow do you migrate historical data without disrupting production?show

Move history in bulk and current data incrementally, then converge — never freeze the source system.

  • Bulk history — export to GCS (Transfer Service / distcp), load into BigQuery partition by partition, chunked and resumable
  • Current data — dual-write or run the new ingestion path in parallel from a known point in time
  • Converge — backfill the gap between the bulk snapshot and the streaming start point, then reconcile
  • Never freeze the source — the business will not accept a maintenance window measured in days
  • Validate each historical chunk as it lands rather than at the very end
QWhat was hardest about the migration — and it should not be the technology.show

The honest senior answer is usually organisational: undocumented logic, unknown consumers, and getting people to trust the new numbers.

  • Undocumented business logic buried in decade-old Hive scripts, with the authors long gone
  • Unknown consumers — someone always has a spreadsheet or a script pointed at a table you thought was dead
  • Trust — even with matching numbers, stakeholders need a parallel-run period before they believe the new platform
  • Skills — the team had to learn cloud-native patterns while still running the legacy platform; this is a real capacity cost that must be planned for
  • Mitigation: lineage tooling, a rigorous parallel run, and heavy investment in communication and enablement
QHow did you control cost after moving to a pay-per-use platform?show

On-prem cost is fixed and invisible; cloud cost is variable and attributable. Put guardrails in from day one rather than reacting to the first big bill.

  • Partition + cluster everything, and enable require_partition_filter on large tables
  • Labels on datasets and jobs so cost is attributable per team and domain
  • Budget alerts and per-query byte monitoring; review the top 20 queries weekly at first
  • Slot reservations for predictable production workloads, on-demand for exploratory use
  • Lifecycle rules on GCS and partition expiration on staging datasets
  • Cost checks in CI — a dry-run byte estimate on changed models catches expensive queries before merge