Track 5: Data Systems at Scale
Building and understanding data systems that handle millions of operations per second. This track covers the fundamental engineering challenge of data-intensive applications: how do you organize, distribute, and access massive datasets when a single machine is not enough? Every decision in this space is a trade-off between read performance, write performance, storage efficiency, and query flexibility.Track Duration: 44-54 hours
Modules: 5
Key Topics: Partitioning, Consistent Hashing, Spanner, Kafka, Stream Processing
Modules: 5
Key Topics: Partitioning, Consistent Hashing, Spanner, Kafka, Stream Processing
Module 22: Partitioning Strategies
Why Partition?
Key-Range Partitioning
Hash Partitioning
Secondary Indexes
order_id (hash partitioning for even distribution). But the “My Orders” page needs to query by user_id, and the admin dashboard needs to query by date_range. With a local secondary index on user_id, the “My Orders” query must scatter-gather across all partitions — at 100 partitions and 5ms per partition, that is 500ms if done sequentially. The solution is either a global index on user_id (fast reads, slower writes) or a denormalized table that is also partitioned by user_id (maintained via Change Data Capture from the primary table). The right choice depends on your read-to-write ratio.
Advanced: Z-Order Curves & Multi-dimensional Partitioning
Standard partitioning (Key-Range or Hash) works well for one-dimensional keys. However, for multi-dimensional data (e.g., searching for users by(latitude, longitude) or (age, income)), a single-key partition leads to expensive “scatter-gather” queries.
Z-Order Curves (Morton Order) map multi-dimensional data into a single dimension while preserving locality.
How it works: Bit Interleaving
To map a 2D point to a 1D Z-value:- Represent and as binary strings.
- Interleave the bits: .
Why it matters for Distributed Systems:
- Locality Preservation: Points that are close in 2D space are usually close on the 1D Z-curve.
- Range Queries: A 2D box query becomes a set of 1D range scans on a standard Key-Range partitioned database (like HBase or Cassandra).
- Used By: Amazon DynamoDB (for Geo-spatial), Uber (H3 is a hexagonal alternative), and many GIS systems.
Module 23: Consistent Hashing
The foundational algorithm for distributed systems. Consistent hashing solves a deceptively simple problem: when you add or remove a server, how do you avoid reshuffling all the data? With naivehash(key) % N, changing N moves almost everything. Consistent hashing arranges servers on a conceptual ring so that adding or removing a server only affects its immediate neighbors — roughly 1/N of the keys move instead of all of them.
The apartment building analogy: Imagine tenants assigned to floors by hashing their name. With regular hashing, adding a floor means everyone moves. With consistent hashing, the new floor only takes tenants from the floor “next to it” on the ring. Everyone else stays put.
Virtual Nodes
Implementation
Alternative: Rendezvous Hashing
Module 24: Distributed Databases Deep Dive
Google Spanner
CockroachDB
Cassandra
When to Use What?
Module 25: Distributed Storage Systems
HDFS / GFS Architecture
Object Storage (S3 Architecture)
Comparison: Replication vs. Erasure Coding
Staff Tip: Erasure coding is best for cold data (infrequently accessed) where storage cost dominates. For hot data, replication is preferred to avoid the CPU and latency penalties of “reconstruction reads.”
Compute/Storage Separation: The Snowflake Model
While Aurora uses “Database-Aware” storage, analytical systems like Snowflake and Google BigQuery use a different pattern: Storage/Compute Separation via Object Storage.1. Decoupled Scaling
- Compute: Stateless “Virtual Warehouses” (clusters of VMs). Can be turned off or scaled to 100 nodes in seconds.
- Storage: Highly durable, cheap Object Storage (S3/Azure Blob/GCS).
2. The Metadata Layer (The “Brain”)
The metadata layer tracks:- Which files (S3 objects) belong to which table.
- Statistics for pruning (min/max values in each file).
- Transactional state (using MVCC).
3. Local Caching
To avoid the latency of S3 on every query, compute nodes use Ephemeral SSDs to cache frequently accessed blocks.- Result: Performance of local disk with the elasticity of the cloud.
Advanced: The Shuffle Problem & Distributed Query Execution
While databases like Spanner handle OLTP (Online Transaction Processing), large-scale analytics (OLAP) systems like Presto/Trino, Spark, and ClickHouse face a different challenge: The Shuffle.1. What is a Shuffle?
A shuffle is the process of redistributing data across a cluster so that all records with the same key end up on the same physical node. This is required for:- Joins: To join Table A and Table B on
user_id, all rows foruser_id=123from both tables must meet on the same node. - Aggregations: To
GROUP BY city, all “NYC” rows must be on one node.
2. The Shuffle Bottleneck
Shuffle is the most expensive operation in distributed systems because it involves:- Network I/O: Moving terabytes of data across the wire.
- Disk I/O: Buffering data to disk if it doesn’t fit in RAM (spilling).
- Serialization: Converting objects to bytes and back.
3. Execution Models: Exchange vs. Push-Based
- Exchange Operators (Volcano Model): Each node pulls data from its predecessors. This is simple but can be slow due to “pull” overhead.
- Push-Based (Vectorized): Modern engines like DuckDB or Photon (Databricks) push batches of data (vectors) through the pipeline, maximizing CPU cache efficiency.
4. Join Strategies
Staff Tip: To optimize distributed queries, your goal is to minimize the shuffle. Use broadcast joins whenever possible, and try to partition your “fact” and “dimension” tables on the same key at the storage level.
Advanced Storage: Storage Engines (LSM-Trees vs. B-Trees)
In distributed databases like Cassandra, RocksDB, and Spanner, the Storage Engine—the part that actually writes to disk—is a critical design choice.1. B-Trees (Read-Optimized)
Standard in RDBMS (Postgres, MySQL).- Structure: Sorted tree of fixed-size blocks (pages).
- Write: Overwrites data in place.
- Pros: Fast, deterministic reads.
- Cons: Write amplification (updating a small row requires writing a full page) and random disk I/O.
2. LSM-Trees (Write-Optimized)
Log-Structured Merge-Trees are used in Cassandra, BigTable, and RocksDB.The LSM Write Path (The “Log” part)
Writes never overwrite data. They are always appended.- WAL (Write Ahead Log): Append-only log for durability.
- Memtable: In-memory sorted buffer (often a Skip List or Red-Black Tree).
- SSTable (Sorted String Table): When the memtable is full, it’s flushed to disk as an immutable sorted file.
The LSM Read Path
- Check the Memtable.
- Check the Bloom Filter (a probabilistic data structure that tells you if a key might exist or definitely doesn’t exist).
- If Bloom filter says “maybe,” check the SSTable Index and read from disk.
Compaction (The “Merge” part)
Since SSTables are immutable, updates/deletes just add more records. Compaction merges these files in the background.Comparison: The Three Amplifications
In Staff-level interviews, you must discuss the RUM Conjecture (Read, Update, Memory):
Staff Tip: If your system has high write volume (e.g., logging, metrics, or a distributed ledger), choose an LSM-Tree. If you need low-latency range reads on a stable dataset, choose a B-Tree.
Advanced: The Bw-Tree & LLAMA (Lock-Free Storage)
For high-concurrency systems (like Microsoft SQL Server’s Hekaton or Azure Cosmos DB), traditional B-Trees suffer from latch contention (locking) and “in-place” update overhead. The Bw-Tree (Buzzword Tree) solves this using a log-structured, lock-free approach.1. The Mapping Table
The core innovation is a Mapping Table that maps a logical Page ID to a physical memory pointer.- Benefit: Instead of updating a page in-place (which requires a lock), you create a new version of the page and update the pointer in the mapping table using a single Atomic CAS (Compare-and-Swap).
2. Delta Records
Instead of rewriting a 4KB page for a 10-byte change, Bw-Tree appends a Delta Record to the existing page.- Chain: A logical page becomes a chain:
[Mapping Table] -> [Delta 2] -> [Delta 1] -> [Base Page]. - Consolidation: When the chain grows too long (e.g., > 8 deltas), a thread “consolidates” them into a new Base Page.
3. LLAMA (Latch-Free, Log-structured Access Method)
LLAMA is the storage subsystem that manages these pages. It ensures that both the in-memory state and the on-disk state are log-structured and latch-free.Advanced: WAL Internals & Zero-Copy I/O
At the “Principal” level, performance is often gated by how fast you can write the Write-Ahead Log (WAL). High-performance logs (like Kafka or Finagle) use OS-level optimizations to bypass the CPU.1. Zero-Copy (sendfile)
In a traditional write, data moves:Disk → Kernel Buffer → App Buffer → Socket Buffer → NIC.
With Zero-Copy (sendfile system call), the data moves: Disk → Kernel Buffer → NIC.
This reduces context switches and memory bus contention, allowing a single node to saturate a 100Gbps link.
2. Group Commit
Instead of callingfsync() for every request (which is slow due to disk head movement), the system buffers multiple writes and performs one large synchronous write.
- Trade-off: Increases latency for individual requests but massively increases total throughput.
3. Direct I/O (O_DIRECT)
Databases like ScyllaDB or Oracle bypass the OS Page Cache entirely.- Why? The OS cache uses LRU (Least Recently Used), but databases often know better (e.g., “I’m doing a sequential scan, don’t cache this”). Direct I/O allows the database to manage its own “Buffer Pool” with domain-specific knowledge.
Module 26: Stream Processing
Kafka Architecture
Kafka Guarantees
Stream Processing Concepts
Handling Late Data (Post-Watermark)
When an event arrives with , it is considered Late. Options:- Drop: Discard the event (standard for real-time dashboards).
- Side Output: Send to a separate “late-events” stream for manual correction.
- Update: Re-calculate the window and emit an updated result (costly).
2. Multi-Range Transactions (Percolator Model)
When a transaction touches keys in multiple ranges (e.g., a bank transfer from User A to User B), the database must coordinate across Raft groups. CockroachDB and TiDB use a variant of Google’s Percolator protocol. The Two-Phase Commit (Simplified):- Prewrite: Write “intent” records (locks) to all involved keys across ranges. The first key is the Primary Lock.
- Commit: If prewrite succeeds, write a commit record to the primary key’s row. Then, asynchronously resolve all other intents.
- Recovery: If a transaction crashes, other transactions can detect stale intents and either roll them forward (if primary is committed) or roll them back.
3. Timestamp Oracle (TSO)
To achieve Serializable Snapshot Isolation (SSI), the database needs globally ordered timestamps. This is handled by a Timestamp Oracle (TSO):- In TiDB, the TSO is a centralized service (Placement Driver).
- In CockroachDB, it’s decentralized using Hybrid Logical Clocks (HLC).
4. Multi-Region SQL
For global deployments, data placement becomes critical for latency.
Staff Tip: For Staff+ interviews, be ready to discuss how these databases handle follower reads (reading from a non-leader replica for lower latency) and the consistency trade-offs involved (stale reads vs. waiting for leader).
Key Interview Questions
Q: How does Google Spanner achieve external consistency?
Q: How does Google Spanner achieve external consistency?
TrueTime + Commit Wait:
-
TrueTime API returns time interval [earliest, latest]
- GPS receivers + atomic clocks
- Uncertainty typically 1-7ms
-
Commit protocol:
- Transaction gets timestamp T at commit
- Wait until TrueTime.after(T) is true
- This ensures T is definitely in the past
- No other transaction can get earlier timestamp
-
Result: If T1 commits before T2 starts:
- T1’s timestamp < T2’s timestamp
- Real-time ordering preserved globally
Q: Design a distributed cache with consistent hashing
Q: Design a distributed cache with consistent hashing
Q: How does Kafka provide exactly-once semantics?
Q: How does Kafka provide exactly-once semantics?
Three mechanisms:
-
Idempotent Producer
- Broker deduplicates by (producer_id, sequence_number)
- Prevents duplicates from retries
-
Transactional Producer
- Atomic writes across partitions
- Uses two-phase commit internally
-
Consumer read_committed
- Only sees committed messages
- Consume → Process → Produce atomically
- Commit consumer offset in same transaction
- If crash, replay from last committed offset
Q: Compare Cassandra vs DynamoDB for a new project
Q: Compare Cassandra vs DynamoDB for a new project
Next Steps
Continue to Track 6: Production Excellence
Learn observability, chaos engineering, and SRE practices