Unit 1 · 4 hrs · CSUE301 Big Data Analytics
Big Data
Fundamentals
Every idea in this chapter is tested on the same small example: CityCourier, a food-delivery service running three neighbourhood hubs out of one kitchen. Sixteen orders, one fifteen-minute lunch rush — small enough to add up by hand, and that is exactly the point. Everything a real big-data system does to a billion rows, we will do to sixteen, so you can see it happen.
16 rows, plotted in time
You can eyeball this one
Which hub is busiest? Just look.
Each dot is one order: when it landed, and which hub picked it up. At sixteen rows your eyes are a perfectly good query engine — Hub N (rose) is visibly busier in the first half, Hub E (violet) picks up toward the end. No cluster required yet.
One kitchen, three hubs, one far zone
But it's not one machine
The three hubs don't share memory.
Hub N, Hub S and Hub E are separate buildings with separate order queues and separate staff. Nothing here is a metaphor for a "distributed system" — it already is one. Section 1.3 gives this shape a name: shared-nothing architecture.
Same arithmetic, three zoom levels
Where "big" data starts
Nothing changes except the size.
Hold the arrival rate fixed and stretch the clock: sixteen orders becomes forty-six thousand a day across one city's worth of hubs. No new idea appears at that scale — the same counting, the same joins, the same trade-offs from this chapter. What breaks is doing it on one machine, in your head, or in a spreadsheet. That gap is the entire subject of this course.
What Makes Data “Big”?
You have a log of orders. At what point does it stop being a spreadsheet problem and become a big-data problem — and what, precisely, changes when it does?
Sixteen rows is not big data by any definition. You can read all of them in the time it takes to scroll. But every large-scale system this course studies is built to survive the moment a table like this stops being sixteen rows and becomes sixteen billion — and the only way to see what breaks is to know, in complete and boring detail, what the small version looks like first.
The five things that get harder, not the one number that gets bigger
It is tempting to define "big data" as "data too big for one computer." That definition is not wrong, but it hides the useful part. Data resists being handled by one machine for at least five independent reasons, and a system that only solves one of them is not a big-data system — it is a bigger spreadsheet.
These five are independent axes, not stages of one problem. A dataset can be enormous and still perfectly trustworthy (a well-run sensor archive). A dataset can be tiny and still unusable (three rows, all wrong). The challenges CO1 asks you to analyze — storage, processing, heterogeneity, quality, extraction of value — map onto these five almost one-to-one: Volume and Velocity drive storage and processing challenges; Variety drives heterogeneity; Veracity drives quality; Value is the challenge of the other four actually paying off.
depth · the V-family didn't stop at five
Some texts use only 3V (Volume, Velocity, Variety — the original 2001 formulation) and add Veracity and Value later; others extend further to Variability, Validity, Volatility and Visualization. None of this is a disagreement about big data — it's different authors choosing how finely to slice the same handful of underlying difficulties. This chapter teaches the 5V form because it is the one you will meet most often in industry writing and in this syllabus's own "characteristics and challenges" framing; if your reference book uses a different count, the ideas underneath still map across.
Worked Example · The CityCourier Log
Here is the entire spine dataset for this chapter: every order CityCourier's three hubs handled during one fifteen-minute lunch rush. Read it once, in full, the way you would a printed table — you will not get this chance again once the chapters ahead make it bigger.
| # | hub | restaurant | t (s) | amount (₹) | rating | delivery (s) |
|---|---|---|---|---|---|---|
| 1 | Hub N | Curry Point | 12 | 340 | 5 | 612 |
| 2 | Hub S | Momo Hut | 48 | 180 | 4 | 540 |
| 3 | Hub N | Wrap City | 75 | 260 | — | 780 |
| 4 | Hub E | Sushi Go | 130 | 560 | 5 | 900 |
| 5 | Hub S | Curry Point | 158 | 310 | 3 | 660 |
| 6 | Hub N | Pizza Barn | 201 | 420 | 4 | 720 |
| 7 | Hub E | Momo Hut | 244 | 150 | — | 480 |
| 8 | Hub S | Wrap City | 289 | 275 | 2 | 810 |
| 9 | Hub N | Curry Point | 333 | 355 | 5 | 600 |
| 10 | Hub E | Pizza Barn | 378 | 440 | 4 | −60 |
| 11 | Hub S | Sushi Go | 422 | 520 | — | 930 |
| 12 | Hub N | Momo Hut | 467 | 165 | 3 | 510 |
| 13 | Hub E | Curry Point | 511 | 330 | 4 | 690 |
| 14 | Hub S | Pizza Barn | 556 | 410 | 5 | 750 |
| 15 | Hub N | Sushi Go | 602 | 545 | 4 | 870 |
| 16 | Hub E | Wrap City | 648 | 285 | 5 | 795 |
Walk the five V's across this one table:
- Volume — 16 rows at rest. Small here; the "at scale" tab above already showed the same rate holds 1,536 orders a day per hub-set, ~46,000 across a city's worth of hub-sets. The row count is the least interesting axis — it is also the only one a bigger hard drive can fix.
- Velocity — the 16 orders span 636 seconds, so a new order lands roughly every 42.4 seconds on average (636 ÷ 15 gaps). A system that can only store orders but not absorb one every 42 seconds without falling behind has a velocity problem even if it never runs out of disk.
- Variety — this table shows only the structured fields. The same order also carries a GPS breadcrumb trail (semi-structured, Section 1.6) and, in the real app, a free-text review. Three shapes, one order.
- Veracity — three ratings are missing (18.8% of the log) and order #10 claims a delivery time of −60 seconds: a courier who arrived a minute before the food left the kitchen. That second problem is worse than the first. A missing value announces itself; a wrong value that is still a plausible-looking number does not.
- Value — none of the above matters until someone asks a question of it. "Which hub needs another rider?" turns this table into a staffing decision. Nobody asking anything turns it into disk usage.
Interactive · One Bad Record, One Silent Number
Veracity filter
toggle and watch the total moveOrder #10's delivery time is impossible, which tells you its clock is not trustworthy — but if the clock is wrong, what confidence do you have in that same row's amount field? The strict policy below drops the whole row rather than the one broken cell once any field fails a sanity check, on the reasoning that a record caught lying once has lost the benefit of the doubt everywhere else.
pitfalls
- "I have a lot of rows, so this is a big-data problem." Volume alone is the easiest V to fix — buy more disk. A billion small, clean, slow-arriving rows on one well-specified server is not what this course is about; a hundred rows a second of messy, five-shaped, unverifiable data is.
- "No NULLs means no veracity problem." Order #10 has no missing field. Every cell is populated with something that parses as a number. The veracity failure is entirely in the fact that the number is impossible — a check that has nothing to do with counting blanks.
- "Value follows automatically once you have enough Volume, Velocity and Variety." It does not. A log nobody queries has the same business value at sixteen rows and at sixteen billion: zero. Value is earned by asking a specific question, not accumulated by storing more answers to none.
Practice
-
Using the full log, count how many orders each hub handled. If CityCourier can afford exactly one additional rider today, which hub should get them?
Solution
Hub N: 6 orders (#1,3,6,9,12,15). Hub S: 5 orders (#2,5,8,11,14). Hub E: 5 orders (#4,7,10,13,16). Total 16, which checks out against the log. Hub N is one order ahead of the other two, so the marginal rider goes there first.
-
Suppose you learn that order #7's rating of "—" is not missing at all: the review system logged a genuine 0-star rating as blank during a five-minute app outage, and 0 is a valid score in this app. Does reclassifying #7 change which V category its problem belonged to, and does it change the missing-rating percentage?
Solution
Yes to both. #7 moves out of Veracity (a value that shouldn't be trusted) because there is now nothing wrong with it — it was a Variety/ingestion bug (the outage encoded a valid low score as an absent one), already fixed by knowing the true value. The missing-rating count drops from 3/16 (18.8%) to 2/16 (12.5%), since #3 and #11 are still genuinely blank.
-
A dashboard reports CityCourier's average rating as 4.0, computed from the 13 non-missing scores, and a manager concludes "customers love us." What's wrong with that conclusion — assuming the arithmetic itself is correct?
Solution
The conclusion assumes the three missing ratings are missing for reasons unrelated to how the order went — that they are, in the jargon, missing completely at random. There is no evidence for that here, and reason to doubt it: if customers who had a bad experience are less likely to bother rating at all, the missing three are disproportionately the unhappy ones, and 4.0 overstates satisfaction. Veracity is not just "is the visible data correct" — it's also "is what's invisible invisible for an innocent reason."
-
If CityCourier's order volume grows 100× next year on the same order-entry app, will the rate of impossible records like #10 improve, worsen, or stay the same — and separately, will the count of them stay manageable?
Solution
The rate stays the same: whatever software defect produced a negative delivery time is a property of the app, not of how many orders flow through it, so scaling Volume alone doesn't touch Veracity's underlying cause. But the count scales with volume — one bad row in sixteen becomes roughly a hundred in sixteen hundred, thousands per day at city scale. A rate you could catch by reading the table stops being catchable by eye long before it stops being small; this is precisely why Chapter 3 onward builds automated data-quality checks into the pipeline instead of leaving them to a human glance.
Where a Row Comes From, and Where It Goes
Row #4 in the table above didn't start as a row and won't end as one. What happens to it before and after it sits in that table?
Follow order #4 — Hub E, Sushi Go, ₹560, the most expensive order in the log. At t = 130s it is a tap on a customer's phone. Twenty-four hours later it may be three different things at once: a settled row in a ledger, an input to tomorrow's staffing recommendation, and (per Section 1.7's retention rules) a countdown toward eventual deletion. A large-scale system has to manage all three simultaneously, for every row, forever — which is why the data life cycle is treated as a first-class design object, not an afterthought to storage.
Seven stages, and a hand-off at every arrow
Every large-scale system moves a record through roughly the same seven stages, whatever the domain:
Each arrow between stages is a network hop, and every network hop is a place a record can be delayed, duplicated, or lost — which is exactly the boundary Section 1.6 spends its cost-trade-off discussion on. The life cycle is not a diagram you draw once; it is the map of every place your system can fail.
why this differs from a single database's life cycle
In a one-machine system, "store" is one event and "the data" has one location. In CityCourier, order #4 is written to Hub E's local log and replicated toward a central store and, once Chapter 2's replication strategies are in play, copied again for fault tolerance. "Delete this order" is no longer one write — it is a coordination problem across every copy, which is precisely why "delete" reappears as a pitfall below.
Worked Example · Order #4, Stage by Stage
Trace one record end to end
order #4 · Hub E · ₹560The Life Cycle, Drawn
pitfalls
- "Storage is the end of the life cycle." Storage is the middle. Most of the engineering (and most of this course) is about what happens on either side of it — ingestion at one end, processing, analysis, and governed deletion at the other.
- "Delete means the data is gone." Deleting a logical order from the primary database does not, by itself, remove it from backups, replicas, cached aggregates, or a downstream analytics warehouse. "Right to be forgotten" compliance (Section 1.7) requires tracing every copy the life cycle created, not just the first one.
- "Once ingested, a record's contribution to an analysis is fixed." The Lambda architecture in Section 1.4 exists precisely because early analysis, run on a partial stream, routinely needs revising once the full batch arrives — the life cycle can loop back into Process more than once for the same record.
Practice
-
List, in order, the seven life-cycle stages order #9 (Hub N, Curry Point, ₹355) passes through between the customer's tap and the moment it appears inside a monthly revenue report.
Solution
Generate (tap) → Collect (edge capture at Hub N) → Ingest (validated, timestamped, queued) → Store (written durably to Hub N's log) → Process (folded into a batch aggregate) → Analyze/Visualize (appears in the monthly report) — with Archive/Purge still ahead of it, on the same 90-day / 2-year schedule as every other row.
-
CityCourier's legal team rules that GPS breadcrumb data must be purged 24 hours after delivery, while the order record itself (amount, rating) is kept for 2 years for tax purposes. Does a single order therefore have one life-cycle length or several?
Solution
Several — the life cycle is defined per field, not per row, once retention policy gets involved. The GPS trail for order #9 completes its full seven stages, including purge, within a day; the transactional fields of the same logical order are still in the Store/Archive stages nearly two years later. A "record" in governance terms is really a bundle of independently aging fields.
-
A customer exercises their right to be forgotten. Support confirms the order is deleted from the primary orders database. Is CityCourier's obligation now satisfied?
Solution
Not necessarily. The note above lists at least three other places the same record could still exist: a backup taken before the delete, a replica at another hub not yet caught up, and any batch-layer aggregate (Section 1.4) computed while the row still existed. Deleting from one store proves the life cycle's Store stage was touched, not that every downstream stage was.
-
Order #10's impossible −60-second delivery time (Section 1.1) was actually detectable the moment the courier's app reported it. At which life-cycle stage should that check ideally happen, and why does catching it at the Process stage instead (as a nightly batch job did, in this trace) cost more?
Solution
Ideally at Ingest, where the record is still one hop from its source and can be rejected, flagged, or sent back for correction before it is durably stored anywhere. Catching it at Process means the bad value has already been replicated, already sits in at least one archive snapshot, and any aggregate computed before the nightly job ran (a dashboard refresh, a speed-layer estimate) already absorbed the bad number. The cost of a data-quality bug grows with every life-cycle stage it survives.
Four Ways to Split the Work
Hub N, Hub S and Hub E each hold their own slice of the log. How do you turn three separate answers into one correct answer — and does the rule change depending on what question you're asking?
Every model in this section answers the same underlying question — how do independent machines cooperate without sharing memory? — but each answers it under different constraints: is the input finite or endless? Does step 2 need step 1's global result, or just its own slice? These constraints, not preference, are what determine which model fits a given problem.
The foundation: shared-nothing
CityCourier's three hubs already are a shared-nothing architecture: each has its own CPU, its own memory, its own local order log, and the only way one hub learns anything about another is by sending it a message over the network. No hub can reach into another's memory. This is a deliberate design, not a limitation to work around — it is what lets CityCourier add a fourth hub next year by buying one more machine, instead of buying a bigger one.
shared-nothing is not "no communication"
The name is frequently misread. Shared-nothing means no shared hardware — no shared memory, no shared disk that two nodes both touch directly. It says nothing about whether the nodes talk to each other; every model below has them talking constantly, over the network, on purpose.
Given that foundation, four models answer "how do the messages flow?" differently:
Worked Example · MapReduce, Counting Orders Per Restaurant
Ask "how many orders did each restaurant get?" and MapReduce's two phases fit exactly: each hub can count its own restaurant totals with zero coordination (the map), and the only cross-hub work is merging same-named restaurants together (the reduce).
| restaurant | count |
|---|---|
| Curry Point | 4 |
| Momo Hut | 3 |
| Wrap City | 3 |
| Sushi Go | 3 |
| Pizza Barn | 3 |
Notice what never had to happen: no hub ever asked another hub "what have you got so far?" mid-map. That independence is exactly why MapReduce scales — and exactly why it struggles with the next question.
Worked Example · BSP / Graph Processing, Shortest Route to Zone Z
Now ask a different kind of question: "what's the fastest route from the Kitchen to Zone Z, a customer cluster reachable only through the hubs?" This is not embarrassingly parallel — Hub E cannot know its true distance from the Kitchen until it has heard from whichever hub sits between them, which itself had to hear from the Kitchen first. The answer has to propagate, in rounds. That is precisely what BSP is for, and graph algorithms are its most common use — Google's Pregel, the model this course's "graph processing" bullet ultimately refers to, is BSP with one rule added: think like a vertex. Every node runs the same tiny program, knowing only its own state and its neighbours' messages.
Superstep by superstep
Kitchen → Hub N / Hub S / Hub E → Zone ZBefore any messages: only the Kitchen knows its own distance. Every other vertex starts at ∞ and updates only once a message reaches it.
why this needed four rounds, not one
Hub E's true distance (11, via Hub N) only becomes knowable in superstep 2, once Hub N has something to relay. Zone Z's true distance (14, via Hub E) only becomes knowable in superstep 3, once Hub E has revised its own number. Each superstep's global barrier — everyone waits until everyone finishes — is what guarantees superstep 3 never runs on stale superstep-1 information. A single MapReduce-style round could not have produced this answer at all.
Worked Example · Stream Processing, a Running Average That Doesn't Wait
Last question: "what's the average delivery time, updated continuously, without waiting for the lunch rush to end?" Batch models assume you can see the whole input before answering; a stream model assumes you never will. The usual fix is the tumbling window: chop the endless stream into fixed, non-overlapping slices — here, 300 seconds each — and emit one average per slice as soon as it closes.
grey = every reading in the window as it arrived · amber = veracity-filtered (Section 1.1's rule applied per window)
Window 2 (300–600s) is the one to stare at: its raw average, 570.0s, is lower than its filtered average, 696.0s — because order #10's impossible −60-second reading was pulling the raw number down, not up. A stream engine that reports 570.0s without a veracity check isn't just imprecise, it's reporting the wrong direction of the story: deliveries in that window were actually slower than average, not faster.
pitfalls
- "BSP is a graph algorithm." BSP is a general model for synchronous parallel rounds; it says nothing about graphs. Pregel is what you get when you specialise BSP to "each vertex runs a compute() function" — the graph part is the specialisation, not the base model.
- "Streaming is just MapReduce that never stops." A stream job cannot wait for "all the data" the way a batch reduce implicitly can — there is no such moment. It must decide, per window, with only what has arrived so far, which is exactly why the raw-vs-filtered gap above exists: the window closed before anyone could double-check order #10.
- "More supersteps means the algorithm is slower to converge, full stop." More supersteps means more network round-trips, which does cost wall-clock time (Section 1.5) — but a problem that needs propagation, like shortest path, cannot be solved correctly in fewer rounds than its longest dependency chain, no matter how the code is written.
Practice
-
Run the same map/shuffle/reduce pattern shown above, but group by hub instead of restaurant. What are the three reduced counts, and do they sum to 16?
Solution
Map: each order emits (hub, 1) — this needs no shuffle at all, since every order already lives on its own hub's node; the "grouping" is free. Reduce: Hub N → 6, Hub S → 5, Hub E → 5. Sum: 6+5+5 = 16, matching the log's row count.
-
Suppose the Hub S → Zone Z edge weight were revised from 8 minutes to 3 (a new shortcut opens). Recompute the shortest distances and say which superstep now first reaches the correct answer for Zone Z.
Solution
Superstep 1 is unchanged (Kitchen=0, Hub-N=6, Hub-S=9, Hub-E=15, Zone-Z=∞). Superstep 2: Hub-E still revises to 11; Zone-Z now hears 9+3=12 from Hub-S (beating the old 17-via-Hub-N tie), so Zone-Z=12. Superstep 3: Hub-E's 11+3=14 arrives but 14>12, so nothing changes. The computation converges one superstep earlier than the original graph — in 3 supersteps rather than 4 — and the shortest path to Zone-Z now runs through Hub-S, not Hub-E.
-
Window 2's raw average (570.0s) undersells how slow deliveries actually were, because a wrongly-negative reading dragged it down. Could a wrongly-negative reading ever make a raw window average look artificially slow instead of artificially fast? Construct the condition under which that happens.
Solution
No single rule guarantees a direction — it depends on the sign and size of the corrupted value relative to the rest of the window. A large positive corrupted value (say a delivery mistakenly logged as 9,000 seconds instead of 900) would drag the raw average up, making deliveries look slower than they were. The lesson generalises past this one window: an unvalidated value doesn't bias an aggregate in a fixed direction, which is exactly why you check for validity rather than just "does the average look reasonable."
-
CityCourier wants both (a) total revenue per hub and (b) the shortest route from the Kitchen to every hub. Which of this section's models fits each task, and why can't MapReduce's two-phase shape comfortably do both?
Solution
(a) is embarrassingly parallel — every hub's revenue depends only on its own rows — so MapReduce's map-then-reduce shape fits directly, as Section 1.3's first worked example showed. (b) is inherently iterative: each hub's shortest distance depends on another hub's shortest distance, which is exactly the propagation pattern MapReduce has no native concept for. Forcing it into MapReduce would mean running a whole new MapReduce job per superstep, writing every intermediate result to disk between rounds — correct, but paying a full disk round-trip for what BSP does with one in-memory message pass. This gap is historically why Pregel-style, BSP-native systems were built at all.
Where Batch and Stream Results Actually Live
Section 1.3 produced two different kinds of answer — a slow exact one and a fast approximate one. An architecture is the wiring that decides which one a dashboard shows, and when.
Any large-scale system is layered, whatever else it does: raw events come in, get stored somewhere, get processed into something usable, and get served to whoever asked. The interesting design decisions live in exactly one question: how many processing paths does data take on its way from storage to a dashboard, and how do their answers get reconciled?
Worked Example · A Dashboard That Disagrees With Itself, On Purpose
Run CityCourier's revenue-per-hub figure (Section 1.3's MapReduce pattern, grouped by hub instead of restaurant) through both layers of a Lambda design and watch them disagree:
speed layer · snapshot after 10 of 16 orders
batch layer · exact, full 16-order log
Neither number is a bug. The speed layer is answering "what do we know right now," honestly, from six fewer orders than exist. The serving layer's entire job is to display the speed layer's estimate live and quietly swap in the batch layer's exact figure once it lands — without that swap, "provisional" silently becomes "permanent," which is where dashboards start lying.
Lambda and Kappa, Side by Side
Lambda · two paths, one merge
Kappa · one path, replay to reprocess
A Data Lake is neither of these paths — it's the raw, schema-on-read store the Event Log or Data Lake box above actually is: every field CityCourier ever collected, kept in its original shape, with structure applied only when something reads it. Both Lambda and Kappa can sit on top of one.
pitfalls
- "Kappa is strictly the modern replacement for Lambda." Kappa needs a stream engine that can replay potentially its entire history cheaply. If CityCourier's batch algorithm and its streaming algorithm genuinely differ (say, the nightly job trains a staffing model that the live layer only approximates), or if reprocessing years of history is routine, keeping two purpose-built paths can beat forcing one engine to do both jobs.
- "Schema-on-read means no organisation." A data lake with no catalogue, no naming convention, and no ownership isn't flexible — it's a data swamp nobody can query without archaeology first. Schema-on-read defers structure; it doesn't excuse skipping metadata.
- "The speed layer's number is simply wrong." It's provisional, computed honestly from less data, not incorrect. Treating it as final is the actual mistake — not the number itself.
Practice
-
Using the two panels above, compute how much each hub's revenue figure will still move once the batch layer absorbs the remaining 6 orders.
Solution
Hub N: ₹2,085 − ₹1,375 = ₹710. Hub S: ₹1,695 − ₹765 = ₹930. Hub E: ₹1,765 − ₹1,150 = ₹615. These three differences sum to ₹2,255, which is exactly the revenue from orders #11–16 (520+165+330+410+545+285) — a useful sanity check that the batch/speed gap accounts for precisely the missing orders and nothing else.
-
CityCourier switches to a Kappa design and later discovers a bug: the streaming aggregator was mis-parsing amounts under ₹200. What does "replay to fix it" mean operationally, and what does Lambda's batch layer give you for free that Kappa now has to do deliberately?
Solution
Under Kappa, fixing the bug means deploying the corrected aggregation logic and re-running it over the entire retained event log from the start, producing a corrected history in one pass — the log itself never changes, only the logic reading it. Under Lambda, the batch layer already recomputes from raw data on every run by design, so a logic bug would have self-corrected at the very next scheduled batch job with no special "replay" step; Kappa gets the same correctness, but only if the team remembers to trigger it.
-
A shift manager glances at the dashboard at t = 422s, sees "Hub S: ₹765," and decides Hub S needs no extra staff today. What's the risk in that decision, given what you know about the serving layer?
Solution
₹765 is the speed layer's figure after only 10 of 16 orders — Hub S's true total for just this lunch rush is ₹1,695, more than double. Deciding staffing from a number the serving layer itself labels as provisional risks under-resourcing the hub that, once the batch layer catches up, turns out to be busiest. The fix isn't to distrust the speed layer generally — it's to know which numbers on the dashboard are "as of now" and which are final.
-
Which of Section 1.3's distributed computing models most naturally implements a Lambda architecture's batch layer, and which implements its speed layer?
Solution
MapReduce (or a BSP-style iterative job, for anything that needs propagation) fits the batch layer: it assumes a finite, complete input and produces one exact answer per run, exactly matching the nightly full-log recompute. Stream processing fits the speed layer by definition — unbounded input, windowed, approximate, always live. Lambda is, in this sense, "pick one model from each side of Section 1.3's foundation and wire their outputs into one serving layer."
"Faster" Is Not One Number
Section 1.3 said three hubs beat one node at counting orders. By how much, exactly — and does a fourth hub make it better still, or worse?
Four numbers, precisely defined, replace the word "faster":
Scalability is not a fifth number — it's what happens to Speedup and Efficiency as p grows. A perfectly scalable system has Speedup(p) = p (Efficiency = 100% at every p); every real system falls short of that line, and by how much is the whole engineering story.
Worked Example · Processing the 16-Order Batch
Give each order a fixed 40ms of aggregation work. One node does all 16 serially. Three nodes split the work along the hubs' natural partition (6 / 5 / 5 orders) and pay a fixed 55ms coordination cost once, at the end, to shuffle and merge — the same shuffle Section 1.3 already introduced.
Try it with a different node count
same 16 orders, same 40ms/order, same 55ms shuffle3 nodes split 6/5/5 — a well-balanced partition, so most of the theoretical 3× speedup survives as real speedup.
the surprise in the 2-node case
Try "2 nodes" above (Hub N+S combined on one machine, Hub E alone on the other). It is less efficient (64.6%) than the 3-node split (72.3%), despite having one fewer machine to coordinate. The reason has nothing to do with node count: 11-vs-5 is a lopsided split, so the two-node machine sits idle waiting on its slower partner, while the three-node split's near-even 6/5/5 wastes almost nothing. Balance dominates headcount. A cluster that adds machines without rebalancing the work can get slower speedup, not faster, than a smaller, well-balanced one.
depth · efficiency and utilization can be the same number
Resource utilization is the fraction of the compute you paid for that was actually doing useful work: total useful work time ÷ (p × wall-clock time). Here, the three nodes' combined work is 240+200+200 = 640ms — exactly T₁, because reshuffling the same 16 orders across more machines didn't create or duplicate any work. Utilization = 640/(3×295) = 72.3%, identical to Efficiency(3) above. That equality is not a coincidence of this example; it holds whenever no work is duplicated across nodes. It breaks — utilization and efficiency diverge — the moment redundant computation enters, such as a fault-tolerance scheme that recomputes the same partition on two machines on purpose.
pitfalls
- "More nodes always means more speedup." The 2-node case above is the counterexample sitting right there in the panel: fewer machines, worse efficiency, because of imbalance rather than coordination cost.
- "Speedup and efficiency are basically the same measurement." Speedup(3) = 2.17× sounds good in isolation; Efficiency(3) = 72.3% is the same fact stated as "you kept about three-quarters of what three machines could theoretically give you." Report speedup alone and a decision-maker can't tell efficient scaling from wasteful scaling.
- "Higher throughput means lower latency." They can move in opposite directions. A system that batches more work per round can raise throughput while making any individual item wait longer in the batch before it starts — exactly the batch-layer trade-off Section 1.4's Lambda architecture is built around.
Practice
-
Compute resource utilization for the 1-node case (p=1).
Solution
Utilization = useful work time ÷ (p × wall time) = 640ms ÷ (1 × 640ms) = 100%. With one node, "wall time" and "work time" are the same thing by definition — there is no possibility of idling relative to yourself, which is why p=1 is always the trivial 100% case.
-
If the shuffle overhead for the 3-node case rose from 55ms to 200ms (a slower network), is 3-node still faster than 1-node? At what overhead does 3-node stop being worth it at all?
Solution
At 200ms overhead: T₃ = 240 + 200 = 440ms, still comfortably below T₁'s 640ms — 3 nodes remain the better choice. The break-even point is where T₃ = T₁: 240 + X = 640, so X = 400ms. Below 400ms of shuffle overhead, splitting the work across 3 nodes wins; above it, the coordination cost eats the entire benefit and a single node would have finished first.
-
The 3-node split (72.3% efficient) beats the 2-node split (64.6% efficient) despite having more machines to coordinate. What does this imply about treating "scalability" as a property of node count alone?
Solution
It implies scalability is a property of the partitioning as much as the hardware. A system description that says "we scale to N nodes" without saying how work is divided among them is incomplete — the same N nodes can land anywhere from near-linear speedup to barely-better-than-serial, purely as a function of how evenly the load is split.
-
Section 1.3's BSP shortest-path example took 4 supersteps, each ending in a global barrier. If each barrier round-trip costs the same 55ms this section used for a single MapReduce shuffle, what's the total coordination overhead of the BSP example, and how does it compare to MapReduce's cost?
Solution
4 supersteps × 55ms ≈ 220ms of pure coordination overhead for BSP, versus one 55ms shuffle for MapReduce — roughly four times the coordination cost, purely because the problem needed four rounds of propagation rather than one. This is the concrete, measurable version of Section 1.3's claim that "more supersteps costs real wall-clock time": here is exactly how much, in the same units this section already established.
What a Cluster Owes You When It Goes Dark
Two questions, both about what a distributed system does under stress: what happens when Hub S loses its connection mid-rush — and separately, is it cheaper to move data to computation, or computation to data?
Part A · Consistency, Availability, Partition tolerance
A network partition is exactly what it sounds like: Hub S can no longer talk to the rest of CityCourier's cluster, but its own machine is fine and its own customers keep tapping "confirm." The CAP theorem, due to Eric Brewer, describes what a system can promise while that's happening:
Brewer's result is narrower than it's usually quoted: you cannot have all three while a partition is actually happening. Outside a partition — the overwhelming majority of the time — a well-built system gives you all three at once. The theorem is a statement about a failure mode, not a permanent tax on every request a distributed system ever serves.
the choice is CP vs AP, and only during the partition
Since real distributed systems cannot promise a partition will never happen, Partition tolerance is effectively non-negotiable, which leaves one real decision: when a partition hits, does the system stay Consistent (refuse or delay requests it can't verify against the rest of the cluster) or stay Available (answer anyway, from whatever it has locally, and reconcile afterward)? "CA" — consistent and available with no partition tolerance — is only achievable if you can guarantee network failures never happen, which no real multi-machine system can.
Worked Example · Ninety Seconds Without Hub S
Orders arrive across the whole log at 16 orders in 636 seconds — about 0.0252 orders/second, or roughly 1.5 a minute. Suppose Hub S loses its link to the central cluster for 90 seconds during the rush. Expected orders arriving at Hub S in that window: 0.0252 × 90 ≈ 2. Small, but not zero — and what happens to those two orders is exactly the CP/AP choice.
choose Availability (AP)
Hub S accepts both orders locally, confirms them to the customer instantly, and syncs with the central cluster once the link returns. Risk: if either order was also placed through another channel during the outage (a customer retrying because the app looked frozen), the cluster now has to reconcile two records of what might be the same order — a conflict-resolution problem, not a lost-order problem.
choose Consistency (CP)
Hub S refuses or queues both orders until it can confirm with the central cluster that no conflicting state exists. Risk: for up to 90 seconds, Hub S looks completely dead to exactly the two customers unlucky enough to order during the gap — a correctness guarantee purchased with a visible, if small, outage.
Notice neither branch is "wrong." CityCourier choosing AP for order placement (a missed reconciliation is annoying but fixable) while choosing CP for, say, refund processing (a double refund is a real loss) is a completely reasonable, and common, design — CAP is a per-operation decision, not a single global setting for the whole system.
Part B · Storage, Computation, and Communication Cost
Every distributed operation spends three different kinds of resource: storage (keeping data somewhere), computation (doing something with it), and communication (moving it between machines that don't share memory). The general engineering principle — data locality, which Chapter 2's file systems are built around — is to minimise the most expensive of the three, and communication is very often it.
Worked Example · Ship the Data, or Ship the Question?
Each CityCourier order carries a GPS breadcrumb trail: 45 points × 24 bytes each = 1,080 bytes/order, × 16 orders = 17,280 bytes of raw tracking data. Someone at head office wants one number from it: each hub's average delivery distance. Two ways to get it, over the same 2 MB/s cross-town link:
bar width is proportional to bytes moved — the second bar is not a rendering error, it really is that thin.
pitfalls
- "CAP means I permanently sacrifice consistency or availability." Only during an actual partition. The rest of the time, a correctly built system gives you all three, which is most of the time by design.
- "Choosing CP is always the safer choice." CP can mean a real, user-visible outage for exactly the customers caught in the partition. "Safe" against stale data and "safe" against angry customers are different guarantees, and a system can only buy one of them during the gap.
- "Minimising communication always means shipping less data." The 19× ratio above assumes the computation is cheap and the data is not. Flip that — a tiny dataset feeding an enormous model — and shipping the data can beat shipping the computation. Apply the principle to the numbers, not from habit.
Practice
-
Recompute the expected number of stranded orders if Hub S's partition lasted 240 seconds instead of 90.
Solution
0.0252 orders/s × 240s ≈ 6.04, so about 6 orders. The AP/CP trade-off scales directly with outage length: a 90-second gap risking 2 orders is a very different operational conversation from a 4-minute gap risking 6.
-
If the hub-to-central link were upgraded from 2 MB/s to 20 MB/s, recompute both transfer times. Does the 19× conclusion change?
Solution
Move-data time: 17,280 ÷ 20,000,000 = 0.864ms. Move-compute time: 924 ÷ 20,000,000 = 0.046ms. Both times shrink by exactly 10×, but their ratio is still 17,280/924 ≈ 18.7× — unchanged, because bandwidth divides both sides of the ratio equally. The lesson: the "ship compute, not data" conclusion here is about the shape of the two payloads, not about how fast any particular link happens to be.
-
CityCourier later finds that one of the two orders Hub S accepted locally during the outage shares an order ID with one placed through the main app during the same window. What class of problem is this, and roughly how is it normally resolved?
Solution
This is a write conflict created by choosing Availability during a partition — two writes to the same logical record, accepted independently, that now disagree. It is not data loss and not a bug in either hub; it's the expected cost of an AP choice. Resolution typically means detecting the conflict (comparing timestamps, version numbers, or a "last write wins" / application-specific merge rule) and applying a reconciliation rule once the partition heals — the mechanics of exactly how belong to Chapter 2's replication strategies.
-
If Hub S chooses Availability during the partition — serving customers from its own local state without waiting for the central cluster — is it also, implicitly, choosing to move computation to data rather than data to computation? Explain the connection.
Solution
Yes. Choosing Availability requires Hub S to make a decision using only what it has locally, which is only possible if the logic needed to decide (validate an order, compute a price) can run at the hub itself — exactly the "ship the question, not the answer" pattern from Part B. A CP design that insists on checking with the central cluster before responding is, structurally, choosing to ship the request to where the authoritative data lives instead. The CAP choice and the cost-locality choice are two views of the same underlying decision: where does the deciding actually happen?
Should the Dashboard Be Trusted?
A manager's dashboard says "Hub E: fastest average delivery, no action needed." Should CityCourier act on that — and who is responsible if it's wrong?
Every earlier section in this chapter treated the CityCourier log as an engineering object: something to count, route through, architect around, and time. Governance asks a different question of the exact same sixteen rows — not can you compute an answer, but should you act on it, and who answers for it if it turns out to be wrong.
Worked Example · The Ranking That Wasn't Real
Recall order #10 from Section 1.1: Hub E, delivery time logged as −60 seconds. Compute each hub's average delivery time — a completely reasonable thing for a performance dashboard to show — twice: once trusting every value as logged, once applying the same veracity filter from Section 1.1.
raw averages, every value trusted
| rank | hub | avg delivery (s) |
|---|---|---|
| 1st · fastest | Hub E | 561.0 |
| 2nd | Hub N | 682.0 |
| 3rd · slowest | Hub S | 738.0 |
veracity-filtered averages (drop order #10)
| rank | hub | avg delivery (s) |
|---|---|---|
| 1st · fastest | Hub N | 682.0 |
| 2nd | Hub E | 716.25 |
| 3rd · slowest | Hub S | 738.0 |
One corrupted reading — a courier's clock, not even a customer's private data — hands Hub E first place on the raw dashboard. Clean the input and Hub E drops to a distant second; Hub N, never mentioned in the "fastest hub" conversation, was actually fastest all along. If a bonus, a staffing decision, or a public "our fastest hub" press line got attached to the raw number, Section 1.1's veracity bug has quietly become a fairness problem: Hub N's team did the better work and Hub E's team got the credit for it, because nobody checked whether −60 seconds was possible before an average got computed from it.
this is why governance isn't only a legal question
Nothing above required a lawyer, a privacy officer, or a documented policy. It required one validation check — delivery time cannot be negative — running before the number reached a dashboard. Fairness failures this concrete usually start as engineering shortcuts, not as anyone deciding to be unfair.
pitfalls
- "The model never looks at hub name, so it can't be biased by hub." Hub E's raw ranking wasn't produced by anyone typing "favour Hub E" — it fell out of one bad timestamp. A pipeline can be "blind" to every protected attribute and still be unfair, if a fixable data-quality problem happens to help one group and not another.
- "Governance is compliance's job, not engineering's." The actual fix for this section's worked example is a range check at ingestion (Section 1.2) — a few lines of validation code, owned by whoever built the pipeline, not a new policy document.
- "Removing the customer's name makes the data private." A GPS breadcrumb trail that shows the same address every evening at 7pm identifies a person just as effectively as their name would, name field or not. Privacy has to reason about what a combination of fields reveals, not just which fields are labelled "PII."
Practice
-
Using the veracity-filtered table, rank the three hubs from fastest to slowest average delivery.
Solution
Hub N (682.0s) fastest, Hub E (716.25s) second, Hub S (738.0s) slowest.
-
CityCourier's policy is "the slowest hub each week loses its bonus." Compare which hub loses the bonus under the raw numbers versus the veracity-filtered numbers. Which of the two rankings — "fastest" or "slowest" — actually changed once the data was cleaned, and what does that tell you about when a data-quality bug matters most?
Solution
Hub S is slowest under both the raw (738.0) and filtered (738.0) numbers — the bonus-loss decision doesn't change. What changes is who is credited as fastest: Hub E under raw data, Hub N once cleaned. The lesson is specific, not "always recheck everything equally": a data-quality bug matters most exactly where the corrupted record sits — it inflated Hub E's own number, so it distorts comparisons Hub E is party to, and leaves comparisons among the other hubs untouched.
-
Suppose CityCourier automatically flags any courier whose average delivery time exceeds 800 seconds for review. Explain how the same −60-second bug that wrongly crowned Hub E "fastest" could, in a different pipeline, just as easily let a genuinely underperforming courier avoid being flagged at all.
Solution
A large negative value pulls an average down. If that same courier had several legitimately slow deliveries pushing their average toward the 800s threshold, one corrupted −60 reading averaged in alongside them could drag the mean back under 800 and suppress the flag — the identical mechanism that inflated Hub E's ranking here would, for an individual courier, hide a real problem instead of manufacturing a fake one. Section 1.3 made the general point that bad data doesn't bias an aggregate in a fixed direction; this is that same point with a governance consequence attached.
-
Which earlier section's concept is the root cause of this section's ranking flip, and at which of Section 1.2's life-cycle stages should it have been caught?
Solution
Section 1.1's Veracity problem — order #10's physically impossible delivery time — is the entire root cause; nothing in this section introduced a new error, it only showed a consequence of the old one. Per Section 1.2, it should have been caught at Ingest, the last point where a single bad value can be rejected before it is durably stored, replicated, and eventually folded into an aggregate that a real staffing or bonus decision relies on.
Chapter 1, One Page
1.1 · Five V's
Volume data at rest · 16 rows here
Velocity arrival rate · ~42.4s/order
Variety incompatible shapes · 3+ here
Veracity wrong ≠ missing · 18.8% missing, 1 impossible
Value earned by asking a question, never automatic
1.2 · Life Cycle
Generate → Collect → Ingest → Store → Process → Analyze/Visualize → Archive/Purge
Every arrow = a network hop = a chance to lose or duplicate a record
"Delete" is a coordination problem across every replica, not one write
1.3 · Computing Models
Shared-nothing no shared hardware, not "no communication"
MapReduce map (local) → shuffle (network) → reduce, one round
BSP many supersteps, global barrier, vote-to-halt
Graph proc. BSP specialised to "think like a vertex" (Pregel)
Stream unbounded input, windows, never "waits for all data"
1.4 · Architectures
Lambda batch (slow, exact) + speed (fast, approx) + serving (merge)
Kappa one stream path, replay the log to reprocess
Data Lake schema-on-read raw store, sits under either
1.5 · Performance
Speedup(p) = T₁÷Tₖ · Efficiency(p) = Speedup÷p
Utilization = useful work ÷ (p × wall time)
Balance beats headcount — imbalance can make more nodes slower, not faster
1.6 · CAP & Cost
CAP trade-off (CP vs AP) applies only during a partition
Communication is usually the expensive resource — ship compute to data when data >> code
AP choices and "ship compute to data" are the same underlying decision
1.7 · Governance
Fairness · Transparency · Accountability · Privacy/Security · Lifecycle Governance
An unvalidated Veracity bug (1.1) is often a fairness bug in disguise
Anonymized names ≠ private, once other fields can re-identify
Mixed Review
Eight questions, deliberately out of section order — an exam won't tell you which topic it's testing either.
- A distributed store keeps serving reads and writes through a network failure, but two replicas briefly disagree once the failure clears. Which side of the CP/AP choice did it make?
Solution
Availability. It kept answering requests through the partition (never refused or hung) at the cost of a brief consistency gap between replicas — the AP branch of the trade-off in Section 1.6.
- A batch job takes 800ms on one node and 250ms on four. Compute its speedup and efficiency at p=4.
Solution
Speedup = 800/250 = 3.2×. Efficiency = 3.2/4 = 80%.
- A delivery record shows a 5-star rating and a 3-second delivery time for a 40-minute cross-town trip. Is this missing data or wrong data, and which characteristic does it violate?
Solution
Wrong data — every field is populated, but the delivery time is physically implausible. This is a Veracity violation, the same category as CityCourier's order #10.
- Name the two processing layers in a Lambda architecture, and say which one a live dashboard figure is usually reading from first.
Solution
The batch layer (slow, exact) and the speed layer (fast, approximate). A live dashboard reads the speed layer first; the serving layer swaps in the batch layer's corrected number once it's ready.
- In a BSP computation, a vertex receives no message for two consecutive supersteps. What does it do, and what would make it active again?
Solution
It votes to halt and stays idle. It reactivates only if it receives a new message from a neighbour in some later superstep.
- A company strips customer names from a GPS tracking dataset before sharing it with a partner. Is that sufficient for privacy?
Solution
Not necessarily. A repeated location pattern (the same address every evening) can re-identify a person without a name field at all — privacy has to account for what combinations of fields reveal, not just which fields are labelled personal.
- Grouping a thousand (word, count) pairs so every count for the same word reaches the same reducer is which phase of MapReduce?
Solution
Shuffle (with sort) — the one phase that crosses the network, between the local map phase and the local reduce phase.
- A system ships a 50KB scoring model out to where a 50GB dataset lives, instead of shipping the data to a central server. What principle is this, and under what condition would the right choice reverse?
Solution
Moving computation to data (data locality), to minimise communication cost when the data is far larger than the code. It reverses if the computation itself becomes the larger payload — a huge model scoring a tiny dataset is cheaper to run by shipping the small data to the model, not the other way around.
If You Want the Long Version
- Mining of Massive Datasets — Leskovec, Rajaraman & Ullman. The MapReduce and stream-mining chapters go well beyond word count; good next stop after Section 1.3.
- Designing Data-Intensive Applications — Martin Kleppmann. The single best full-length treatment of the CAP theorem and replication trade-offs behind Section 1.6; worth reading before Chapter 2.
- Streaming Systems — Akidau, Chernyak & Lax. Goes deep on exactly the event-time-vs-processing-time questions Section 1.3's tumbling window only touches; essential before Chapter 5.
Chapter 1 of 7 · CSUE301 Big Data Analytics · this is the first chapter, nothing precedes it.
Next → Chapter 2, Distributed Storage Systems (HDFS, NoSQL models, indexing & query execution).