通过查阅网上大神的博客可以发现,博客中读取Hive进度的方法都是通过Hive的日志去读取。但是我在查看Hive3.0的日志后,发现Hive3.0的日志中不会记录实时的任务进度,只会记录实时进度以外的其他数据。所以必须另辟蹊径,以解决这个问题。
如何才能读取到Hive的任务进度?
通过观察可以发现,Hive的任务可以分为两种:
- 不需要执行MapReduce的简单任务,可以瞬时完成。
- 需要执行MapReduce的复杂任务,如:需要表关联、统计等任务,需要执行一段时间。
所以我们可以看出,我们只要读取需要执行MapReduce的Hive任务进度即可,并且这个任务进度应该就是MapReduce的任务进度。在CLI执行Hive SQL时可以发现,HIve能在命令行显示出MapReduce任务的进度。那么Hive是通过何种方式读取到MapReduce的任务进度的呢?
HIve自身是如何读取任务进度?
通过分析源码,我发现Hive自身是通过Hadoop所提供的API接口,去读取MapReduce的任务进度。通过查阅文档和实际测试我们可以发现在http://slave2.hadoop:8088/ws/v1/cluster/apps/application_1430424020775_0001这个接口下,可以由application_1430424020775_0001这个MapReduce任务ID,拿到对应任务状态的JSON格式数据,如下(hadoop 3.0)
{
"app": {
"id": "application_1545745555642_0008",
"user": "hdfs",
"name": "HIVE-f33a32e4-5932-46a9-8473-dc755616a595",
"queue": "default",
"state": "FINISHED",
"finalStatus": "SUCCEEDED",
"progress": 100,
"trackingUI": "History",
"trackingUrl": "http://slave2.hadoop:8088/proxy/application_1545745555642_0008/",
"diagnostics": "Session timed out, lastDAGCompletionTime=1548319082823 ms, sessionTimeoutInterval=600000 ms\nSession stats:submittedDAGs=1, successfulDAGs=1, failedDAGs=0, killedDAGs=0\n",
"clusterId": 1545745555642,
"applicationType": "TEZ",
"applicationTags": "hive_20190124163742_0a204765-22a4-4a35-b08c-c629a8244758",
"priority": 0,
"startedTime": 1548319064617,
"finishedTime": 1548319741514,
"elapsedTime": 676897,
"amContainerLogs": "http://slave3.hadoop:8042/node/containerlogs/container_e12_1545745555642_0008_01_000001/hdfs",
"amHostHttpAddress": "slave3.hadoop:8042",
"amRPCAddress": "slave3.hadoop:45439",
"masterNodeId": "slave3.hadoop:45454",
"allocatedMB": -1,
"allocatedVCores": -1,
"reservedMB": -1,
"reservedVCores": -1,
"runningContainers": -1,
"memorySeconds": 12773007,
"vcoreSeconds": 692,
"queueUsagePercentage": 0,
"clusterUsagePercentage": 0,
"resourceSecondsMap": {
"entry": {
"key": "vcores",
"value": "692"
}
},
"preemptedResourceMB": 0,
"preemptedResourceVCores": 0,
"numNonAMContainerPreempted": 0,
"numAMContainerPreempted": 0,
"preemptedMemorySeconds": 0,
"preemptedVcoreSeconds": 0,
"preemptedResourceSecondsMap": {},
"logAggregationStatus": "SUCCEEDED",
"unmanagedApplication": false,
"amNodeLabelExpression": "",
"timeouts": {
"timeout": [
{
"type": "LIFETIME",
"expiryTime": "UNLIMITED",
"remainingTimeInSeconds": -1
}
]
}
}
}
可以发现其中的progress就是任务的状态。(需要注意的是,这个接口获取的任务状态,在任务进行时是准确的,但是任务一旦完成或者失败,这个任务的进度就会变为0,而不是100或者其他数字。其次,在hive连续提交任务时,多个hive任务会共用一个app_id)。
初步思路
我们可以通过读取Hive的日志获取到,MapReduce的app_id,然后在通过这个id和yarn的接口获取到任务进度。
即:
- 读取到HIve的日志,从日志中获取MapReduce的任务id
- 通过任务id和接口获取到任务的状态对应的JSON格式的数据