Deep Dives: Reading Order

This directory is the reference core of the curriculum: 21 deep-dive chapters that together explain how Apache Tez turns a DAG object into a distributed computation running across a YARN cluster. Each chapter is self-contained and verified against a real Tez checkout, but they form a dependency graph — read in the order below the first time through, then use this page as a lookup index when you return to fix a bug.

Every chapter follows the same shape: a "what you can do after this" opening, role-based sections that each start with a runnable grep/find, real code excerpts attributed by module + class (never by line number, because code moves between branches), at least one diagram, a reading exercise, a "common bugs and symptoms" table, and a Validation: prove you understand this gate. Treat that gate as the definition of "read."


The system in one picture

A Tez job has four tiers: the client builds a plan and launches an AM; the YARN layer schedules containers; the AM (DAGAppMaster) drives the DAG's state machines and hands work to containers; the tasks run your input/processor/output code and shuffle data between stages.

 ┌───────────────────────────────────────────────────────────────────────┐
 │ CLIENT JVM (tez-api)                                                    │
 │   DAG.create() → verify() → DAGPlan(proto)                             │
 │   TezClient.start() ─────────────► YARN RM: submitApplication          │
 │   TezClient.submitDAG() ──(RPC or staged tez-dag.pb)──► AM             │
 │   DAGClient.getDAGStatus()/waitForCompletion()  ◄── status             │
 └───────────────────────────────────────────────────────────────────────┘
              │ launches                                 ▲ RPC status/kill
              ▼                                          │
 ┌───────────────────────────────────────────────────────────────────────┐
 │ DAGAppMaster JVM (tez-dag)                                              │
 │   DAGClientServer ── AsyncDispatcher (single thread, the only mutation)│
 │        │            ├─ DAGImpl ─ VertexImpl ─ TaskImpl ─ TaskAttemptImpl│
 │        │            ├─ TaskSchedulerManager ─► YARN RM (AMRM heartbeat) │
 │        │            ├─ ContainerLauncherManager ─► YARN NM (launch)     │
 │        │            ├─ TaskCommunicatorManager (umbilical RPC server)   │
 │        │            └─ HistoryEventHandler / RecoveryService (ATS, log) │
 └───────────────────────────────────────────────────────────────────────┘
              │ launches containers                      ▲ umbilical: getTask,
              ▼                                          │ heartbeat, done, events
 ┌───────────────────────────────────────────────────────────────────────┐
 │ TASK CONTAINER JVM (tez-runtime-internals + tez-runtime-library)       │
 │   TezChild → LogicalIOProcessorRuntimeTask                            │
 │   Inputs → Processor → Outputs;  Sorter/IFile → ShuffleManager/Fetcher │
 └───────────────────────────────────────────────────────────────────────┘
flowchart TB
    subgraph Client["Client JVM · tez-api"]
        DAG["DAG / Vertex / Edge"] --> TCL["TezClient"]
        DC["DAGClient (poll/kill)"]
    end
    subgraph YARN["YARN"]
        RM["ResourceManager"]
        NM["NodeManagers"]
    end
    subgraph AM["DAGAppMaster JVM · tez-dag"]
        DISP["AsyncDispatcher"]
        DI["DAGImpl→VertexImpl→TaskImpl→TaskAttemptImpl"]
        SCH["TaskSchedulerManager"]
        CL["ContainerLauncherManager"]
        TCM["TaskCommunicatorManager"]
    end
    subgraph Task["Task container JVM · runtime"]
        RT["LogicalIOProcessorRuntimeTask"]
        IPO["Inputs → Processor → Outputs"]
    end
    TCL -->|submitApplication| RM
    RM -->|launch AM| AM
    TCL -->|submitDAG RPC| DISP
    DISP --> DI
    SCH <-->|AMRM heartbeat| RM
    CL -->|launch container| NM
    NM --> Task
    Task <-->|umbilical| TCM
    DC -->|getDAGStatus / tryKillDAG| DISP

The through-line: events are the only way to mutate AM state, everything the client sees is a snapshot, and every plan is self-sufficient so the AM can run it (or recover it) without calling back to the client. Hold those three ideas and the 21 chapters stop feeling like trivia.


The module map — a maintainer's mental model

Before the chapters, internalize where code lives. These are the Maven modules you will cd into (verified against the checkout's root pom.xml):

ModuleWhat lives hereYou touch it when
tez-apiThe public API and wire format: DAG/Vertex/Edge, all *Descriptors, TezConfiguration, TezClient/DAGClient, the .proto files, serviceplugins/api. No YARN server deps.Adding config, changing the DAG model, evolving the client or a protocol
tez-commonCross-cutting utilities shared by client, AM, and tasks: TezUtils, counters plumbing, reflection, IO helpers.Adding a shared utility; touching counter serialization
tez-dagThe AM: DAGAppMaster, the DAGImpl/VertexImpl/TaskImpl/TaskAttemptImpl state machines, schedulers (rm/), launchers (launcher/), recovery, the runtime dag.impl.Edge. Also LocalClient.90% of AM bugs; scheduling, recovery, lifecycle
tez-runtime-libraryThe pluggable I/O: sorters, IFile, ShuffleManager, Fetcher, MergeManager, the ordered/unordered KV inputs/outputs, built-in VertexManagerPlugins.Shuffle/sort bugs; new edge I/O; partitioners
tez-runtime-internalsThe task-side engine: TezChild, LogicalIOProcessorRuntimeTask, the umbilical client, input/output/processor context impls.How a task actually runs; umbilical issues
tez-mapreduceMapReduce compatibility: MRInput/MROutput, split generation, the mapreduce/mapred shims, MRInputAMSplitGenerator.Reading Hadoop InputFormats; MR-on-Tez
tez-testsIntegration tests and MiniTezCluster: end-to-end jobs, fault injection, TestFaultTolerance.Reproducing cluster behavior; new integration coverage
hadoop-shim (+ hadoop-shim-impls)Version-portable adapters over Hadoop APIs that differ across releases, loaded via HadoopShimsLoader.Supporting a new Hadoop version

Two more you will meet but this section does not cover in depth: tez-plugins (ATS/Timeline history backends, aux shuffle service) and tez-examples (OrderedWordCount and friends, the smallest real DAGs to trace).

Tip: The single most important boundary is tez-api vs tez-dag. The Edge you build (org.apache.tez.dag.api.Edge, tez-api) is a dumb plan record; the Edge that routes events (org.apache.tez.dag.app.dag.impl.Edge, tez-dag) owns the EdgeManager. Same name, different worlds. When a colleague says "look at VertexImpl / Edge / DAG," always ask which module.


Reading order and rationale

Group 1 — The DAG model and the client

These four define "what is a Tez job" and how it is submitted and observed, before any execution machinery. Start here; without the DAG model in your head every later chapter reads as noise.

#FileYou will be able to…Consumed by
1dag-model.mdBuild a DAG by hand; recite the three EdgeProperty enums; predict the EdgeManager; enumerate DAG.verify() checks; explain the DAGPlan protobufLevel 1 (all labs); Level 2 lab 2.1
2logical-physical.mdExplain how a logical DAG gains concrete parallelism at runtime via VertexManagerPluginsLevel 4 lab 4.2; Level 5 lab 5.1
3tez-client.mdTrace create() → start() → submitDAG(); distinguish session/non-session/local; describe the AM launch context and prewarmLevel 3 lab 3.1; Level 7 lab 7.1
4dag-client.mdTell which backend (AM/RM/Timeline) answered a status; explain the long-poll and the source waterfall; use tryKillDAG correctlyLevel 3 lab 3.1; Level 8 lab 8.1

Group 2 — AM lifecycle and dispatch

How the AM comes up and how it mutates state. These must precede every per-entity lifecycle chapter.

#FileYou will be able to…Consumed by
5dag-app-master.mdMap any early AM log line to a method; list the child services and dispatcher registrations; explain recovery on attempt 2; use ServicePluginsDescriptorLevel 3 lab 3.2; Level 8 lab 8.2
6state-machines.mdUse Hadoop's StateMachineFactory; state the dispatcher invariants; write a state-machine testLevel 4 labs 4.1, 4.3, 4.4
7event-routing.mdNavigate the event hierarchy and apply the "events are the only mutation API" ruleLevel 4 (all labs)

Group 3 — Per-entity lifecycle

Read 8 → 9 → 10 in order; each refers back to events (7) and state-machine primitives (6).

#FileYou will be able to…Consumed by
8vertex-lifecycle.mdTrace VertexImpl NEW → SUCCEEDED plus failure/kill pathsLevel 4 lab 4.2
9task-lifecycle.mdExplain TaskImpl, speculation, and max-failed-attemptsLevel 4 lab 4.3
10task-attempt-lifecycle.mdFollow TaskAttemptImpl through container assignment and termination causesLevel 4 lab 4.4; Level 8 lab 8.2

Group 4 — Input / Processor / Output

The code inside the task JVM (tez-runtime-internals + tez-runtime-library).

#FileYou will be able to…Consumed by
11ipo-abstractions.mdImplement LogicalInput/LogicalOutput/Processor; use merged inputsLevel 5 lab 5.1; Level 7 lab 7.1
12tez-runtime.mdExplain LogicalIOProcessorRuntimeTask, TezChild, and the umbilical from the task sideLevel 5 lab 5.1

Group 5 — Shuffle, sort, and counters

#FileYou will be able to…Consumed by
13shuffle-sort.mdWalk sorters, IFile, ShuffleManager, Fetcher, MergeManagerLevel 5 labs 5.2, 5.3
14counters-diagnostics.mdRead/emit TezCounters; understand ATS publication and diagnosticsLevel 8 lab 8.1

Do not debug a shuffle problem without reading 13 cold first.

Group 6 — Scheduling and resources

#FileYou will be able to…Consumed by
15scheduler.mdExplain TaskSchedulerManager, YarnTaskSchedulerService, and AMRM heartbeatsLevel 6 lab 6.2
16container-reuse.mdTrace AMContainerImpl, reuse policy, and idle timeoutsLevel 6 labs 6.1, 6.2
17yarn-integration.mdReason about YARN tokens, the AMRM client, AM failover, and log aggregationLevel 6 lab 6.2

Group 7 — Modes and integrations

#FileYou will be able to…Consumed by
18local-mode.mdDebug a DAG in-process with LocalContainerLauncher, no YARNLevel 2 labs
19hive-integration.mdExplain Hive's TezTask, edge usage, dynamic partition pruning, ATS spansLevel 7 (Hive labs)

Group 8 — Failure, recovery, and testing

#FileYou will be able to…Consumed by
20failure-handling.mdReason about task retry, vertex rerun, AM restart, and recovery recordsLevel 8 lab 8.2
21testing-framework.mdUse MiniTezCluster, MockContainerLauncher, DrainDispatcher, and fault injectionLevel 2 labs; Level 4 labs

Which chapter answers which question

If you are asking…Read
What are the fields of an edge and which EdgeManager gets picked?dag-model.md
Why is my vertex stuck with parallelism -1?dag-model.md, then logical-physical.md
How does a logical vertex get real task counts at runtime?logical-physical.md
Why did start() hang / submitDAG throw SessionNotRunning?tez-client.md
Why does my session AM keep shutting down?tez-client.md, dag-app-master.md
Why is getDAGStatus returning stale/RM-sourced data?dag-client.md
Where do I read counters after the job finished?dag-client.md, counters-diagnostics.md
What services does the AM start, and in what order?dag-app-master.md
How does the AM survive a crash?dag-app-master.md, failure-handling.md
How do I plug in a custom scheduler/launcher/communicator?dag-app-master.md, scheduler.md
How do I write a state-machine transition/test?state-machines.md
What events exist and who may emit them?event-routing.md
Why is a vertex/task/attempt stuck in state X?vertex-lifecycle.md, task-lifecycle.md, task-attempt-lifecycle.md
How do I write an Input/Processor/Output?ipo-abstractions.md
How does a task JVM actually run my processor?tez-runtime.md
Why is shuffle slow / a fetcher failing?shuffle-sort.md
Which counters exist and how are they published?counters-diagnostics.md
Why aren't containers being reused?container-reuse.md, scheduler.md
How do tokens / AM failover / log aggregation work?yarn-integration.md
How do I debug without a cluster?local-mode.md
How does Hive drive Tez?hive-integration.md
How do task retry and vertex rerun decisions get made?failure-handling.md
How do I write a reliable integration/fault test?testing-framework.md

What a maintainer should internalize from each chapter

  • dag-model — the plan is immutable and self-sufficient; verify() is the contract; the two Edge classes.
  • logical-physical — parallelism is often decided in the AM, not the client; VertexManagerPlugins reshape the graph legally.
  • tez-client — three submission paths behind one method; session start() launches the AM, non-session defers it; the IPC-size fallback.
  • dag-client — status is a snapshot with a source; the AM→cache→Timeline→RM waterfall; the server-side long-poll makes waitForCompletion cheap.
  • dag-app-master — the single-threaded dispatcher is the only mutation path; recovery is per-DAG; the scheduler/launcher/communicator are plugins.
  • state-machines / event-routing — every transition is an event; handlers must not block; the state machine is the source of truth.
  • vertex / task / task-attempt lifecycle — the exact states and the legal transitions; where failure and kill diverge.
  • ipo-abstractions / tez-runtime — the task's initialize→start→run→close contract; the umbilical is the task's only line home.
  • shuffle-sort / counters — where bytes and time actually go; how to measure it.
  • scheduler / container-reuse / yarn-integration — how containers are asked for, kept, and reclaimed; the YARN contracts underneath.
  • local-mode / hive-integration — the two most common real-world entry points into Tez.
  • failure-handling / testing-framework — how Tez tolerates faults, and how you prove your change does too.

Order vs index

The deep-dives are an index: they exist to be looked up. Your first pass should follow the groups above. When you return to fix a bug, jump straight to the most relevant chapter and follow its cross-links. Do not skip the Validation section at the end of any chapter — it is the gate before you may claim to have read it, and the difference between "I saw the code" and "I can change the code."