</> MAANG.io

Expert

Design landmark systems in depth, from Dynamo, GFS, Bigtable and Kafka to payments and ads pipelines.

0 of 232 solved 0%

Section 5: A Tree of Tiny Files - Data Modeling

Executive Summary: The whole data model is one record type, the znode: a node in a hierarchical namespace holding a few kilobytes of data and a stat of counters and zxids. Two flags decide its life: ephemeral ties it to a session, and sequential appends an increasing counter. Every state change is stamped with a 64-bit zxid (epoch high, counter low) that puts all writes in one total order. The full tree, about 600 MB in our assumptions, lives in memory on every server, and survives restarts through an fsynced transaction log plus fuzzy snapshots that are safe only because every transaction is idempotent.

The interviewer points at the seven calls from Section 4. "Every one of those takes a path. What's actually at the end of it, and what's on disk when a server reboots?"

You: "A tree of tiny files: a name, a little data and a stat. No lock records, lease records or waiter queues, because Decision 1 put all of that in client recipes."

Znodes: Two Kinds, One Flag

Kind Lives until Children? Used for
Persistent (the 2010 paper calls it regular) an explicit delete yes config, service metadata, the parent directories of recipes
Ephemeral its creating session ends, or an explicit delete no membership, election candidates, lock holders
+ sequential (either kind) as above as above ordering: the server appends a 10-digit counter, unique per parent

Interviewer: "Why can't an ephemeral have children?"

You: "Because a session's death would then cascade through a subtree other sessions wrote into. An ephemeral means one thing: this node exists while that session is alive. Expiry deletes a flat list of nodes, nothing more, which is what makes Section 9's membership and election cheap."

The sequential flag is how the election gets its order. When sch-1, sch-2 and sch-3 each call create("/services/settlement/election/n_", ephemeral|sequential), the server appends the parent's next counter value and returns the real names: n_0000000041, n_0000000042, n_0000000043. The counter belongs to the parent, and in Apache ZooKeeper's implementation it comes from the parent's child-change count, so deletions leave gaps. Recipes compare numbers and never assume they're contiguous.

Here is Sam's corner of the tree:

Sam's corner of the znode tree: the root has services and config; services/settlement/election (persistent) holds three ephemeral sequential children, n_0000000041 for sch-1 (the leader), n_0000000042 for sch-2 and n_0000000043 for sch-3, each watching its predecessor, while config/settlement holds batch-size = 500 at version 7.

The dotted edges are watches, not tree edges; they live in server memory, as we'll see below.

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

Sign in to MAANG.io

Use your Google or Microsoft account — no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.