YARN Integration
The Tez AM is, from YARN's perspective, an ordinary YARN application: an ApplicationMaster running in a container, talking to the ResourceManager to request more containers, talking to NodeManagers to launch them, and (when configured) publishing events to a Timeline Server. Nothing about Tez is special to YARN — which is exactly why so many "Tez won't start" and "tasks can't fetch" problems are really YARN-deployment problems wearing a Tez stack trace.
This chapter walks every YARN-facing interface Tez touches, quoting the real
classes from your Tez checkout at ~/tez-src. All commands run from the Tez
repo root and are verified against current master. Where a class name
matters for grep, it is given by module path plus class, never by line
number.
After this chapter you can:
- Trace the AM boot path from a YARN-launched container to
AMRMClientAsync.registerApplicationMaster. - Name the client (
TezYarnClient) that submits the app and the classes that build the AM'sContainerLaunchContext. - Read the
YarnTaskSchedulerServiceallocate/heartbeat/callback loop. - Explain how Tez reacts to preemption, disk failure, node loss, and RM errors — by pointing at the real handler in each case.
- Deploy the
tez_shuffleaux-service and reason about token flow.
This chapter pairs with three siblings: Scheduler (how the AM decides what to ask YARN for), Container Reuse (why the AM holds containers instead of releasing them), and Failure Handling (the state-machine reactions to the YARN events described here).
Two YARN roles: the client and the AM
Tez talks to YARN from two processes, and they use different clients:
| Process | Client | Class (module) | Role |
|---|---|---|---|
| Submitting client | TezYarnClient (wraps YarnClient) | org.apache.tez.client.TezYarnClient (tez-api) | Submit the AM application, poll app report, kill app |
| AM | AMRMClientAsync via TezAMRMClientAsync | org.apache.tez.dag.app.rm.YarnTaskSchedulerService (tez-dag) | Register, request/release containers, heartbeat |
| AM | ContainerManagementProtocolProxy | org.apache.tez.dag.app.launcher.TezContainerLauncherImpl (tez-dag) | Launch/stop containers on NMs |
Confirm the client wrapper — TezYarnClient extends FrameworkClient and
holds a YarnClient:
grep -n "class TezYarnClient\|private final YarnClient\|submitApplication\|createApplication\|killApplication" \
tez-api/src/main/java/org/apache/tez/client/TezYarnClient.java
FrameworkClient is the abstraction that lets Tez also run against a local
or alternate runtime; TezYarnClient is the YARN implementation and simply
delegates to YarnClient.submitApplication, getApplicationReport,
killApplication.
Building the AM: TezClientUtils
Before the app is submitted, the client assembles everything YARN needs
to launch the AM container. This is TezClientUtils in tez-api
(org.apache.tez.client.TezClientUtils).
grep -n "createApplicationSubmissionContext\|ensureStagingDirExists\|setupTezJarsLocalResources\|setupDAGCredentials\|createSessionToken" \
tez-api/src/main/java/org/apache/tez/client/TezClientUtils.java
The staging directory comes first (ensureStagingDirExists), keyed on
tez.staging-dir (TEZ_AM_STAGING_DIR). Tez localizes the framework
tarball from tez.lib.uris (TEZ_LIB_URIS) into per-app local resources
via setupTezJarsLocalResources, and stages the serialized DAG plan
(TEZ_PB_PLAN_BINARY_NAME) as an application-visibility LocalResource.
The environment (CLASSPATH, etc.) is assembled by
TezYARNUtils.setupDefaultEnv (tez-api,
org.apache.tez.common.TezYARNUtils), whose classpath comes from
getFrameworkClasspath:
grep -n "setupDefaultEnv\|getFrameworkClasspath" \
tez-api/src/main/java/org/apache/tez/common/TezYARNUtils.java
The AM command line is built in TezClientUtils and ends in the AM main
class constant TezConstants.TEZ_APPLICATION_MASTER_CLASS
(org.apache.tez.dag.app.DAGAppMaster); for session mode it adds the
--session CLI option, and it appends the standard YARN stdout/stderr log
redirections:
grep -n "TEZ_APPLICATION_MASTER_CLASS\|TEZ_SESSION_MODE_CLI_OPTION\|LOG_DIR_EXPANSION_VAR" \
tez-api/src/main/java/org/apache/tez/client/TezClientUtils.java \
tez-api/src/main/java/org/apache/tez/dag/api/TezConstants.java
The AM ContainerLaunchContext
The CLC is what the NM uses to fork the AM JVM. It is built at the end of
createApplicationSubmissionContext with
ContainerLaunchContext.newInstance(amLocalResources, environment, vargsFinal, serviceData, securityTokens, acls). Its fields:
| Field | What Tez puts there |
|---|---|
commands | $JAVA_HOME/bin/java <opts> org.apache.tez.dag.app.DAGAppMaster [--session] 1>.../stdout 2>.../stderr |
environment | CLASSPATH (framework classpath), plus user AM env |
localResources | Tez tarball (tez.lib.uris), the serialized DAG plan, user resources |
tokens | Delegation tokens collected via TokenCache (HDFS, timeline, etc.) |
serviceData | Under the shuffle aux-service key: the serialized session JobToken |
acls | View/modify ACLs for the app |
The serviceData entry is the subtle one. From TezClientUtils
(org.apache.tez.client.TezClientUtils, method
createApplicationSubmissionContext):
Map<String, ByteBuffer> serviceData = new HashMap<String, ByteBuffer>();
String auxiliaryService = conf.get(TezConfiguration.TEZ_AM_SHUFFLE_AUXILIARY_SERVICE_ID,
TezConfiguration.TEZ_AM_SHUFFLE_AUXILIARY_SERVICE_ID_DEFAULT);
serviceData.put(auxiliaryService,
TezCommonUtils.serializeServiceData(TokenCache.getSessionToken(amLaunchCredentials)));
The comment right above it in the source explains why the AM needs a
shuffle token: tasks can run inside the AM container, and the NM's shuffle
aux-service on the AM's node must be able to authorize fetches against it.
The same shuffle-token-in-serviceData pattern is used for every task
container — built in AMContainerHelpers.createCommonContainerLaunchContext
(tez-dag, org.apache.tez.dag.app.rm.container.AMContainerHelpers):
grep -n "serviceData\|auxiliaryService\|createCommonContainerLaunchContext" \
tez-dag/src/main/java/org/apache/tez/dag/app/rm/container/AMContainerHelpers.java
AM boot: DAGAppMaster as a YARN AM
find tez-dag/src/main/java -name "DAGAppMaster.java"
grep -n "public static void main\|serviceInit\|serviceStart" \
tez-dag/src/main/java/org/apache/tez/dag/app/DAGAppMaster.java | head
Boot sequence when YARN launches the AM container:
- NodeManager runs the command line built by
TezClientUtils, i.e.java ... org.apache.tez.dag.app.DAGAppMaster. DAGAppMaster.mainreadsApplicationAttemptId, container ID, AMResource, and the NM host/port from the container environment YARN injects.- It constructs the service tree — dispatchers, state machines, the
TaskSchedulerManager, theContainerLauncherManager, and the history (ATS) service — viaserviceInit. serviceStartbrings up the client RPC server and, throughTaskSchedulerManager, registers with the RM.- In session mode it waits for DAG submissions over RPC; in non-session mode it picks up the single pre-submitted DAG.
The scheduler is not created directly by DAGAppMaster; it is instantiated
by TaskSchedulerManager.instantiateSchedulers, which is what actually
registers the AM with the RM. Follow the chain:
grep -n "instantiateSchedulers\|registerApplicationMaster" \
tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java
Which scheduler class is instantiated is configurable. The default is
DagAwareYarnTaskScheduler (tez.am.yarn.scheduler.class /
TEZ_AM_YARN_SCHEDULER_CLASS), with YarnTaskSchedulerService as the
classic alternative — both implement AMRMClientAsync.CallbackHandler:
grep -n "TEZ_AM_YARN_SCHEDULER_CLASS\b" tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
grep -n "class DagAwareYarnTaskScheduler\|class YarnTaskSchedulerService" \
tez-dag/src/main/java/org/apache/tez/dag/app/rm/DagAwareYarnTaskScheduler.java \
tez-dag/src/main/java/org/apache/tez/dag/app/rm/YarnTaskSchedulerService.java
AMRMClientAsync: register, allocate, heartbeat
The task scheduler is the AMRM callback handler. In
YarnTaskSchedulerService (tez-dag,
org.apache.tez.dag.app.rm.YarnTaskSchedulerService):
public class YarnTaskSchedulerService extends TaskScheduler
implements AMRMClientAsync.CallbackHandler {
It builds its async client through Tez's own subclass,
TezAMRMClientAsync (tez-dag,
org.apache.tez.dag.app.rm.TezAMRMClientAsync extends AMRMClientAsyncImpl):
grep -n "createAMRMClientAsync\|amRmClient\|setHeartbeatInterval" \
tez-dag/src/main/java/org/apache/tez/dag/app/rm/YarnTaskSchedulerService.java | head
Register
From YarnTaskSchedulerService.start() (method start, same class):
amRmClient.start();
response = amRmClient.registerApplicationMaster(appHostName,
appHostPort,
appTrackingUrl);
The RegisterApplicationMasterResponse carries the maximum container
Resource, the application ACLs, the client-to-AM token master key, and the
queue — all pushed back into the AM via setApplicationRegistrationData.
The heartbeat interval is capped by tez.am.am-rm.heartbeat.interval-ms.max
(TEZ_AM_RM_HEARTBEAT_INTERVAL_MS_MAX):
grep -n "am-rm.heartbeat.interval-ms.max" tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
The callbacks
AMRMClientAsync's internal heartbeat thread fires these on the scheduler.
Tez keeps them short — mostly forwarding to its own dispatcher and doing
allocation math under a lock:
grep -n "onContainersAllocated\|onContainersCompleted\|onNodesUpdated\|onShutdownRequest\|onError\|getProgress" \
tez-dag/src/main/java/org/apache/tez/dag/app/rm/YarnTaskSchedulerService.java
onContainersAllocated(List<Container>)— new containers to match against pending task requests (or release if the app is shutting down).onContainersCompleted(List<ContainerStatus>)— a container exited; its exit status decides how Tez classifies the loss (see below).onNodesUpdated(List<NodeReport>)— node health/decommission reports.onShutdownRequest()— the RM wants the AM to stop; forwarded asappShutdownRequested().onError(Throwable)— an RM-side error; reported asYarnTaskSchedulerServiceError.RESOURCEMANAGER_ERROR.getProgress()— returns app progress 0..1 and is the hook where Tez runspreemptIfNeeded()on each heartbeat.
Unregister
On clean shutdown the scheduler calls
amRmClient.unregisterApplicationMaster(status, msg, trackingUrl) and then
amRmClient.stop(). Failing to unregister (AM killed, GC pause past the
liveness expiry) is what leaves an app in a FAILED/KILLED state with no
final diagnostics.
sequenceDiagram
participant AM as YarnTaskSchedulerService
participant Async as TezAMRMClientAsync (heartbeat thread)
participant RM as ResourceManager
AM->>Async: registerApplicationMaster(host, port, url)
Async->>RM: register
RM-->>Async: maxResource, ACLs, clientToAMKey, queue
loop every heartbeat
Async->>RM: allocate(pending requests, releases, progress)
RM-->>Async: allocated + completed containers, node reports
Async->>AM: onContainersAllocated / onContainersCompleted / onNodesUpdated
end
AM->>Async: unregisterApplicationMaster(state, msg, url)
Async->>RM: unregister
Launching containers: TezContainerLauncherImpl
Once the RM allocates a container, the AM must tell that container's NM to
fork the JVM. That is TezContainerLauncherImpl (tez-dag,
org.apache.tez.dag.app.launcher.TezContainerLauncherImpl), managed by
ContainerLauncherManager. Note it uses ContainerManagementProtocolProxy
directly (not NMClientAsync):
grep -n "ContainerManagementProtocolProxy\|startContainers\|stopContainers" \
tez-dag/src/main/java/org/apache/tez/dag/app/launcher/TezContainerLauncherImpl.java
The launch call, from TezContainerLauncherImpl (inner launch path):
StartContainersResponse response =
proxy.getContainerManagementProtocol().startContainers(
StartContainersRequest.newInstance(
Collections.singletonList(startRequest)));
A failed launch (NM rejects the request, or the container was killed before
launch) is turned into a sendContainerLaunchFailedMsg, which the AM's
container state machine consumes — see Failure Handling.
The local/uber counterpart is LocalContainerLauncher (same package), used
in local mode.
How Tez reacts when YARN misbehaves
This is the payoff section: match the YARN misbehavior to the exact Tez handler.
Preemption and disk failure
onContainersCompleted forwards each ContainerStatus to
TaskSchedulerManager.containerCompleted, which classifies by
ContainerExitStatus. From TaskSchedulerManager (tez-dag,
org.apache.tez.dag.app.rm.TaskSchedulerManager, method
containerCompleted):
if (exitStatus == ContainerExitStatus.PREEMPTED) {
message = "Container preempted externally. ";
errCause = TaskAttemptTerminationCause.EXTERNAL_PREEMPTION;
} else if (exitStatus == ContainerExitStatus.DISKS_FAILED) {
message = "Container disk failed. ";
errCause = TaskAttemptTerminationCause.NODE_DISK_ERROR;
}
The TaskAttemptTerminationCause propagates into the task-attempt state
machine so a preempted attempt is retried without counting as a "real"
failure — preemption is expected, not a bug.
Node loss and blacklisting
Two distinct mechanisms:
- RM-driven node updates arrive through
onNodesUpdatedand flow to the AM's node tracker. - AM-driven blacklisting: repeated task-attempt failures on the same
node trip
AMNodeImpl(tez-dag,org.apache.tez.dag.app.rm.node.AMNodeImpl). Its decision isblacklistingEnabled && (numFailedTAs >= maxTaskFailuresPerNode):
grep -n "maxTaskFailuresPerNode\|blacklistingEnabled\|numFailedTAs" \
tez-dag/src/main/java/org/apache/tez/dag/app/rm/node/AMNodeImpl.java
The knobs (all tez-api, TezConfiguration):
| Key | Constant | Default | Effect |
|---|---|---|---|
tez.am.node-blacklisting.enabled | TEZ_AM_NODE_BLACKLISTING_ENABLED | true | Master switch. |
tez.am.maxtaskfailures.per.node | TEZ_AM_MAX_TASK_FAILURES_PER_NODE | 10 | Failures before a node is blacklisted. |
tez.am.node-blacklisting.ignore-threshold-node-percent | TEZ_AM_NODE_BLACKLISTING_IGNORE_THRESHOLD | 33 | If this % of the cluster would be blacklisted, stop blacklisting. |
tez.am.node-unhealthy-reschedule-tasks | TEZ_AM_NODE_UNHEALTHY_RESCHEDULE_TASKS | false | Reschedule tasks off a node marked unhealthy. |
grep -n "TEZ_AM_NODE_BLACKLISTING_ENABLED\|TEZ_AM_MAX_TASK_FAILURES_PER_NODE\|TEZ_AM_NODE_BLACKLISTING_IGNORE_THRESHOLD\|TEZ_AM_NODE_UNHEALTHY_RESCHEDULE_TASKS" \
tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
The ignore-threshold exists to prevent a bad job from blacklisting the whole cluster: if a code bug fails every attempt, Tez must not conclude that every node is broken.
RM failover and AM re-attempt
If the RM restarts or the AM loses the RM, onError reports a
RESOURCEMANAGER_ERROR. If the AM itself dies, YARN starts a new attempt up
to tez.am.max.app.attempts (TEZ_AM_MAX_APP_ATTEMPTS, default 2), and the
new AM rebuilds DAG state from what RecoveryService wrote — the recovery
path covered in Failure Handling.
grep -n "TEZ_AM_MAX_APP_ATTEMPTS\b" tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
AM GC pause → "RM expired"
getProgress() and the heartbeat run on the AMRM thread. A full-GC pause
longer than YARN's AM liveness expiry means the RM stops seeing heartbeats
and declares the AM dead, killing the container mid-DAG. The fix is AM heap
tuning, not a Tez code change — but the symptom looks like a Tez crash.
The shuffle aux-service
Tez ships its own ShuffleHandler aux-service (tez-plugins,
org.apache.tez.auxservices.ShuffleHandler extends AuxiliaryService) so the
NM can serve map outputs to fetchers. Two identifiers matter and they are
different:
grep -n "class ShuffleHandler\|TEZ_SHUFFLE_SERVICEID\|SHUFFLE_PORT_CONFIG_KEY\|DEFAULT_SHUFFLE_PORT" \
tez-plugins/tez-aux-services/src/main/java/org/apache/tez/auxservices/ShuffleHandler.java
grep -n "TEZ_SHUFFLE_HANDLER_SERVICE_ID\|TEZ_AM_SHUFFLE_AUXILIARY_SERVICE_ID\b" \
tez-api/src/main/java/org/apache/tez/dag/api/TezConstants.java \
tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
ShuffleHandler.TEZ_SHUFFLE_SERVICEID = "tez_shuffle"— the aux-service id you register inyarn-site.xmlif you deploy the Tez shuffle handler.TezConstants.TEZ_SHUFFLE_HANDLER_SERVICE_ID = "mapreduce_shuffle"— the default value oftez.am.shuffle-auxiliary-service-id(shuffle.auxiliary-service.id), i.e. the aux-service Tez asks the NM for when putting the shuffle token inserviceData.
The default port is 13563 (SHUFFLE_PORT_CONFIG_KEY = "tez.shuffle.port").
The mismatch between the two ids is the single most common Tez deployment
error: a Fetcher: ConnectException almost always means the aux-service
name/port that Tez requests does not match what the NM actually runs.
Deploy either the MapReduce mapreduce_shuffle handler (default, no extra
config) or the Tez tez_shuffle handler (then set
tez.am.shuffle-auxiliary-service-id=tez_shuffle and register tez_shuffle
in yarn.nodemanager.aux-services). Do not mix them.
Tokens and security
Token collection happens client-side in TezClientUtils, mediated by
TokenCache (tez-api, org.apache.tez.common.security.TokenCache):
grep -n "obtainTokensForFileSystems\|getSessionToken\|setSessionToken\|mergeBinaryTokens" \
tez-api/src/main/java/org/apache/tez/common/security/TokenCache.java
| Token | Issued by | Used for | Where it lives |
|---|---|---|---|
AMRMToken | RM, auto-injected | AM ↔ RM RPC | AM JVM credentials |
ClientToAMToken | RM (master key returned at register) | Client (DAGClient) ↔ AM RPC | Client + AM credentials |
Session JobToken | Tez (createSessionToken) | Shuffle-fetch authorization | serviceData under the shuffle aux-service key |
| HDFS delegation token | NameNode | Tasks reading/writing HDFS | Container credentials, via TokenCache.obtainTokensForFileSystems |
On a secure cluster the RM renews the file-system delegation tokens it was
handed at submit; note the comment in TokenCache that a token with an
empty renewer is skipped by the RM. A ClientToAMToken auth failure
almost always means client and AM disagree on
hadoop.security.authentication.
The staging-dir lifecycle
The per-app staging dir (tez.staging-dir) is created client-side by
ensureStagingDirExists, carries the framework tarball and serialized DAG,
and is torn down by the AM on shutdown — but only if unregistration
succeeded, guarded by tez.am.staging.scratch-data.auto-delete. From
DAGAppMaster (tez-dag, org.apache.tez.dag.app.DAGAppMaster):
// Given pre-emption, we should delete tez scratch dir only if unregister is
// successful
boolean deleteTezScratchData = this.amConf.getBoolean(
TezConfiguration.TEZ_AM_STAGING_SCRATCH_DATA_AUTO_DELETE,
TezConfiguration.TEZ_AM_STAGING_SCRATCH_DATA_AUTO_DELETE_DEFAULT);
grep -n "TEZ_AM_STAGING_SCRATCH_DATA_AUTO_DELETE\b" \
tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
Consequence: a hard-killed AM (yarn application -kill, RM expiry, OOM)
never runs the cleanup, so orphaned staging dirs accumulate under the parent
path. In a busy HiveServer2 cluster this is a real disk-leak source — a
periodic sweep of the staging parent is standard operational hygiene.
Timeline Server (ATS) and log aggregation
Two more YARN-facing surfaces matter for post-mortem debugging, and both are about where the evidence lives after the app is gone.
ATS. Tez publishes a rich event stream — DAG/vertex/task/attempt started
and finished, container launched/stopped — to the YARN Timeline Server via a
pluggable history service. The plugin is selected by
tez.history.logging.service.class (TEZ_HISTORY_LOGGING_SERVICE_CLASS in
tez-api), and the implementations live in tez-plugins:
ls tez-plugins/
grep -n "TEZ_HISTORY_LOGGING_SERVICE_CLASS\b" tez-api/src/main/java/org/apache/tez/dag/api/TezConfiguration.java
grep -rln "class ATSHistoryLoggingService\|class ATSV15HistoryLoggingService" \
tez-plugins/tez-yarn-timeline-history*/src/main/java
| ATS flavor | Tez plugin module | Notes |
|---|---|---|
| ATSv1 | tez-yarn-timeline-history | ATSHistoryLoggingService; LevelDB-backed Timeline Server. |
| ATSv1.5 | tez-yarn-timeline-history-with-fs (+ -with-acls) | ATSV15HistoryLoggingService; entity-file staging to HDFS reduces ATS write load. |
The Tez UI reads these events to render the DAG view, task swimlanes, and
counter trees; the UI location is surfaced in DAGStatus via
tez.am.tez-ui.history-url.template (TEZ_AM_TEZ_UI_HISTORY_URL_TEMPLATE).
An empty ATS for a completed app almost always means
tez.history.logging.service.class is mis-set or the Timeline Server is not
running — not that Tez failed to emit events.
Log aggregation. With yarn.log-aggregation-enable=true, every
container's stdout, stderr, and syslog are uploaded to HDFS under
yarn.nodemanager.remote-app-log-dir when the container exits, retrievable
with yarn logs -applicationId <appId>. With it disabled, the logs sit in
${yarn.nodemanager.log-dirs}/<applicationId>/<containerId>/ on each NM
until yarn.nodemanager.log.retain-seconds expires — which is where you go
for a TezChild that crashed before it could aggregate. This is pure YARN
configuration; Tez neither aggregates nor cleans these logs, it only writes
to the redirections the CLC set up.
yarn CLI behaviors for Tez apps
| Command | Behavior on a Tez app |
|---|---|
yarn application -list | Lists Tez AMs; application type is TEZ (TezConstants.TEZ_APPLICATION_TYPE). |
yarn application -status <appId> | AM state, RM tracking URL, ATS URL if configured. |
yarn application -kill <appId> | RM kills the AM container; staging dir is not cleaned (see above). |
yarn logs -applicationId <appId> | Streams aggregated logs of AM + all TezChild containers (if aggregation on). |
yarn node -list | Confirm the shuffle aux-service is up on each NM. |
grep -n "TEZ_APPLICATION_TYPE\b" tez-api/src/main/java/org/apache/tez/dag/api/TezConstants.java
Reading exercise
Run all from ~/tez-src:
grep -n "registerApplicationMaster\|unregisterApplicationMaster" \ tez-dag/src/main/java/org/apache/tez/dag/app/rm/YarnTaskSchedulerService.java— read the surroundingstart()andstop()methods; what does the register response give back to the AM?- Read
createApplicationSubmissionContextinTezClientUtils. List every argument passed toContainerLaunchContext.newInstance. grep -n "ContainerExitStatus" tez-dag/src/main/java/org/apache/tez/dag/app/rm/TaskSchedulerManager.java— enumerate every exit status Tez special-cases and theTaskAttemptTerminationCauseit maps to.- Read
AMNodeImplaround the blacklisting predicate. Under what two conditions does a node get blacklisted, and what disables it cluster-wide? grep -n "TEZ_SHUFFLE_SERVICEID\|SHUFFLE_PORT_CONFIG_KEY" \ tez-plugins/tez-aux-services/src/main/java/org/apache/tez/auxservices/ShuffleHandler.java— reconciletez_shufflevs the requestedmapreduce_shuffledefault.- Read the staging-delete block in
DAGAppMaster. Why is deletion gated on successful unregistration?
Common bugs and symptoms
| Symptom | Likely cause | First look |
|---|---|---|
ConnectException from Fetcher | Shuffle aux-service name/port mismatch | tez.am.shuffle-auxiliary-service-id vs yarn-site.xml |
Auxiliary service ... not configured | aux-service missing on the NM | yarn.nodemanager.aux-services |
| AM dies "RM expired" | AMRM heartbeat blocked (full GC) past liveness expiry | AM heap; getProgress thread |
Frequent EXTERNAL_PREEMPTION retries | Queue over capacity, preemption on | Queue config; this is expected, not a Tez bug |
| Whole cluster blacklisted, job fails | Job-level bug failing every attempt | tez.am.node-blacklisting.ignore-threshold-node-percent |
| Orphaned staging dirs accumulate | AM hard-killed, cleanup skipped | tez.am.staging.scratch-data.auto-delete; sweep the parent |
ClientToAMToken auth fail | Client/AM security mismatch | hadoop.security.authentication on both sides |
| Second AM attempt loses DAG progress | Recovery disabled or incomplete | tez.am.max.app.attempts; Failure Handling |
Validation: prove you understand this
- Trace the call path from
DAGAppMaster.serviceStarttoAMRMClientAsync.registerApplicationMaster, naming the intermediate class that actually creates the scheduler. - List the six arguments to
ContainerLaunchContext.newInstancein the AM CLC and say who consumesserviceData. - A container completes with
ContainerExitStatus.PREEMPTED. Name the TezTaskAttemptTerminationCauseit maps to and why the attempt is retried without penalty. Cite the class and method. - Explain the difference between
tez_shuffleand the defaultmapreduce_shuffleid, and give the exact config change to run Tez's own shuffle handler. - Why does an AM full-GC pause manifest as "RM expired", and which side (Tez config or YARN config) owns the threshold?
- Under what condition does the staging dir survive AM shutdown, and what operational problem does that create on a busy HS2 cluster?