A second cluster, and the menu that didn't arrive
The college now runs two clusters: prod on campus and a DR (disaster recovery) cluster in another building. Every night Kabir copies /prod/canteen to DR with DistCp. One morning the canteen raises the price of chai from ₹15 to ₹18. The nightly copy finishes "successfully", yet the DR menu still says ₹15. Same file name, same size (143 bytes), so plain DistCp skipped it without a word.
Sir, DistCp said it succeeded. How can DR be wrong?
Without options DistCp only asks "does a file with this name already exist there?". If yes, it skips it. It never looked inside menu.csv. With -update it compares size and checksum, and with -delete it also removes what prod deleted.
And if the campus floods tonight, DR is our only copy. Whatever wasn't synced yet is simply gone.
That loss window has a name: the RPO. Today we copy between two real clusters, fix the sync, use snapshots so a nightly sync copies only what changed, and run a failover drill to see exactly what DR would miss.
DistCp and disaster recovery
DistCp (distributed copy) is a Hadoop tool that copies large directory trees within or between clusters by running a map-only MapReduce job: the client builds a listing of source files, splits it into chunks, and each map task copies its files directly from source DataNodes to destination DataNodes, verifying checksums. Options control incremental behaviour (-update copies files whose size or checksum differ, -overwrite copies unconditionally, -delete removes target files missing from the source, -diff applies a snapshot difference), what metadata is preserved (-p), parallelism (-m) and bandwidth (-bandwidth). Disaster recovery (DR) is the set of plans, copies and procedures that let a service resume at another site after the primary site is lost. It is measured by the recovery point objective (RPO), the maximum acceptable data loss expressed as time, and the recovery time objective (RTO), the maximum acceptable time to restore service.
DistCp is cp for clusters: many map tasks copy files in parallel. DR means keeping a second copy far away and knowing how to switch to it. RPO = how much data you can lose; RTO = how long you can be down.
Words you'll meet in this lesson
Architecture at a glance
Our lab: two clusters on separate networks. DistCp's map tasks run on prod's YARN and write straight into the DR cluster's DataNodes. Snapshots on both sides make each night's sync small.
From our lab (two Hadoop 3.5.0 clusters)
| First full copy | 5 files, 169,964,453 bytes, 5 map tasks, 25.5 s |
|---|---|
| Plain re-run | Files Copied=1, Files Skipped=4: the changed menu.csv (same 143 bytes) was skipped and the deleted file stayed |
-update / -delete | Copied only menu.csv (143 bytes); then removed feedback.txt on DR |
| Snapshot diff | -update -diff s1 s2: 1 file (28,086 bytes), 1 map, 15.1 s; a rename was replayed as a rename |
| Throttle | -bandwidth 1 on 19.4 MB: 34.2 s |
| DR drill | The Lesson 8.1 report ran on DR data with identical results; a file written after the last sync was missing on DR |
DR at three levels
Beginner A spare key with a neighbour
- You keep a spare house key with a neighbour in another street. If you lose yours, you can still get in: that is DR.
- If you changed the lock last week and forgot to give the neighbour the new key, the spare is useless. A stale copy is the risk DistCp
-updateprotects against. - How old the spare may be is the RPO; how long it takes to walk over and get it is the RTO.
Intermediate How DistCp decides what to copy
- No option: if a file with the same name exists at the target, it is skipped. Our changed
menu.csvwas skipped. -update: copy if the target is missing, or if size or checksum differ.menu.csvwas copied (143 bytes).-overwrite: copy everything again, always.-delete(with-updateor-overwrite): delete target files not present at the source.-diff s1 s2: ask the NameNode what changed between two snapshots, replay renames and deletes, copy only new or modified files.
Advanced What production DR adds
- Metadata too: Hive/Impala tables need their metastore replicated (schemas, partitions), not just HDFS files.
- Checksums across settings: HDFS file checksums depend on block size and checksum type. Copy with
-pb(preserve block size) or usedfs.checksum.combine.mode=COMPOSITE_CRC;-skipcrccheckhides real corruption and is a last resort. - Across versions and clouds:
webhdfs://works between different Hadoop versions;s3a://andabfs://targets copy to cloud storage. - Drills: a DR plan that was never tested is a guess. Teams run the real jobs on DR a few times a year and measure the actual RTO.
Exam tip: For "What is DistCp and how is it used for DR?", say: a map-only MapReduce job that copies files in parallel between clusters; incremental with -update (size + checksum) and -delete; snapshot-based with -diff; and define RPO and RTO with one example.
DistCp options and DR designs
| Option | What it does | Our lab |
|---|---|---|
| (none) | Copy files whose name doesn't exist at the target | Skipped the changed menu.csv |
| -update | Copy if missing or size/checksum differ | Copied 143 bytes |
| -overwrite | Copy everything, always | (not used; would copy 162 MB) |
| -delete | Remove target files missing at source | Removed feedback.txt |
| -diff s1 s2 | Replay a snapshot diff; needs s1 on both sides | 1 file, 1 map, rename kept |
| -p[rbugpcaxt] | Preserve replication, block size, user, group, permissions, checksum type, ACLs, xattrs, times | Use -pb when block sizes differ |
| -m N / -strategy dynamic | Number of maps; dynamic lets fast maps take more chunks | One map per file here |
| -bandwidth MB | Limit each map's speed, to protect the network | 1 MB/s: 34.2 s for 19.4 MB |
| -i / -atomic | Ignore failures / copy to a temp folder then move in one step | - |
DR designs
Backup only
Copies on cheaper storage (another cluster, cloud). Protects data, but restoring and rebuilding compute takes days: long RTO.
cheapestActive–passive
A DR cluster kept in sync (nightly or hourly DistCp). Jobs move there on failover. RPO = sync interval.
most commonActive–active
Both sites ingest and serve; data is written to both or replicated continuously. Low RPO/RTO, highest cost and complexity.
critical systemsCloud as DR
DistCp to s3a:// or abfs://; spin up a cloud cluster only during a disaster.
Animated example: when Chennai floods
- 01:00: the nightly snapshot-diff DistCp copies the day's changes from Chennai to the Pune DR cluster.
- Daytime: new claims keep arriving, but only Chennai has them until the next sync.
- 19:00: a flood takes the Chennai data centre offline.
- 19:40: following the runbook, the team points jobs and users at the Pune NameNode.
- 20:30: service is back (RTO 1.5 hours), but claims written since 01:00 are lost (RPO 18 hours).
- Afterwards: hourly snapshots and diff syncs cut the possible loss to about one hour. (Illustrative scenario.)
Run DistCp from the cluster with spare YARN capacity and, when versions differ, from the newer one, reading the older cluster over webhdfs://. In our lab the maps ran on prod's workers, the only machines that could reach both clusters.
Two clusters, one nightly sync, one drill
Prod is the Module 8 cluster; DR is the federation cluster from Lesson 7.2 (hdfs://nn-canteen:8020). Commands run on a prod worker, which join_clusters.sh connects to both networks.
First full copy
A map-only job: the client listed 5 files, YARN ran 5 copy maps on prod's workers, and each map streamed blocks from prod DataNodes into DR DataNodes, then compared checksums.hadoop distcp /prod/canteen hdfs://nn-canteen:8020/dr/exit 0, took 25540 ms Bytes Copied=169964453 Files Copied=5 Launched map tasks=5A day later: plain DistCp again
Only the new file was copied. The changedhadoop distcp /prod/canteen hdfs://nn-canteen:8020/dr/Bytes Copied=70147 Files Copied=1 Files Skipped=4 143 /dr/canteen/menu.csv 5093962 /dr/canteen/feedback.txtmenu.csv(same name, same size) and the deletedfeedback.txtwere left as they were, and the job still reported success.-update, then-update -deleteWithhadoop distcp -update /prod/canteen hdfs://nn-canteen:8020/dr/canteen hadoop distcp -update -delete /prod/canteen hdfs://nn-canteen:8020/dr/canteen hdfs dfs -cat hdfs://nn-canteen:8020/dr/canteen/menu.csv | head -1Bytes Copied=143 Files Copied=1 Files Skipped=4 ... Files Skipped=5 chai,drink,18,A-update, source and target paths are the folders themselves. Size was equal, but the checksums differed, somenu.csvwas copied.-deletethen removedfeedback.txtfrom DR.Sync only a snapshot difference
DistCp asked the NameNode for the diff instead of comparing every file. The rename was applied as a rename on DR (no bytes copied) and only the new 28 KB file travelled. On millions of files this is the difference between hours of listing and minutes.hdfs dfs -createSnapshot /prod/canteen s1 # and s1 on the DR copy hdfs dfs -mv .../orders_day31.csv .../orders_2026-10-31.csv ; put orders_2026-11-01.csv hdfs dfs -createSnapshot /prod/canteen s2 hdfs snapshotDiff /prod/canteen s1 s2 hadoop distcp -update -diff s1 s2 /prod/canteen hdfs://nn-canteen:8020/dr/canteenM . + ./orders_2026-11-01.csv R ./orders_day31.csv -> ./orders_2026-10-31.csv exit 0, took 15085 ms Bytes Copied=28086 Files Copied=1 Launched map tasks=1Throttle the copy
At 1 MB/s per map, 19.4 MB needs at least 19 s of copying plus job start-up. Throttling protects the link between sites during business hours.hadoop distcp -bandwidth 1 /prod/canteen/student_orders.csv hdfs://nn-canteen:8020/dr/throttled.csvexit 0, took 34192 ms Bytes Copied=19418699Disaster drill
The Lesson 8.1 report gives identical numbers from DR data. But anything written after the last sync exists only on prod: if prod were gone now, that file would be lost. That gap is the RPO.hadoop jar mr.jar ItemRevenue hdfs://nn-canteen:8020/dr/canteen/canteen_orders.csv hdfs://nn-canteen:8020/dr/report hdfs dfs -put day32.csv /prod/canteen/orders_2026-11-02.csv # written after the last synccompleted successfully chai 50170 752550 dosa 49948 2247660 idli 49984 1499520 prod files: 7 DR files: 6 missing on DR: orders_2026-11-02.csv
Never point a scheduled sync at the wrong direction or the wrong folder with -delete: it will faithfully delete everything the source doesn't have. Test every new sync command on a scratch folder first, and keep snapshots on the target so a bad run can be undone.
Our sync, run by run
Six steps from the lab: full copy, silent skip, update, delete, snapshot diff, drill.
- The first copy moves all 5 files, 170 MB, with 5 map tasks in 25.5 s.
- Run again without options: only the new file is copied; the changed menu is skipped.
- With -update, the menu's checksum mismatch is noticed and 143 bytes are copied.
- With -delete, DR also loses the file prod deleted.
- The snapshot diff sync copies one 28 KB file and replays a rename.
- The drill runs the report on DR; one file written after the sync is missing.
- DR becomes an exact copy: each map copies one file and verifies it.
- Prod changed the menu, added a file and deleted one; plain DistCp only notices the new name.
- -update compares size and checksum; equal sizes are not enough to skip.
- -delete removes target files that no longer exist at the source.
- With snapshots, only the listed changes are applied: a rename and one new file.
- DR can run the same jobs, but always lags prod by the time since the last sync.
DistCp and DR at work
1. Bank: regulator-mandated DR
Banks must show a tested DR plan. Transaction history in HDFS is synced to a second data centre several times a day, and failover drills are run and reported every quarter.
2. Telecom: migrating to a new cluster
When a telecom moves petabytes of call records from an old Hadoop distribution to a new cluster, DistCp over webhdfs:// copies data while both run; repeated -update runs shrink the final cut-over window.
3. E-commerce: archive to the cloud
Old order data is copied to object storage (s3a:// or abfs://) with DistCp, verified, and then deleted from the on-prem cluster to free disks.
4. Analytics team: refreshing a test cluster
A masked sample of production data is copied to the development cluster every week so new jobs are tested on realistic data without touching prod.
5. Healthcare: two regions, active–active
A hospital chain ingests records in two regions and replicates each region's data to the other, so either site can serve all reports if one goes down.
Simplified; organisations differ in tools and policies.
Decide like DistCp
This model reproduces our second run. Each file has a size and a checksum. Plain DistCp only checks whether the name exists at the target; -update also compares size and checksum; -delete removes target files the source no longer has.
prod = {"canteen_orders.csv": (4692009, "c1"), "menu.csv": (143, "m2"),
"orders_day31.csv": (70147, "d1"), "orders_x30.csv": (140759640, "x1"),
"student_orders.csv": (19418699, "s1")}
dr = {"canteen_orders.csv": (4692009, "c1"), "menu.csv": (143, "m1"),
"feedback.txt": (5093962, "f1"), "orders_x30.csv": (140759640, "x1"),
"student_orders.csv": (19418699, "s1")}
def plan(src, dst, update=False, delete=False):
copy, skip = [], []
for name, (size, crc) in src.items():
if name not in dst:
copy.append(name)
elif update and dst[name] != (size, crc): # size OR checksum differs
copy.append(name)
else:
skip.append(name)
gone = [n for n in dst if n not in src] if delete else []
return copy, skip, gone
for opts in [{}, {"update": True}, {"update": True, "delete": True}]:
c, s, g = plan(prod, dr, **opts)
print(opts or "no options", "-> copy", c, "| skipped", len(s), "| delete", g)elif update and dst[name] != (size, crc): # size OR checksum differsOur menu.csv: same 143 bytes, different checksum. Only -update notices.gone = [n for n in dst if n not in src] if delete else []-delete is what removed feedback.txt from the DR copy.
Run it on your PC: two clusters, one sync, one drill
You need the Module 8 lab (prod) and the Lesson 7.2 federation lab (DR) running together; stop the Module 5 lab to save memory. join_clusters.sh connects only prod's three workers to the DR network: both clusters use names like namenode, and when we joined every container to both networks, a client resolved resourcemanager to the wrong network and got "Connection refused". Then run distcp_lab.sh inside lab8-worker1-1. It takes about 4 minutes.
Connect the clusters, then sync and drill
# ---- join_clusters.sh (run on your PC) ----
# join_clusters.sh: let the lab8 workers (where DistCp's map tasks run) reach the second cluster.
# Only the workers join: the clusters both use names like "namenode", and a container on two networks
# can answer to the wrong address. Run on your PC.
docker compose -p lab72 start # the Lesson 7.2 federation cluster = our "DR" site
for c in worker1 worker2 worker3; do docker network connect lab72_default lab8-$c-1; done
docker exec lab8-worker1-1 getent hosts namenode resourcemanager nn-canteen
docker cp lab8-namenode-1:/tmp/mr/mr.jar /tmp/mr.jar && docker cp /tmp/mr.jar lab8-worker1-1:/tmp/mr.jar
# ---- distcp_lab.sh ----
# distcp_lab.sh: copy a production folder to a second (DR) cluster, keep it in sync, then fail over.
# PROD = the Module 8 cluster (hdfs://namenode). DR = the federation cluster of Lesson 7.2 (hdfs://nn-canteen:8020).
# The lab8 workers are joined to the DR cluster's Docker network (join_clusters.sh). Run inside lab8-worker1-1.
DR=hdfs://nn-canteen:8020
P=/prod/canteen
D=$DR/dr/canteen
run() { local name=$1; shift; local s=$(date +%s%N)
hadoop distcp "$@" > /tmp/$name.log 2>&1; echo " exit $?, took $(( ($(date +%s%N) - s) / 1000 / 1000 )) ms"
grep -E "Bytes Copied|Bytes Skipped|Files Copied|Files Skipped|DIR_COPY|Launched map tasks|Deleted|Files Deleted|Bytes Expected" /tmp/$name.log | sed 's/^\s*/ /' | sort -u; }
hdfs dfs -rm -r -f -skipTrash $P $DR/dr > /dev/null 2>&1
hdfs dfs -mkdir -p $P $DR/dr
hdfs dfs -cp /user/hadoop/data/{canteen_orders.csv,student_orders.csv,menu.csv,feedback.txt,orders_x30.csv} $P/
echo "== 0. what we protect (prod)"
hdfs dfs -count -h $P
echo "== 1. first full copy to the DR cluster (one map per file here)"
run d1 $P $DR/dr/
hdfs dfs -count -h $D
echo "== 2. a day later: one new file, one changed file, one deleted file"
hdfs dfs -cat $P/canteen_orders.csv | head -5001 > /tmp/day31.csv; hdfs dfs -put -f /tmp/day31.csv $P/orders_day31.csv
hdfs dfs -cat $P/menu.csv | sed 's/^chai,drink,15/chai,drink,18/' > /tmp/menu.csv; hdfs dfs -put -f /tmp/menu.csv $P/menu.csv
hdfs dfs -rm -skipTrash $P/feedback.txt > /dev/null
echo "-- plain distcp again (no -update): the existing files are NOT replaced"
run d2a $P $DR/dr/
hdfs dfs -ls $D | awk '{print " ", $5, $8}' | sed "s#$DR##"
echo "-- distcp -update: copy only what is new or different"
run d2 -update $P $D
echo "-- distcp -update -delete: also remove what prod deleted"
run d3 -update -delete $P $D
hdfs dfs -ls $D | awk '{print " ", $5, $8}' | sed "s#$DR##"
echo "-- is the price change there?"; hdfs dfs -cat $D/menu.csv | head -1
echo "== 3. snapshot-based sync: only the difference between two snapshots"
hdfs dfsadmin -allowSnapshot $P > /dev/null; hdfs dfsadmin -fs $DR -allowSnapshot /dr/canteen > /dev/null
hdfs dfs -createSnapshot $P s1 > /dev/null; hdfs dfs -createSnapshot $D s1 > /dev/null
hdfs dfs -mv $P/orders_day31.csv $P/orders_2026-10-31.csv
hdfs dfs -cat $P/canteen_orders.csv | head -2001 | tail -2000 > /tmp/day32.csv; hdfs dfs -put /tmp/day32.csv $P/orders_2026-11-01.csv
hdfs dfs -createSnapshot $P s2 > /dev/null
hdfs snapshotDiff $P s1 s2 2>/dev/null | sed 's/^/ /'
run d4 -update -diff s1 s2 $P $D
hdfs dfs -ls $D | awk '{print " ", $5, $8}' | sed "s#$DR##"
echo "== 4. throttle: -bandwidth 1 (MB/s per map) on the 19 MB student_orders.csv"
run d5 -bandwidth 1 $P/student_orders.csv $DR/dr/throttled.csv
echo "== 5. disaster drill: prod is down, run the report on the DR cluster"
hdfs dfs -rm -r -f -skipTrash $DR/dr/report > /dev/null 2>&1
hadoop jar /tmp/mr.jar ItemRevenue $D/canteen_orders.csv $DR/dr/report > /tmp/dr_job.log 2>&1
grep -oE "completed successfully|failed with state [A-Z]+" /tmp/dr_job.log
hdfs dfs -cat $DR/dr/report/part-r-00000 | head -3
echo "-- recovery point: what DR has vs prod right now"
hdfs dfs -put -f /tmp/day32.csv $P/orders_2026-11-02.csv # written after the last sync
echo " prod files: $(hdfs dfs -ls $P | grep -c '^-') DR files: $(hdfs dfs -ls $D | grep -c '^-') missing on DR: $(diff <(hdfs dfs -ls $P | grep '^-' | awk -F/ '{print $NF}') <(hdfs dfs -ls $D | grep '^-' | awk -F/ '{print $NF}') | grep '^<' | cut -c3-)"
# Run: docker cp distcp_lab.sh lab8-worker1-1:/tmp/ && docker exec lab8-worker1-1 bash /tmp/distcp_lab.shReal output. Timings vary. Notice step 2: plain DistCp reports success with "Files Skipped=4" while the DR menu still has the old price.
Applying a snapshot diff
Follow a DR folder as the diff is applied: a rename moves a name without copying bytes, and only the new file is copied.
Worked examples: real problems, solved and traced in memory
Four DR calculations from different industries: RPO and RTO, the sync window, snapshot savings and cost.
Does the nightly sync meet the regulator?
Problem statement
A bank's policy says RPO ≤ 4 hours and RTO ≤ 2 hours. Today it syncs once a night at 02:00 and failover takes 90 minutes. What is the worst-case RPO, and does it comply?
sync every 24 h · failover 90 min · limits 4 h / 2 h
RPO 24 h (limit 4) -> FAIL; RTO 1.5 h (limit 2) -> OK syncs needed per day for RPO 4 h: 6
Approach
- Worst case: disaster just before the next sync.
- RPO = sync interval; RTO = failover time.
- Compare with the limits.
Solution: run it live
What happens in memory, step by step
Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.
How long does the first copy take?
Problem statement
A telecom starts DR for 1.2 PB of call records. The inter-site link is 10 Gbit/s; DistCp may use 60% of it. How many days does the first full copy take?
1.2 PB · 10 Gbit/s · 60% usable
20.8 days
Approach
- Convert the link to bytes per second.
- Divide data by usable rate.
- Convert to days.
Solution: run it live
What happens in memory, step by step
Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.
How much listing does a snapshot diff save?
Problem statement
A folder holds 50 million files; 20,000 change per day. A plain -update run must compare every file (say 2 ms of NameNode work per file on each side); a -diff run asks only for the changes. Compare the comparison time.
50,000,000 files · 20,000 changes · 2 ms per file
-update compare: 56 h -diff: 1.3 min
Approach
- -update: every file is listed and compared on both clusters.
- -diff: the NameNode returns only the changes.
- Compare.
Solution: run it live
What happens in memory, step by step
Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.
Backup, active–passive or active–active?
Problem statement
An insurer loses about ₹5 lakh of business per hour of downtime and ₹2 lakh per hour of lost data. Option A, cloud backup: ₹40 lakh/yr, RTO 48 h, RPO 24 h. Option B, active–passive DR: ₹1.6 crore/yr, RTO 2 h, RPO 1 h. Option C, active–active: ₹4 crore/yr, RTO 0.1 h, RPO 0.1 h. Expect one disaster every 5 years. Which is cheapest in total?
3 options · 0.2 disasters per year
A backup run 40 lakh + expected loss 57.6 lakh = 97.6 lakh/yr B active-passive run 160 lakh + expected loss 2.4 lakh = 162.4 lakh/yr C active-active run 400 lakh + expected loss 0.1 lakh = 400.1 lakh/yr
Approach
- Expected yearly loss = 0.2 × (RTO × downtime cost + RPO × data cost).
- Total = running cost + expected loss.
- Compare.
Solution: run it live
What happens in memory, step by step
Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.
Check yourself
Quick revision
Lesson 12.2 in one screen
- DistCp = map-only MapReduce copy; maps copy files and verify checksums.
- No option: existing names are skipped (our changed menu.csv).
-update: size + checksum.-overwrite: always.-delete: mirror deletions. -update -diff s1 s2: apply a snapshot diff (1 file, 1 map, rename replayed in our lab).-ppreserves metadata;-pbkeeps block size so checksums match;-bandwidththrottles;-msets maps.- RPO = data you can lose (time since last sync); RTO = time to recover.
- Designs: backup, active–passive, active–active, cloud as DR. Replicate metadata (Hive metastore) too.
- Test with drills: our report ran on DR with identical results; the unsynced file was missing.
Interview and viva questions
What is DistCp in Hadoop?
DistCp (distributed copy) copies large amounts of data within or between clusters. It runs as a map-only MapReduce job: the client lists the source files, and map tasks copy them in parallel from source DataNodes to destination DataNodes, verifying checksums. It supports incremental copies (-update, -delete), snapshot-based syncs (-diff), preserving metadata (-p) and throttling (-bandwidth).
What is the difference between -update and -overwrite in DistCp?
With -update, a file is copied only if it is missing at the target or its size or checksum differs. With -overwrite, every file is copied again even if it is identical. Without either, files whose names already exist at the target are skipped, even if their content changed.
What are RPO and RTO?
The recovery point objective (RPO) is the maximum acceptable amount of data loss, measured as the time since the last good copy. The recovery time objective (RTO) is the maximum acceptable time to restore service after a disaster. Sync frequency drives RPO; automation and drills drive RTO.
How do you do disaster recovery for HDFS?
Keep a second cluster (or cloud storage) at another site, sync data with scheduled DistCp runs (ideally snapshot-based with -diff), replicate metadata such as the Hive metastore, document a failover runbook (DNS, job configs, access) and test it with regular drills. Commercial tools (for example Cloudera Replication Manager) automate the same steps.
Why does DistCp fail with a checksum mismatch between clusters?
HDFS file checksums are computed from block-level checksums, so they depend on block size and checksum type. If source and target use different settings, the checksums differ even for identical data. Preserve block size and checksum type (-pbc) or use the COMPOSITE_CRC combine mode; use -skipcrccheck only when you verify the data another way.
Practice problems
DR exercises with the real numbers from our two clusters.
Copy speed
The first copy moved 169,964,453 bytes in 25,540 ms. What was the effective rate in MB/s?
bytes · ms
6.3 MB/s
Show solution and explanation
print(round(169964453 / 2**20 / 25.540, 1), "MB/s")How it works: About 6.3 MB/s, including job start-up; the copy itself was faster.
What was skipped?
Run 2 copied 70,147 bytes and skipped 164,870,491. How many bytes were really changed on prod, and how many of the skipped bytes were stale?
Bytes Copied / Bytes Skipped
copied 70147 | stale but skipped: menu.csv 143 bytes
Show solution and explanation
print("copied", 70147, "| stale but skipped: menu.csv", 143, "bytes")How it works: Only 143 bytes were stale, but they held the new price. A tiny skip can be a business error.
Throttle check
At -bandwidth 1 (MB/s), what is the minimum time to copy 19,418,699 bytes? The run took 34.2 s. Where did the rest go?
19.4 MB · 1 MB/s
18.5 s minimum
Show solution and explanation
print(round(19418699 / 2**20, 1), "s minimum")How it works: About 18.5 s of copying; the rest was job submission, container start-up and checksum verification.
RPO for a schedule
Syncs run at 00:00, 06:00, 12:00 and 18:00. A disaster happens at 17:30. How much data is lost, and what is the worst case?
4 syncs a day
lost: 5.5 h | worst case: 6 h
Show solution and explanation
syncs = [0, 6, 12, 18]
d = 17.5
print("lost:", d - max(s for s in syncs if s <= d), "h | worst case: 6 h")How it works: 5.5 hours this time; the worst case is a full interval of 6 hours.
Mirror check
Write a function that lists files to copy, files to delete and files that are stale-but-skipped for a plain run.
two dicts name → checksum
copy: ['c'] stale but skipped: ['b'] left behind: ['d']
Show solution and explanation
src = {"a": "1", "b": "2", "c": "3"}
dst = {"a": "1", "b": "9", "d": "4"}
print("copy:", [n for n in src if n not in dst])
print("stale but skipped:", [n for n in src if n in dst and src[n] != dst[n]])
print("left behind:", [n for n in dst if n not in src])How it works: c is copied, b is stale but skipped, d stays behind: the three problems -update and -delete solve.
Maps for a big copy
DistCp splits 120,000 files totalling 30 TB over -m 200 maps. Roughly how much does each map copy, and how long at 80 MB/s per map?
30 TB · 200 maps · 80 MB/s
154 GB per map, about 0.5 h
Show solution and explanation
per_map_gb = 30 * 1024 / 200
print(f"{per_map_gb:.0f} GB per map, about {per_map_gb * 1024 / 80 / 3600:.1f} h")How it works: About 154 GB per map and 0.5 hours, if the network and both clusters can sustain 16 GB/s in total, which they often can't: throttle and schedule.
Is a drill worth it?
A failover drill costs one Saturday for 6 engineers (₹15,000 each). Without drills, the team estimates RTO doubles from 2 h to 4 h in a real disaster, at ₹5 lakh per hour. With one disaster every 5 years, is a drill every quarter worth it?
4 drills/yr · ₹15,000 × 6 · 0.2 disasters/yr
drills Rs 360,000 vs expected saving Rs 200,000 per year
Show solution and explanation
drills = 4 * 6 * 15000
saved = 0.2 * (4 - 2) * 500000
print(f"drills Rs {drills:,} vs expected saving Rs {saved:,.0f} per year")How it works: ₹3.6 lakh vs ₹2 lakh on these illustrative numbers. Teams usually still drill, because a failed real failover can be far worse than the average, and regulators often require it.
Build a copy plan from a snapshot diff
Given a snapshotDiff report with +, -, M and R lines, produce the list of DR actions and the bytes to copy.
diff lines + sizes
[('copy', './a.csv'), ('delete', './old.csv'), ('rename', './x.csv', './y.csv'), ('copy', './menu.csv')] 28229 bytesShow solution and explanation
diff = ["M\t.", "+\t./a.csv", "-\t./old.csv", "R\t./x.csv -> ./y.csv", "M\t./menu.csv"]
size = {"./a.csv": 28086, "./menu.csv": 143}
plan, nbytes = [], 0
for line in diff:
kind, path = line.split("\t")
if path == ".":
continue
if kind in "+M":
plan.append(("copy", path)); nbytes += size[path]
elif kind == "-":
plan.append(("delete", path))
elif kind == "R":
plan.append(("rename",) + tuple(path.split(" -> ")))
print(plan, nbytes, "bytes")How it works: Copy a.csv and menu.csv (28,229 bytes), delete old.csv, rename x.csv to y.csv: everything else is untouched.
Real-world scenario questions (asked in company interviews)
DistCp and DR questions come up in data platform and Hadoop admin interviews.
"How do you copy data between two Hadoop clusters?"
A standard question for any Hadoop role.
The interviewer is checking: DistCp and its key options.
Show a strong answer
- Use DistCp: a map-only MapReduce job that copies files in parallel and verifies checksums.
- For repeated syncs use -update (size + checksum) and -delete; for big folders use snapshots with -diff.
- Throttle with -bandwidth, preserve metadata with -p, use webhdfs:// across Hadoop versions.
The DR copy has old data, but every nightly job "succeeded"
An auditor finds that a reference table on DR is three months out of date.
The interviewer is checking: DistCp default semantics and verification.
Show a strong answer
- Plain DistCp skips files whose names already exist; a file rewritten with the same name was never copied again.
- Fix the job: -update (and -delete if DR must mirror deletions), or snapshot-based -diff syncs.
- Add verification: compare file counts and checksums (hdfs dfs -checksum) for key folders, and alert on differences.
Design DR for a 2 PB cluster with RPO 1 hour
A payments company asks for a plan and its cost drivers.
The interviewer is checking: RPO/RTO thinking and incremental replication.
Show a strong answer
- Seed DR once (staged DistCp or shipped disks), then hourly snapshots with distcp -update -diff on the changed folders.
- Replicate the Hive metastore and configs; keep a runbook for DNS, job schedulers and access; run quarterly drills.
- Size the link for the hourly change rate with headroom; monitor sync lag as a first-class alert.
"What is the difference between backup and disaster recovery?"
Often asked together with RPO and RTO.
The interviewer is checking: data protection vs service continuity.
Show a strong answer
- Backup keeps copies of data so it can be restored; restoring and rebuilding compute may take days (long RTO).
- DR keeps a ready site that can take over the service within the RTO, with data no older than the RPO.
- Many teams need both: DR for outages, backups or snapshots for mistakes (a bad -delete is replicated to DR too).