fsimage, edit log and checkpointing

The NameNode answers every request from memory, yet it survives restarts without losing a single file. The trick is an fsimage snapshot plus an edit log of every change since, merged regularly by a checkpoint. In this lesson you read the real metadata files of a running cluster, decode the edit log entries of your own commands, and watch the SecondaryNameNode take a checkpoint, then learn why skipping checkpoints has caused hours-long outages.

Module 5 · HDFS architecture⏱ 26 minIntermediateReal metadata filesoev / oiv dumpsRuns in your browser (Python)8 practice problems
1 The story

A photo and a diary

Kabir lists the NameNode's metadata folder and frowns: fsimage_0000000000000000064, edits_0000000000000000065-0000000000000000066, edits_inprogress_0000000000000000067… “Why so many files with long numbers? And why does it keep changing every two minutes?” Riya has heard that a NameNode once took hours to restart at a big company because “the edits were too big”. Arjun Sir draws two pictures on the board: a photograph, and a diary.

fsimage_…066 photo of the wholenamespace aftertransaction 66 + edits 67 … 73 68 OP_MKDIR …/edits_demo69 OP_ADD …/hello.txt71 OP_RENAME_OLD … = namespace now in NameNode memory checkpoint = new photo Restart = load the newest photo, then replay the diary. A short diary means a fast restart. myphatshala.in
Arjun Sir

The NameNode keeps the whole namespace in memory. To survive a restart it writes two things to disk. The fsimage is a photograph of the entire namespace at one moment. The edit log is a diary: every single change after that moment, each with a transaction number.

Kabir

Why not just update the photo every time something changes?

Arjun Sir

Because the photo can be gigabytes. Rewriting it for every mkdir would be far too slow. Appending one line to the diary is cheap. But the diary grows for ever, and on restart the NameNode must replay all of it. So every so often someone takes a new photo: loads the old photo, applies the diary, saves the result. That's a checkpoint, and it's the SecondaryNameNode's whole job.

Riya

So the SecondaryNameNode isn't a backup NameNode?

Arjun Sir

No. Its name is the most misleading in Hadoop. Today we'll read the diary entries of our own commands and watch a real checkpoint happen.

2 Definition

fsimage, edit log and checkpointing

Formal definition (write this in exams)

The NameNode persists its namespace in two kinds of files in dfs.namenode.name.dir. The fsimage (fsimage_<txid>) is a complete, checkpointed image of the namespace (inodes, directories, permissions, file-to-block lists) as of a given transaction ID. The edit log (edits_<start>-<end> segments and one edits_inprogress_<start>) is a write-ahead log recording every namespace-changing operation (e.g. OP_MKDIR, OP_ADD, OP_CLOSE, OP_RENAME, OP_DELETE) with a transaction ID; an operation is acknowledged only after it is logged. At start-up the NameNode loads the latest fsimage and replays the edits that follow it. Checkpointing merges the fsimage with subsequent edits into a new fsimage, keeping restart time short; it is done by the SecondaryNameNode (non-HA), or the Standby NameNode (HA), or manually with hdfs dfsadmin -saveNamespace. It is triggered every dfs.namenode.checkpoint.period (3600 s) or after dfs.namenode.checkpoint.txns (1,000,000) uncheckpointed transactions, whichever comes first.

In simple words

fsimage = a full photo of all folders and files. Edit log = a diary of every change since that photo. Checkpoint = take a fresh photo so the diary can start again, which makes restarts fast.

Words you'll meet in this lesson

Transaction ID (txid)A number given to every namespace change, increasing by 1 each time.
Edit log segmentA finished edits file covering a range, e.g. edits_…065-…066.
edits_inprogressThe segment currently being written. Exactly one at a time.
seen_txidStart of the current segment; lets the NameNode check no edits are missing at restart.
Checkpointfsimage + edits → new fsimage. Old images and edits are then removed.
RollClosing the in-progress segment and starting a new one (done before each checkpoint).
oiv / oevOffline Image Viewer and Offline Edits Viewer: tools to read fsimage and edits files.
saveNamespaceManual checkpoint by the NameNode itself; requires safe mode.

Checkpoint settings (Hadoop 3.5.0 defaults)

checkpoint.period3600 s: at least one checkpoint per hour (our lab: 120 s)
checkpoint.txns1,000,000 uncheckpointed transactions also trigger one
checkpoint.check.period60 s: how often the checker looks at the transaction count
num.checkpoints.retained2 fsimage files are kept (we saw the oldest removed)
Wheredfs.namenode.name.dir (NameNode), dfs.namenode.checkpoint.dir (SecondaryNameNode: …/dfs/namesecondary)
Web UISecondaryNameNode 9868; the NameNode UI shows “Last Checkpoint Time”

Checkpointing at three levels

Pick your level. New to this? Start at Beginner and climb.

Beginner A bank passbook

  • The bank's yearly statement is the fsimage: your full balance on 31 March.
  • Every deposit and withdrawal after that is a line in the passbook: the edit log.
  • To know today's balance, start from the statement and add every line. If the passbook has 10 lakh lines, that takes long.
  • So the bank prints a fresh statement now and then (a checkpoint) and starts a new passbook.

Intermediate How a checkpoint works (non-HA)

  • The SecondaryNameNode asks the NameNode to roll its edit log: the current segment is closed, a new one starts.
  • It downloads the latest fsimage and the closed edit segments over HTTP.
  • It loads the fsimage into memory, applies the edits, and writes a new fsimage.
  • It uploads the new fsimage to the NameNode, which keeps it and deletes older images and edits beyond the retention limit.
  • The NameNode never stops serving clients during this.

Advanced Production details

  • The SecondaryNameNode needs about as much memory as the NameNode, because it loads the whole namespace.
  • With HA there is no SecondaryNameNode: the Standby NameNode checkpoints, and edits go to JournalNodes (Lesson 7.1).
  • Write metadata to several directories (comma-separated dfs.namenode.name.dir) on different disks; losing all copies of the fsimage and edits loses the file system.
  • If checkpoints silently fail for weeks, edits pile up and the next restart can take hours. Monitor “Last Checkpoint Time” / transactions since checkpoint.
  • Back up the fsimage regularly (it can be fetched with hdfs dfsadmin -fetchImage).

Exam tip: “Explain the role of the SecondaryNameNode”: it is not a standby or backup NameNode. It performs periodic checkpoints: rolls the edit log, downloads fsimage + edits, merges them, and uploads a new fsimage, so that the edit log stays small and the NameNode restarts quickly. Mention the defaults: every 1 hour or 10 lakh transactions.

3 Types and ways to use it

Who can make a checkpoint?

SecondaryNameNodeStandby NameNode (HA)saveNamespaceCheckpoint / Backup node
When usedClusters without HAHA clustersManually, e.g. before maintenanceRarely; older alternatives
HowDownloads image + edits, merges, uploadsAlready has the namespace; saves and uploadsThe NameNode saves its own memory to a new fsimageSimilar to Secondary
NeedsRAM like the NameNodeIs a full NameNodeSafe mode during the save—
Can take over?NoYes (failover)—No

Tools for metadata files

hdfs oiv

Offline Image Viewer: turns an fsimage into text, XML or a delimited table of every path.

fsimage

hdfs oev

Offline Edits Viewer: turns an edits file into XML, one record per operation.

edits

dfsadmin -fetchImage

Downloads the latest fsimage from the NameNode: a simple metadata backup.

Backup

dfsadmin -saveNamespace

Forces a checkpoint on the NameNode (in safe mode).

Manual

Data teams often analyse an oiv dump of a copy of the fsimage (offline, so the NameNode isn't touched) to find who owns the most files, which folders hold millions of small files, and which data hasn't been read for years.

4 Step by step

Read the diary and watch the photos being taken

The Module 5 lab cluster runs a SecondaryNameNode with dfs.namenode.checkpoint.period=120, so a checkpoint happens every 2 minutes instead of every hour.

  1. List the NameNode's metadata files

    docker compose exec namenode ls -l /tmp/hadoop-hadoop/dfs/name/current
    docker compose exec namenode cat /tmp/hadoop-hadoop/dfs/name/current/seen_txid
    -rw-r--r-- 1 hadoop users 4003 Oct 21 06:49 edits_0000000000000000001-0000000000000000044 -rw-r--r-- 1 hadoop users 1920 Oct 21 06:51 edits_0000000000000000045-0000000000000000062 -rw-r--r-- 1 hadoop users 42 Oct 21 06:53 edits_0000000000000000063-0000000000000000064 -rw-r--r-- 1 hadoop users 42 Oct 21 06:55 edits_0000000000000000065-0000000000000000066 -rw-r--r-- 1 hadoop users 1048576 Oct 21 06:55 edits_inprogress_0000000000000000067 -rw-r--r-- 1 hadoop users 1298 Oct 21 06:53 fsimage_0000000000000000064 -rw-r--r-- 1 hadoop users 62 Oct 21 06:53 fsimage_0000000000000000064.md5 -rw-r--r-- 1 hadoop users 1298 Oct 21 06:55 fsimage_0000000000000000066 -rw-r--r-- 1 hadoop users 62 Oct 21 06:55 fsimage_0000000000000000066.md5 -rw-r--r-- 1 hadoop users 3 Oct 21 06:55 seen_txid -rw-r--r-- 1 hadoop users 215 Oct 21 06:48 VERSION 67
    Read the numbers as a timeline: transactions 1–44 (our uploads and jobs), 45–62, … The newest photo is fsimage_…066; everything after transaction 66 is in edits_inprogress_…067, which is pre-allocated as a 1 MB file. A 42-byte segment holds just the start and end markers of an empty segment.
  2. See a checkpoint in the SecondaryNameNode log

    docker compose logs secondarynamenode | grep -iE "checkpoint|Downloaded file|Uploaded image"
    INFO TransferFsImage:177 - Downloaded file edits_tmp_0000000000000000065-0000000000000000066_0000000000000550729 size 0 bytes. INFO Checkpointer:324 - Checkpointer about to load edits from 1 stream(s). INFO Storage:475 - setMostRecentCheckpointInfo txid is 66, time is 1792565757250 INFO TransferFsImage:260 - Uploaded image with txid 66 to namenode at http://namenode:9870 in 0.014 seconds WARN SecondaryNameNode:586 - Checkpoint done. New Image Size: 1298
    Download edits → load → merge → upload fsimage_…066 to the NameNode. (It is logged at WARN level, but it's a normal success message.)
  3. Make some changes, then read the edit log

    docker compose exec namenode hdfs dfs -mkdir data/edits_demo
    docker compose exec namenode hdfs dfs -touchz data/edits_demo/hello.txt
    docker compose exec namenode hdfs dfs -mv data/edits_demo/hello.txt data/edits_demo/namaste.txt
    docker compose exec namenode hdfs dfs -rm -r -skipTrash data/edits_demo
    docker compose exec namenode bash -c 'f=$(ls /tmp/hadoop-hadoop/dfs/name/current/edits_inprogress_*); hdfs oev -i $f -o /tmp/edits.xml; grep -o "<OPCODE>[A-Z_]*</OPCODE>" /tmp/edits.xml | sort | uniq -c'
    1 <OPCODE>OP_ADD</OPCODE> 1 <OPCODE>OP_CLOSE</OPCODE> 1 <OPCODE>OP_DELETE</OPCODE> 1 <OPCODE>OP_MKDIR</OPCODE> 1 <OPCODE>OP_RENAME_OLD</OPCODE> 1 <OPCODE>OP_START_LOG_SEGMENT</OPCODE>
    Four commands, five operations: creating a file is OP_ADD (open) plus OP_CLOSE (finished). The segment always starts with OP_START_LOG_SEGMENT.
  4. Look at one record

    docker compose exec namenode bash -c 'grep -A9 "OP_RENAME" /tmp/edits.xml'
    <OPCODE>OP_RENAME_OLD</OPCODE> <DATA> <TXID>71</TXID> <LENGTH>0</LENGTH> <SRC>/user/hadoop/data/edits_demo/hello.txt</SRC> <DST>/user/hadoop/data/edits_demo/namaste.txt</DST> <TIMESTAMP>1792565829164</TIMESTAMP> <RPC_CLIENTID>52ec91db-a945-4573-8c04-3475b16572cf</RPC_CLIENTID> <RPC_CALLID>3</RPC_CALLID> </DATA>
    Transaction 71: rename hello.txt to namaste.txt. The client ID and call ID let the NameNode recognise a retried request after a failover and not apply it twice.
  5. Force a checkpoint with saveNamespace

    docker compose exec namenode hdfs dfsadmin -safemode enter
    docker compose exec namenode hdfs dfsadmin -saveNamespace
    docker compose exec namenode hdfs dfsadmin -safemode leave
    docker compose exec namenode ls -l /tmp/hadoop-hadoop/dfs/name/current
    Safe mode is ON Save namespace successful Safe mode is OFF -rw-r--r-- 1 hadoop users 4003 Oct 21 06:49 edits_0000000000000000001-0000000000000000044 -rw-r--r-- 1 hadoop users 1920 Oct 21 06:51 edits_0000000000000000045-0000000000000000062 -rw-r--r-- 1 hadoop users 42 Oct 21 06:53 edits_0000000000000000063-0000000000000000064 -rw-r--r-- 1 hadoop users 42 Oct 21 06:55 edits_0000000000000000065-0000000000000000066 -rw-r--r-- 1 hadoop users 652 Oct 21 06:57 edits_0000000000000000067-0000000000000000073 -rw-r--r-- 1 hadoop users 1048576 Oct 21 06:57 edits_inprogress_0000000000000000074 -rw-r--r-- 1 hadoop users 1298 Oct 21 06:55 fsimage_0000000000000000066 -rw-r--r-- 1 hadoop users 62 Oct 21 06:55 fsimage_0000000000000000066.md5 -rw-r--r-- 1 hadoop users 1298 Oct 21 06:57 fsimage_0000000000000000073 -rw-r--r-- 1 hadoop users 62 Oct 21 06:57 fsimage_0000000000000000073.md5 -rw-r--r-- 1 hadoop users 3 Oct 21 06:57 seen_txid -rw-r--r-- 1 hadoop users 215 Oct 21 06:57 VERSION
    Our 5 operations (plus segment markers) became segment 67–73, a new photo fsimage_…073 was written, and fsimage_…064 was deleted: only 2 images are retained. The in-progress segment restarted at 74.
  6. Read the photo

    docker compose exec namenode bash -c 'hdfs oiv -p Delimited -i /tmp/hadoop-hadoop/dfs/name/current/fsimage_0000000000000000073 -o /tmp/fsimage.tsv; cut -f1,2,4,7 /tmp/fsimage.tsv'
    Path Replication AccessTime FileSize / 0 1970-01-01 00:00 0 /user 0 1970-01-01 00:00 0 /user/hadoop 0 1970-01-01 00:00 0 /user/hadoop/data 0 1970-01-01 00:00 0 /user/hadoop/data/canteen_orders.csv 3 2026-10-21 06:49 4692009 /user/hadoop/data/canteen_1mb.csv 3 2026-10-21 06:49 4692009 /user/hadoop/out 0 1970-01-01 00:00 0 /user/hadoop/out/wc1 0 1970-01-01 00:00 0 /user/hadoop/out/wc1/part-r-00000 3 2026-10-21 06:49 4942122 /user/hadoop/out/wc1/_SUCCESS 3 2026-10-21 06:49 0 /user/hadoop/out/wc128 0 1970-01-01 00:00 0 /user/hadoop/out/wc128/part-r-00000 3 2026-10-21 06:49 4942122 /user/hadoop/out/wc128/_SUCCESS 3 2026-10-21 06:49 0
    The whole namespace: 13 inodes in a 1,298-byte file. edits_demo is not there: it was created and deleted before the photo, so it exists only in the diary. Directories show replication 0. (The column header comes from the tool; the selected columns are path, replication, access time and size.)

Never delete files from the NameNode's metadata folder to “save space”. The NameNode cleans up old images and edits itself. Missing edits make the namespace impossible to rebuild.

5 See it happen

One checkpoint, step by step

The real file names from the lab, around the checkpoint at transaction 66.

SecondaryNameNode checkpoint 6 steps
What you see namenode : dfs/name/current fsimage_…064edits_inprogress_…065← 65, 66 … (no changes in these 2 minutes: txid 65 = start, 66 = end of segment) fsimage_…064edits_…065-…066edits_inprogress_…067 2NN: rollEditLog 2NN: Downloaded file edits_tmp_…065-…0662NN: about to load edits from 1 stream fsimage_…066 Uploaded image with txid 66 to namenodeCheckpoint done. New Image Size: 1298 restart: load fsimage_…066 + replay edits from 67 myphatshala.in
Behind the screen NameNode SecondaryNameNode memory: namespace edits_inprogress 65… changes (if any) logged first, then applied edits 65–66 (closed)edits_inprogress 67… 1. “roll your edit log” fsimage_064 + edits 65–662. download over HTTP, load, merge in memory fsimage_066 (new) 3. upload the new image to the NameNode fsimage_066 restart = fsimage_066 + edits from 67the diary to replay stays short the SecondaryNameNode waits for its next turn myphatshala.in
6 Real-world use

Metadata files in production

no checkpointfor 3 weeks

1. The slow-restart incident

A classic outage: checkpoints fail silently (a misconfigured or dead SecondaryNameNode), edits grow to crores of transactions, and the next NameNode restart takes hours of replay. Monitoring the time since the last checkpoint prevents it.

Checkpoint fails→Edits pile up→Hours to restart
oiv dumpwho uses what

2. Storage reports from the fsimage

Platform teams fetch the fsimage daily, convert it with oiv, and load it into Hive or Spark to report file counts and sizes per team, small-file hotspots and stale data, all without querying the live NameNode.

fetchImage→oiv → table→Usage dashboard
2 disks + NFSname.dir

3. Several copies of the metadata

Before HA was common, admins listed two local disks and an NFS mount in dfs.namenode.name.dir, so a disk failure couldn't destroy the only fsimage and edits. With HA, JournalNodes keep the edit log on several machines.

Every edit→Written to all dirs→Survives a disk
saveNamespacebefore upgrade

4. Clean checkpoint before maintenance

Before a planned restart or upgrade, admins enter safe mode and run saveNamespace so the NameNode comes back with almost nothing to replay, and they keep a copy of that fsimage as a rollback point.

Safe mode→saveNamespace→Fast, safe restart

Simplified; organisations differ in tools and policies.

7 Run the code

Rebuild a namespace from a photo and a diary

This program does what a NameNode does at start-up: load the fsimage (a dictionary of paths), then replay each edit after it, in transaction order. The edits are the five real operations from Part 4.

fsimage_txid = 66
fsimage = {"/user/hadoop/data": "dir",
           "/user/hadoop/data/canteen_orders.csv": "file"}
edits = [
    (68, "OP_MKDIR", "/user/hadoop/data/edits_demo", None),
    (69, "OP_ADD", "/user/hadoop/data/edits_demo/hello.txt", None),
    (70, "OP_CLOSE", "/user/hadoop/data/edits_demo/hello.txt", None),
    (71, "OP_RENAME_OLD", "/user/hadoop/data/edits_demo/hello.txt",
         "/user/hadoop/data/edits_demo/namaste.txt"),
    (72, "OP_DELETE", "/user/hadoop/data/edits_demo", None),
]

ns = dict(fsimage)
for txid, op, path, dst in edits:
    if txid <= fsimage_txid:
        continue
    if op == "OP_MKDIR":
        ns[path] = "dir"
    elif op == "OP_ADD":
        ns[path] = "file (open)"
    elif op == "OP_CLOSE":
        ns[path] = "file"
    elif op == "OP_RENAME_OLD":
        ns[dst] = ns.pop(path)
    elif op == "OP_DELETE":
        ns = {p: k for p, k in ns.items() if p != path and not p.startswith(path + "/")}
    print(f"txid {txid}: {op:14} -> {len(ns)} paths")
print(sorted(ns))
txid 68: OP_MKDIR -> 3 paths txid 69: OP_ADD -> 4 paths txid 70: OP_CLOSE -> 4 paths txid 71: OP_RENAME_OLD -> 4 paths txid 72: OP_DELETE -> 2 paths ['/user/hadoop/data', '/user/hadoop/data/canteen_orders.csv']
  • if txid <= fsimage_txid:Edits already contained in the fsimage are skipped. Only transactions after the image's txid are replayed.
  • ns[path] = "file (open)"OP_ADD creates the file while it is being written; OP_CLOSE marks it complete.
  • ns = {p: k for p, k in ns.items() if p != path and not p.startswith(path + "/")}Deleting a directory removes everything below it too.

Run it on your PC: watch your commands land in the edit log

This script makes four changes in HDFS, then decodes the newest edit log segments with hdfs oev and prints only the transactions your commands created. Save it as edit_log_report.py in the hdfs-lab folder and run it while the cluster is up.

Your commands, as NameNode transactions

# edit_log_report.py: make a few changes in HDFS, then read them back from the NameNode's edit log.
# Run in the hdfs-lab folder while the cluster is up.
import json
import subprocess
import xml.etree.ElementTree as ET

NAME_DIR = "/tmp/hadoop-hadoop/dfs/name/current"

def nn(*cmd):
    return subprocess.run(["docker", "compose", "exec", "-T", "namenode", *cmd],
                          capture_output=True, text=True).stdout

def last_txid():
    url = "http://namenode:9870/jmx?qry=Hadoop:service=NameNode,name=NameNodeInfo"
    info = json.loads(json.loads(nn("curl", "-s", url))["beans"][0]["JournalTransactionInfo"])
    return int(info["LastAppliedOrWrittenTxId"])

before = last_txid()
print("last transaction before our changes:", before)
for cmd in (["hdfs", "dfs", "-mkdir", "-p", "data/demo"],
            ["hdfs", "dfs", "-touchz", "data/demo/order.txt"],
            ["hdfs", "dfs", "-mv", "data/demo/order.txt", "data/demo/order_old.txt"],
            ["hdfs", "dfs", "-rm", "-r", "-skipTrash", "data/demo"]):
    nn(*cmd)

# a checkpoint may have closed the segment meanwhile, so read the newest two edit files
files = nn("bash", "-c", f"ls {NAME_DIR} | grep ^edits_ | tail -2").split()
for f in files:
    nn("hdfs", "oev", "-i", f"{NAME_DIR}/{f}", "-o", "/tmp/edits.xml")
    for rec in ET.fromstring(nn("cat", "/tmp/edits.xml")).iter("RECORD"):
        data = rec.find("DATA")
        txid = int(data.findtext("TXID"))
        path = data.findtext("PATH") or data.findtext("SRC") or ""
        dst = data.findtext("DST")
        if txid > before and path:
            print(f"txid {txid:>4}  {rec.findtext('OPCODE'):15} {path}"
                  + (f" -> {dst}" if dst else "") + f"   [{f}]")

# In the hdfs-lab folder:
#   python3 edit_log_report.py
last transaction before our changes: 109 txid 110 OP_MKDIR /user/hadoop/data/demo [edits_inprogress_0000000000000000099] txid 111 OP_ADD /user/hadoop/data/demo/order.txt [edits_inprogress_0000000000000000099] txid 112 OP_CLOSE /user/hadoop/data/demo/order.txt [edits_inprogress_0000000000000000099] txid 113 OP_RENAME_OLD /user/hadoop/data/demo/order.txt -> /user/hadoop/data/demo/order_old.txt [edits_inprogress_0000000000000000099] txid 114 OP_DELETE /user/hadoop/data/demo [edits_inprogress_0000000000000000099]

Real output. The script reads the last transaction ID from the NameNode's /jmx first, so it shows only new entries. Run it twice: the transaction numbers keep growing, and after a checkpoint the entries move from the in-progress file to a closed segment.

8 Line by line

A checkpoint, one line at a time

Follow the SecondaryNameNode: it loads the old image, applies only newer edits, and produces an image with a new transaction ID.

Worked examples: real problems, solved and traced in memory

Three checkpoint calculations that matter in operations: how fast edits accumulate, how long a restart would take right now, and whether metadata storage is safe. Each runs live and is traced in memory.

Example 1BeginnerOperations · rate

How many edits per day?

Problem statement

A cluster's jobs create 30 lakh files a day (each create is OP_ADD + OP_CLOSE plus a few block allocations, about 5 transactions in total) and delete as many. Deleting is one transaction per path. How many transactions per day, and how often is the 10 lakh-transaction checkpoint trigger reached?

Input
30,00,000 creates × 5 tx · 30,00,000 deletes × 1 tx · trigger 10,00,000
Expected output
18,000,000 transactions/day -> count trigger 18 times/day, time trigger 24 times/day

Approach

  1. Transactions = creates × 5 + deletes × 1.
  2. Checkpoints by count = transactions / 10 lakh.
  3. Compare with the hourly trigger (24 a day).

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.

Example 2IntermediateOperations · restart

How long would a restart take now?

Problem statement

The last successful checkpoint was 9 days ago (it has been failing silently). The cluster logs 2 crore transactions a day. Loading the fsimage takes 4 minutes and replay runs at 60,000 transactions per second. Estimate the restart time, then the time if checkpoints were working (at most 10 lakh edits).

Input
9 days × 2 crore tx · load 4 min · 60,000 tx/s
Expected output
broken checkpoints  :   180,000,000 edits ->     54 min
healthy             :     1,000,000 edits ->      4 min

Approach

  1. Edits to replay = days × daily transactions.
  2. Restart = load + edits / rate.
  3. Compare with the healthy case.

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.

Example 3AdvancedAdmin · resilience

Check the metadata directories

Problem statement

Write a checker for dfs.namenode.name.dir: warn if there is only one directory, if two directories are on the same disk, or if any is under /tmp.

Input
"file:///data/1/nn,file:///data/1/nn-copy,file:///tmp/nn" · disks: /data/1, /tmp
Expected output
['/data/1/nn', '/data/1/nn-copy', '/tmp/nn']
several directories on the same disk
/tmp/nn is under /tmp

Approach

  1. Split the comma-separated value.
  2. Map each path to its disk (mount point).
  3. Apply the three checks.

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.

9 Quiz and revision

Check yourself

Quick revision

Lesson 5.4 in one screen

  • fsimage_N = full namespace after transaction N. edits = every change after it (write-ahead log).
  • Files: edits_A-B (closed), edits_inprogress_N (current), seen_txid, VERSION.
  • Ops: OP_MKDIR, OP_ADD + OP_CLOSE (create), OP_RENAME(_OLD), OP_DELETE, plus segment start/end markers.
  • Start-up = load latest fsimage + replay newer edits (+ wait for block reports).
  • Checkpoint: roll edits → download → merge → upload new fsimage. Every 1 h or 10 lakh tx.
  • Done by SecondaryNameNode (non-HA) or Standby NameNode (HA); manually with -saveNamespace (safe mode).
  • SecondaryNameNode is not a backup NameNode. 2 images retained by default.
  • Tools: hdfs oiv (fsimage), hdfs oev (edits), dfsadmin -fetchImage (backup).

Interview and viva questions

What are fsimage and edit log in HDFS?

The fsimage is a persistent snapshot of the entire file system namespace at a certain transaction ID. The edit log records every change made after that snapshot. Together they let the NameNode rebuild its in-memory namespace after a restart.

What is checkpointing in HDFS?

Merging the latest fsimage with the edit log that follows it to produce a new fsimage, so that the edit log stays short and restarts are fast. It is done periodically by the SecondaryNameNode (or Standby NameNode in HA).

Is the SecondaryNameNode a backup of the NameNode?

No. It only creates checkpoints. If the NameNode fails, the SecondaryNameNode cannot serve clients. Its latest checkpoint can help recover metadata, but it may be missing recent edits. Automatic takeover requires HA with a Standby NameNode.

How often does a checkpoint happen?

By default every 3600 seconds (dfs.namenode.checkpoint.period) or when 1,000,000 transactions have accumulated (dfs.namenode.checkpoint.txns), whichever comes first. The SecondaryNameNode checks the transaction count every 60 seconds.

Does the fsimage contain block locations?

No. It contains each file's list of blocks but not which DataNodes hold them. Locations come from DataNode block reports after start-up.

How can I read an fsimage or edits file?

With the offline viewers: hdfs oiv -p XML|Delimited -i fsimage_N -o out for images, and hdfs oev -i edits_file -o out.xml for edit logs. Run them on copies, not on files the NameNode is using.

What happens if the edit log is lost?

All namespace changes since the last checkpoint are lost: files created or renamed after it disappear from the namespace, even though their blocks may still be on DataNodes. That is why edits are written to several directories or JournalNodes.

Practice problems

Exercises on transactions, checkpoint timing and metadata files, using real file names from the lab.

P1Easy

Transactions in a segment

How many transactions does edits_0000000000000000045-0000000000000000062 contain?

Input
45 to 62
Expected output
18
Show solution and explanation
print(62 - 45 + 1)
18

How it works: 18 transactions (both ends included).

P2Easy

Newest image

Given the image files fsimage_…064, fsimage_…066 and fsimage_…073, which one will the NameNode load at restart?

Input
064 · 066 · 073
Expected output
fsimage_0000000000000000073
Show solution and explanation
print("fsimage_%019d" % max([64, 66, 73]))
fsimage_0000000000000000073

How it works: fsimage_0000000000000000073, the highest transaction ID.

P3Easy

Operations per create

Creating one empty file produced OP_ADD and OP_CLOSE. How many transactions for 1,000 empty files?

Input
1,000 files · 2 ops each
Expected output
2000
Show solution and explanation
print(1000 * 2)
2000

How it works: 2,000 transactions. Files with data also log block allocations.

P4Medium

Which edits to replay?

The newest fsimage is at txid 73 and the edit segments are 1-44, 45-62, 63-64, 65-66, 67-73 and in-progress from 74 (now at 81). Which transactions are replayed at restart?

Input
image 73 · segments … · in-progress 74–81
Expected output
[(74, 81)] -> 8 transactions
Show solution and explanation
image = 73
segments = [(1, 44), (45, 62), (63, 64), (65, 66), (67, 73), (74, 81)]
replay = [s for s in segments if s[1] > image]
print(replay, "->", sum(b - max(a, image + 1) + 1 for a, b in replay), "transactions")
[(74, 81)] -> 8 transactions

How it works: Only segment 74–81: 8 transactions. Everything up to 73 is already in the image.

P5Medium

Retention

With num.checkpoints.retained = 2, which fsimage files remain after images at txids 64, 66 and 73 have been written?

Input
64 · 66 · 73 · retain 2
Expected output
[66, 73]
Show solution and explanation
print(sorted([64, 66, 73])[-2:])
[66, 73]

How it works: [66, 73]: exactly what the folder listing showed after saveNamespace (064 was removed).

P6Medium

Checkpoint trigger

The cluster logs 250 transactions per second. Will the time (3600 s) or count (10 lakh) trigger fire first, and after how long?

Input
250 tx/s
Expected output
time trigger after 3600 s
Show solution and explanation
t = 1_000_000 / 250
print("count" if t < 3600 else "time", "trigger after", min(t, 3600), "s")
time trigger after 3600 s

How it works: Time: 10 lakh transactions would take 4,000 s at 250/s, so the hourly time trigger (3,600 s) fires first.

P7Business problem

Cost of a slow restart

A restart with a huge edit log takes 3 hours instead of 10 minutes. 400 analysts each lose Rs 1,200 of work per hour of downtime. What does the extra time cost?

Input
170 extra minutes · 400 people · Rs 1,200/h
Expected output
Rs 13.6 lakh
Show solution and explanation
extra_h = (180 - 10) / 60
print(f"Rs {extra_h * 400 * 1200 / 1e5:.1f} lakh")
Rs 13.6 lakh

How it works: About Rs 13.6 lakh for one restart, more than the cost of monitoring checkpoints for years.

P8Advanced

Detect a stuck checkpoint

Given (time, last checkpoint txid, current txid) samples, alert if the checkpoint txid has not changed for more than 2 hours while transactions keep increasing.

Input
samples every hour
Expected output
ALERT: no checkpoint for 3 h, 3,499,500 edits pending
Show solution and explanation
samples = [(0, 500, 900), (1, 500, 1_200_000), (2, 500, 2_400_000), (3, 500, 3_500_000)]
first = next(t for t, cp, cur in samples if cp == samples[-1][1])
t_now, cp, cur = samples[-1]
if t_now - first > 2 and cur > cp:
    print(f"ALERT: no checkpoint for {t_now - first} h, {cur - cp:,} edits pending")
ALERT: no checkpoint for 3 h, 3,499,500 edits pending

How it works: The checkpoint txid has been stuck at 500 for 3 hours while 35 lakh edits accumulated: the SecondaryNameNode is failing.

Real-world scenario questions (asked in company interviews)

Interviewers love the SecondaryNameNode because its name misleads so many candidates.

HDFS · conceptsFresher

“The NameNode crashed. Can the SecondaryNameNode take over?”

A very common trick question.

The interviewer is checking: that you know what the SecondaryNameNode actually does.

Show a strong answer
  • No. The SecondaryNameNode only merges the fsimage and edit log into checkpoints; it never serves clients.
  • Restart the NameNode (it loads its fsimage + edits). If its metadata disks are lost, the SecondaryNameNode's latest checkpoint can be used to recover, losing edits since that checkpoint.
  • Automatic takeover needs HA: an active and a standby NameNode with shared edits on JournalNodes.
Operations · incidentExperienced

The NameNode has been “starting” for two hours

After a planned restart the NameNode UI shows Startup Progress stuck in “Loading edits”.

The interviewer is checking: root cause and prevention.

Show a strong answer
  • It is replaying a very large edit log, which means checkpoints haven't been happening. Check the SecondaryNameNode/Standby logs and the last checkpoint time.
  • Let it finish (interrupting makes it start again). Afterwards fix the checkpoint process: memory, connectivity on port 9868/9870, disk space for checkpoint.dir.
  • Prevent: alert on time and transactions since the last checkpoint; before planned restarts run saveNamespace in safe mode.
Design · durabilityExperienced

Why is every change written to the edit log before it's acknowledged?

An interviewer asks why the NameNode doesn't just update memory and write a snapshot every minute.

The interviewer is checking: write-ahead logging.

Show a strong answer
  • Memory is lost on a crash. If changes were only in memory, a crash would forget every file created since the last snapshot, even though clients were told “success”.
  • Appending a small record to a log (and syncing it) is cheap; rewriting a multi-GB image is not. So: log first, then apply, then acknowledge.
  • Snapshots (checkpoints) only exist to keep the log short. Databases use the same idea (write-ahead log + checkpoints).
Analytics · metadataFresher

Find the folders with the most small files, without slowing the NameNode

A manager wants a report of small files per team across a 40-crore-file namespace.

The interviewer is checking: that you know the offline fsimage approach.

Show a strong answer
  • Running hdfs dfs -ls -R or -count over everything would load the NameNode heavily.
  • Instead download the latest image (hdfs dfsadmin -fetchImage), convert it with hdfs oiv -p Delimited, and analyse the table with Hive or Spark: count files under 1 MB per top-level folder or owner.
  • Schedule it daily to track progress.