Hadoop YARN - 웹 서비스 REST API 소개
Hadoop YARN - 웹 서비스 REST API 소개
Hadoop YARN 웹 서비스 REST API는 클러스터, 노드, 애플리케이션, 애플리케이션 이력 정보에 접근할 수 있게 해주는 일련의 URI 리소스입니다. URI 리소스는 반환되는 정보의 유형에 따라 API로 그룹화됩니다. 일부 URI 리소스는 컬렉션을 반환하고 다른 것들은 단일(singleton) 객체를 반환합니다.
출처: 문서
본문
개요 (Overview)
Hadoop YARN 웹 서비스 REST API는 클러스터, 노드, 애플리케이션, 애플리케이션 이력 정보에 접근할 수 있게 해주는 URI 리소스 집합입니다. URI 리소스는 반환되는 정보의 유형에 따라 API로 그룹화됩니다. 일부 URI 리소스는 컬렉션을 반환하고 다른 것들은 단일 객체를 반환합니다.
URI
REST 기반 웹 서비스의 URI는 다음과 같은 구문을 가집니다:
http://{http address of service}/ws/{version}/{resourcepath}
이 구문의 요소는 다음과 같습니다:
{http address of service} - 정보를 얻으려는 서비스의 http 주소.
현재 지원되는 것은 ResourceManager, NodeManager,
MapReduce application master, history server입니다.
{version} - API의 버전. 이 릴리스에서 버전은 v1입니다.
{resourcepath} - 단일 리소스 또는 리소스 컬렉션을 정의하는 경로.
HTTP 요청
REST API를 호출하려면 애플리케이션이 리소스와 연결된 URI에 HTTP 연산을 호출합니다.
HTTP 연산 요약
현재 GET만 지원됩니다. 지정된 리소스에 대한 정보를 검색합니다.
보안 (Security)
웹 서비스 REST API는 웹 UI와 동일한 보안을 거칩니다. 클러스터 관리자가 필터를 활성화한 경우, 그들이 지정한 메커니즘으로 인증해야 합니다.
지원되는 헤더
현재 헤더에서 사용되는 필드는 Accept와 Accept-Encoding뿐입니다. Accept는 수락하는 응답 유형으로 XML과 JSON을 지원합니다. Accept-Encoding은 현재 gzip 형식만 지원하며, 이를 지정하면 gzip 압축 출력이 반환되고 그렇지 않으면 압축되지 않은 출력이 반환됩니다. 다른 모든 헤더 필드는 무시됩니다.
HTTP 응답
다음 절들은 웹 서비스 REST API의 HTTP 응답 구문과 기타 세부 사항 중 일부를 설명합니다.
압축 (Compression)
이 릴리스는 HTTP 요청의 Accept-Encoding 헤더에 gzip을 지정하면(Accept-Encoding: gzip) gzip 압축을 지원합니다.
응답 형식 (Response Formats)
이 릴리스의 웹 서비스 REST API는 JSON과 XML 형식의 응답을 지원합니다. JSON이 기본값입니다. 응답 형식을 설정하려면 HTTP 요청의 Accept 헤더에 형식을 지정하면 됩니다.
HTTP 응답 코드에서 명시된 대로, 응답 본문에는 리소스를 나타내는 데이터 또는 오류 메시지가 포함될 수 있습니다. 성공 시 응답 본문은 선택한 형식(JSON 또는 XML)입니다. 오류 시 응답 본문은 요청된 형식에 따라 JSON 또는 XML입니다. 응답의 Content-Type 헤더에는 요청된 형식이 포함됩니다. 애플리케이션이 지원되지 않는 형식을 요청하면 응답 상태 코드는 500입니다. 응답 본문 내 필드 순서는 지정되지 않으며 변경될 수 있음에 유의하세요. 또한 응답 본문에 추가 필드가 추가될 수 있습니다. 따라서 애플리케이션은 어떤 순서로든 응답 본문에서 데이터를 추출할 수 있는 파싱 루틴을 사용해야 합니다.
응답 오류 (Response Errors)
HTTP 요청을 호출한 후 애플리케이션은 응답 상태 코드를 확인하여 성공 여부를 검증하거나 오류를 감지해야 합니다. 응답 상태 코드가 오류를 나타내면 응답 본문에 오류 메시지가 포함됩니다. 첫 번째 필드는 예외 유형이며, 현재 RemoteException만 반환됩니다. 다음 표는 RemoteException 오류 메시지 내의 항목을 나열합니다.
| Item | Data Type | Description | | exception | String | 예외 유형 | javaClassName | String | 예외의 Java 클래스 이름 | message | String | 예외의 자세한 메시지
응답 예시 (Response Examples)
단일 리소스에 대한 JSON 응답
HTTP Request: GET http://rmhost.domain:8088/ws/v1/cluster/apps/application_1324057493980_0001
Response Status Line: HTTP/1.1 200 OK
Response Header:
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Server: Jetty(6.1.26)
Response Body:
{
"app":
{
"id":"application_1324057493980_0001",
"user":"user1",
"name":"",
"queue":"default",
"state":"ACCEPTED",
"finalStatus":"UNDEFINED",
"progress":0,
"trackingUI":"UNASSIGNED",
"diagnostics":"",
"clusterId":1324057493980,
"startedTime":1324057495921,
"finishedTime":0,
"elapsedTime":2063,
"amContainerLogs":"http:\/\/amNM:2\/node\/containerlogs\/container_1324057493980_0001_01_000001",
"amHostHttpAddress":"amNM:2"
}
}
오류 응답에 대한 JSON 응답
여기서는 아직 존재하지 않는 애플리케이션에 대한 정보를 요청합니다.
HTTP Request: GET http://rmhost.domain:8088/ws/v1/cluster/apps/application_1324057493980_9999
Response Status Line: HTTP/1.1 404 Not Found
Response Header:
HTTP/1.1 404 Not Found
Content-Type: application/json
Transfer-Encoding: chunked
Server: Jetty(6.1.26)
Response Body:
{
"RemoteException" : {
"javaClassName" : "org.apache.hadoop.yarn.webapp.NotFoundException",
"exception" : "NotFoundException",
"message" : "java.lang.Exception: app with id: application_1324057493980_9999 not found"
}
}
샘플 사용 (Sample Usage)
웹 서비스 REST API를 사용하는 방법은 많습니다. 이 예제에서는 curl 명령줄 인터페이스를 사용해 REST GET 호출을 합니다.
이 예제에서 사용자는 다음과 같은 명령으로 ResourceManager에 MapReduce 애플리케이션을 제출합니다:
hadoop jar hadoop-mapreduce-test.jar sleep -Dmapred.job.queue.name=a1 -m 1 -r 1 -rt 1200000 -mt 20
클라이언트는 애플리케이션 id와 함께 제출된 작업에 대한 정보를 출력합니다. 예:
12/01/18 04:25:15 INFO mapred.ResourceMgrDelegate: Submitted application application_1326821518301_0010 to ResourceManager at host.domain.com/10.10.10.10:8032
12/01/18 04:25:15 INFO mapreduce.Job: Running job: job_1326821518301_0010
12/01/18 04:25:21 INFO mapred.ClientServiceDelegate: The url to track the job: host.domain.com:8088/proxy/application_1326821518301_0010/
12/01/18 04:25:22 INFO mapreduce.Job: Job job_1326821518301_0010 running in uber mode : false
12/01/18 04:25:22 INFO mapreduce.Job: map 0% reduce 0%
그런 다음 사용자는 애플리케이션을 추적하고자 합니다. ResourceManager에서 애플리케이션에 대한 정보를 얻는 것으로 시작합니다. 압축된 출력을 요청하려면 --compressed 옵션을 사용합니다. curl은 클라이언트 측에서 압축 해제를 처리합니다.
curl --compressed -H "Accept: application/json" -X GET "http://host.domain.com:8088/ws/v1/cluster/apps/application_1326821518301_0010"
Output:
{
"app" : {
"finishedTime" : 0,
"amContainerLogs" : "http://host.domain.com:8042/node/containerlogs/container_1326821518301_0010_01_000001",
"trackingUI" : "ApplicationMaster",
"state" : "RUNNING",
"user" : "user1",
"id" : "application_1326821518301_0010",
"clusterId" : 1326821518301,
"finalStatus" : "UNDEFINED",
"amHostHttpAddress" : "host.domain.com:8042",
"progress" : 82.44703,
"name" : "Sleep job",
"startedTime" : 1326860715335,
"elapsedTime" : 31814,
"diagnostics" : "",
"trackingUrl" : "http://host.domain.com:8088/proxy/application_1326821518301_0010/",
"queue" : "a1"
}
}
이 애플리케이션은 브라우저를 통해 또는 웹 서비스 REST API를 사용해 확인할 수 있습니다. 사용자는 실행 중인 애플리케이션에 대한 더 자세한 정보를 얻기 위해 이 애플리케이션의 MapReduce application master로 직접 이동하고자 합니다. ResourceManager는 이 애플리케이션에 사용할 수 있는 trackingUrl을 나열합니다: http://host.domain.com:8088/proxy/application_1326821518301_0010/. 사용자는 웹 서비스 REST API를 사용해 이 MapReduce application master가 실행 중인 작업 목록을 얻습니다:
curl --compressed -H "Accept: application/json" -X GET "http://host.domain.com:8088/proxy/application_1326821518301_0010/ws/v1/mapreduce/jobs"
Output:
{
"jobs" : {
"job" : [
{
"runningReduceAttempts" : 1,
"reduceProgress" : 72.104515,
"failedReduceAttempts" : 0,
"newMapAttempts" : 0,
"mapsRunning" : 0,
"state" : "RUNNING",
"successfulReduceAttempts" : 0,
"reducesRunning" : 1,
"acls" : [
{
"value" : " ",
"name" : "mapreduce.job.acl-modify-job"
},
{
"value" : " ",
"name" : "mapreduce.job.acl-view-job"
}
],
"reducesPending" : 0,
"user" : "user1",
"reducesTotal" : 1,
"mapsCompleted" : 1,
"startTime" : 1326860720902,
"id" : "job_1326821518301_10_10",
"successfulMapAttempts" : 1,
"runningMapAttempts" : 0,
"newReduceAttempts" : 0,
"name" : "Sleep job",
"mapsPending" : 0,
"elapsedTime" : 64432,
"reducesCompleted" : 0,
"mapProgress" : 100,
"diagnostics" : "",
"failedMapAttempts" : 0,
"killedReduceAttempts" : 0,
"mapsTotal" : 1,
"uberized" : false,
"killedMapAttempts" : 0,
"finishTime" : 0
}
]
}
}
그런 다음 사용자는 위에서 나열된 job id job_1326821518301_10_10 작업의 태스크 세부 정보를 얻고자 합니다.
curl --compressed -H "Accept: application/json" -X GET "http://host.domain.com:8088/proxy/application_1326821518301_0010/ws/v1/mapreduce/jobs/job_1326821518301_10_10/tasks"
Output:
{
"tasks" : {
"task" : [
{
"progress" : 100,
"elapsedTime" : 5059,
"state" : "SUCCEEDED",
"startTime" : 1326860725014,
"id" : "task_1326821518301_10_10_m_0",
"type" : "MAP",
"successfulAttempt" : "attempt_1326821518301_10_10_m_0_0",
"finishTime" : 1326860730073
},
{
"progress" : 72.104515,
"elapsedTime" : 0,
"state" : "RUNNING",
"startTime" : 1326860732984,
"id" : "task_1326821518301_10_10_r_0",
"type" : "REDUCE",
"successfulAttempt" : "",
"finishTime" : 0
}
]
}
}
map 태스크는 끝났지만 reduce 태스크는 아직 실행 중입니다. 사용자는 reduce 태스크 task_1326821518301_10_10_r_0의 태스크 시도 정보를 얻고자 합니다. JSON이 기본 출력 형식이므로 여기서 Accept 헤더는 사실상 필요하지 않습니다:
curl --compressed -X GET "http://host.domain.com:8088/proxy/application_1326821518301_0010/ws/v1/mapreduce/jobs/job_1326821518301_10_10/tasks/task_1326821518301_10_10_r_0/attempts"
Output:
{
"taskAttempts" : {
"taskAttempt" : [
{
"elapsedMergeTime" : 158,
"shuffleFinishTime" : 1326860735378,
"assignedContainerId" : "container_1326821518301_0010_01_000003",
"progress" : 72.104515,
"elapsedTime" : 0,
"state" : "RUNNING",
"elapsedShuffleTime" : 2394,
"mergeFinishTime" : 1326860735536,
"rack" : "/10.10.10.0",
"elapsedReduceTime" : 0,
"nodeHttpAddress" : "host.domain.com:8042",
"type" : "REDUCE",
"startTime" : 1326860732984,
"id" : "attempt_1326821518301_10_10_r_0_0",
"finishTime" : 0
}
]
}
}
reduce 시도는 아직 실행 중이며, 사용자는 해당 시도의 현재 카운터 값을 보고자 합니다:
curl --compressed -H "Accept: application/json" -X GET "http://host.domain.com:8088/proxy/application_1326821518301_0010/ws/v1/mapreduce/jobs/job_1326821518301_10_10/tasks/task_1326821518301_10_10_r_0/attempts/attempt_1326821518301_10_10_r_0_0/counters"
Output:
{
"JobTaskAttemptCounters" : {
"taskAttemptCounterGroup" : [
{
"counterGroupName" : "org.apache.hadoop.mapreduce.FileSystemCounter",
"counter" : [
{
"value" : 4216,
"name" : "FILE_BYTES_READ"
},
{
"value" : 77151,
"name" : "FILE_BYTES_WRITTEN"
},
{
"value" : 0,
"name" : "FILE_READ_OPS"
},
{
"value" : 0,
"name" : "FILE_LARGE_READ_OPS"
},
{
"value" : 0,
"name" : "FILE_WRITE_OPS"
},
{
"value" : 0,
"name" : "HDFS_BYTES_READ"
},
{
"value" : 0,
"name" : "HDFS_BYTES_WRITTEN"
},
{
"value" : 0,
"name" : "HDFS_READ_OPS"
},
{
"value" : 0,
"name" : "HDFS_LARGE_READ_OPS"
},
{
"value" : 0,
"name" : "HDFS_WRITE_OPS"
}
]
},
{
"counterGroupName" : "org.apache.hadoop.mapreduce.TaskCounter",
"counter" : [
{
"value" : 0,
"name" : "COMBINE_INPUT_RECORDS"
},
{
"value" : 0,
"name" : "COMBINE_OUTPUT_RECORDS"
},
{
"value" : 1767,
"name" : "REDUCE_INPUT_GROUPS"
},
{
"value" : 25104,
"name" : "REDUCE_SHUFFLE_BYTES"
},
{
"value" : 1767,
"name" : "REDUCE_INPUT_RECORDS"
},
{
"value" : 0,
"name" : "REDUCE_OUTPUT_RECORDS"
},
{
"value" : 0,
"name" : "SPILLED_RECORDS"
},
{
"value" : 1,
"name" : "SHUFFLED_MAPS"
},
{
"value" : 0,
"name" : "FAILED_SHUFFLE"
},
{
"value" : 1,
"name" : "MERGED_MAP_OUTPUTS"
},
{
"value" : 50,
"name" : "GC_TIME_MILLIS"
},
{
"value" : 1580,
"name" : "CPU_MILLISECONDS"
},
{
"value" : 141320192,
"name" : "PHYSICAL_MEMORY_BYTES"
},
{
"value" : 1118552064,
"name" : "VIRTUAL_MEMORY_BYTES"
},
{
"value" : 73728000,
"name" : "COMMITTED_HEAP_BYTES"
}
]
},
{
"counterGroupName" : "Shuffle Errors",
"counter" : [
{
"value" : 0,
"name" : "BAD_ID"
},
{
"value" : 0,
"name" : "CONNECTION"
},
{
"value" : 0,
"name" : "IO_ERROR"
},
{
"value" : 0,
"name" : "WRONG_LENGTH"
},
{
"value" : 0,
"name" : "WRONG_MAP"
},
{
"value" : 0,
"name" : "WRONG_REDUCE"
}
]
},
{
"counterGroupName" : "org.apache.hadoop.mapreduce.lib.output.FileOutputFormatCounter",
"counter" : [
{
"value" : 0,
"name" : "BYTES_WRITTEN"
}
]
}
],
"id" : "attempt_1326821518301_10_10_r_0_0"
}
}
작업이 끝나면 사용자는 이 작업에 대한 최종 작업 정보를 history server에서 얻고자 합니다.
curl --compressed -X GET "http://host.domain.com:19888/ws/v1/history/mapreduce/jobs/job_1326821518301_10_10"
Output:
{
"job" : {
"avgReduceTime" : 1250784,
"failedReduceAttempts" : 0,
"state" : "SUCCEEDED",
"successfulReduceAttempts" : 1,
"acls" : [
{
"value" : " ",
"name" : "mapreduce.job.acl-modify-job"
},
{
"value" : " ",
"name" : "mapreduce.job.acl-view-job"
}
],
"user" : "user1",
"reducesTotal" : 1,
"mapsCompleted" : 1,
"startTime" : 1326860720902,
"id" : "job_1326821518301_10_10",
"avgMapTime" : 5059,
"successfulMapAttempts" : 1,
"name" : "Sleep job",
"avgShuffleTime" : 2394,
"reducesCompleted" : 1,
"diagnostics" : "",
"failedMapAttempts" : 0,
"avgMergeTime" : 2552,
"killedReduceAttempts" : 0,
"mapsTotal" : 1,
"queue" : "a1",
"uberized" : false,
"killedMapAttempts" : 0,
"finishTime" : 1326861986164
}
}
사용자는 또한 ResourceManager에서 최종 애플리케이션 정보도 얻습니다.
curl --compressed -H "Accept: application/json" -X GET "http://host.domain.com:8088/ws/v1/cluster/apps/application_1326821518301_0010"
Output:
{
"app" : {
"finishedTime" : 1326861991282,
"amContainerLogs" : "http://host.domain.com:8042/node/containerlogs/container_1326821518301_0010_01_000001",
"trackingUI" : "History",
"state" : "FINISHED",
"user" : "user1",
"id" : "application_1326821518301_0010",
"clusterId" : 1326821518301,
"finalStatus" : "SUCCEEDED",
"amHostHttpAddress" : "host.domain.com:8042",
"progress" : 100,
"name" : "Sleep job",
"startedTime" : 1326860715335,
"elapsedTime" : 1275947,
"diagnostics" : "",
"trackingUrl" : "http://host.domain.com:8088/proxy/application_1326821518301_0010/jobhistory/job/job_1326821518301_10_10",
"queue" : "a1"
}
}
더 알아보기 (Learn more)
- 원문: 문서