Section 2: Milliseconds and Gigabytes From One Cluster - Requirements (Functional & Non-Functional)
Executive Summary: Section 1 reframed the prompt as a sparse, sorted, versioned map serving two tenants: Webtable, a 20-billion-row crawl that batch jobs scan end to end, and Profiles, a billion users who each need a personalized read in milliseconds. This section turns that into a contract. Functionally: table and family admin, atomic single-row mutations, filtered row reads, range scans, single-row read-modify-write, and MapReduce input and output. Non-functionally: a 10 ms p99 point read, a 20 ms p99 durable write, 14 GB/s of scan bandwidth, 99.99% availability, zero data loss inside a cell, and about 20 seconds to heal after a server dies. The consistency promise is strong but narrow, one row at a time, and the non-goals keep the design that small.
The interviewer leans back. "You've told me what it is. Now tell me what it promises, in numbers I could test, and what it refuses to do."
You: "Three lists: what it does, which I can demo; what it guarantees, which I can measure; and what it won't do, which I can defend. The headline is in the prompt. One cluster has to answer Maya's read in milliseconds and let the indexer pull gigabytes a second."
Functional requirements: the demo list
Shown through the running example rows, com.cnn.www and Maya's 4f9a1c27…:
- Table and family admin: create and delete tables and column families. A family declares its garbage-collection policy (last N versions, or a maximum age), its locality group, and whether that group lives in memory. Webtable's
contents:keeps 3 versions; Profiles'recent:expires after 7 days and is held in memory, whilehistory:expires after 90. - Atomic row mutation: set and delete cells in one row, all or nothing. At 09:00:00 the crawler writes a new ~50 KB
contents:version ofcom.cnn.wwwand setslanguage:to "EN" in a single mutation. At 08:14 Maya's search writesrecent:searchandhistory:searchtogether, so the two families never disagree. - Read a row with filters: fetch one row, restricted by family, qualifier, timestamp range or version count. Maya's next request reads only
recent:; a cached-page view reads only the latestcontents:. - Scan a row range: iterate rows in key order between two keys, with the same filters. The nightly indexer scans
anchor:across every row. This requirement alone is why rows are sorted and hashing is off the table. - Single-row read-modify-write: CheckAndMutate (apply these mutations only if this predicate on the row holds) and atomic increment and append on a cell.
- Bulk load and MapReduce: tables serve as MapReduce input and output, and large datasets load in bulk rather than through millions of single RPCs.
- Access control per family: read and write permissions are set per column family.
Interviewer: "Increments and CheckAndMutate. Isn't that a transaction?"
You: "A transaction scoped to one row, yes. One server owns each row, so it can lock the row and run the check and the write without coordinating with anyone. Put the predicate and the mutation in two rows and I need a distributed commit, which is a non-goal. Section 4 argues it out."
Quick check before moving on:
Sign in to continue reading
The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.
Sign in to read the full lesson