Hadoop全链路监控解决⽅案
前⾔
我在最近的⼏篇⽂章中都或多或少的提到了⼀个很重要的词-"监控".为什么要提到这个词呢,因为如果你和我⼀样是⼀名⼤数据⼯程师,你⼿下管理着批量的集机器,并且同时这个集的规模还会不定时的扩⼤,机器⼀旦变多,发⽣问题的频率和类型就会变多,所以这是,你靠⼈⾁去分析某台机器上的⽇志,OK,1台机器,2台机器,尚且可以解决办法,但是100台,1000台呢,当然如果⼯程师还这么做的话,我想他会抓狂的.所以如何做到智能化发现问题,定位问题,就显得很关键了,最理想的结果是,你拥有你的集机器中每天跑的job的各种指标数据,然后你动动⿏标,通过展⽰出来的图形界⾯,就迅速的发现了问题.这也是正是我最近在做的⼀件事情,效果还算不错.下⾯是我近1个⽉来,对于我们部门的Hadoop集做的⼀些监控⽅⾯的事情,谈不上⾼⼤上的结构,我们是如何以最简单的⽅式达到最⼤化的效果,希望能给⼤家带来帮助.
监控两⼤主题
监控的⼤⽅向是想好了,但是我们要监控哪些指标,有必要提⼀下,要想做好监控,⾸先你要了解Hadoop这⼀整套的系统逻辑,⼤致了解即可,那么我们是怎么做的呢.分为2⼤⽅向,宏观层⾯和微观层⾯.宏观⾓度的理解就是Node级别,拓扑结构级
别,DataNode,NameNode,JournalNode,ResourceManager,NodeManager,主要就是这5⼤组件,通过分析这些节点上的监控数据,⼀般你能够定位到慢节点,可能某台机器的⽹络出问题了,或者说某台机器执⾏的时间总是⼤于正常机器等等这样类似的问题.刚刚说的是⼀个监控⽅向,还有1个是微观层⾯,就是细粒度化的监控,基于user⽤户级别,基于单个job,单个task级别的监控,像这类监控指标就是另⼀⼤⽅向,这类的监控指标在实际的使⽤场景中特别重要,⼀旦你的集资源是开放给外⾯的⽤户使⽤,⽤户本⾝不了解你的这套机制原理,很容易会乱申请资源,造成严重拖垮集整体运作效率的事情,所以这类监控的指标就是为了防⽌这样的事情发⽣.
宏观层⾯监控
OK,两⼤主题监控⽅向确定,下⾯谈谈具体的实践⽅案,想必这也是⼤家所关⼼的.⾸先要先想能不能通过最简单的⽅式直接拿到⼀些数据,⽐如RPC接⼝去取,这样的⽅式的确是有的,我们⽤了YarnClient的获取nodeReport⽅法,做了这么⼀个获取⼯具,下⾯是核⼼代码:
YarnClient client;
client = ateYarnClient();
client.init(new Configuration());
client.start();
List<NodeReport> nodesReport = NodeReports();
...
这样就得到nodeManager中的许多数据,包括正在运⾏的container数量,使⽤的内存⼤⼩,核数多少等等信息,同理DataNode的数据也可以以类似的⽅式获取,这⾥就不给出代码了.在分节点的统计代码中,还有⼀项指标也可以帮助我们发现节点异常问题,我们对各个IP对namenode的rpc 请求量做了统计,对namenode的请求其实就是对HDFS的请求最了统计.当然,这个统计肯定要⾃⼰去分析才能得到.分析⽇志中的哪条记录信息呢,如果你没有阅读过NameNode和FSNameSystem这2个类的代码,你可能会不知道,hadoop在设计的时候,考虑的⽐较好,对于Client的每次请求,都做了请求记录的输出,名字叫做audit⽇志:
/**
* Default AuditLogger implementation; used when no access logger is
* defined in the config file. It can also be explicitly listed in the
* config file.
*/
private static class DefaultAuditLogger extends HdfsAuditLogger {
....
@Override
public void logAuditEvent(boolean succeeded, String userName,
InetAddress addr, String cmd, String src, String dst,
FileStatus status, UserGroupInformation ugi,
DelegationTokenSecretManager dtSecretManager) {
if (auditLog.isInfoEnabled()) {
final StringBuilder sb = ();
sb.setLength(0);
sb.append("allowed=").append(succeeded).append("\t");
sb.append("ugi=").append(userName).append("\t");
sb.append("ip=").append(addr).append("\t");
sb.append("cmd=").append(cmd).append("\t");
sb.append("src=").append(src).append("\t");
sb.append("dst=").append(dst).append("\t");
if (null == status) {
sb.append("perm=null");
} else {
sb.append("perm=");
sb.Owner()).append(":");
sb.Group()).append(":");
sb.Permission());
}
if (logTokenTrackingId) {
sb.append("\t").append("trackingId=");
String trackingId = null;
if (ugi != null && dtSecretManager != null
&& AuthenticationMethod() == AuthenticationMethod.TOKEN) {
for (TokenIdentifier tid: TokenIdentifiers()) {
if (tid instanceof DelegationTokenIdentifier) {
DelegationTokenIdentifier dtid =
(DelegationTokenIdentifier)tid;
trackingId = TokenTrackingId(dtid);
log4j2 appenderbreak;
}
}
}
sb.append(trackingId);
}
sb.append("\t").append("proto=");
sb.append(NamenodeWebHdfsMethods.isWebHdfsInvocation() ? "webhdfs" : "rpc");
String());
}
}
⾥⾯的信息⾮常全,有⽤户者,操作命令,操作的源⽂件,⽬标⽂件,请求ip,其实单纯这⼏个信息,就可以帮助我们分析出很多有价值的信息了,当然我们先⽤他来分析基于IP的请求统计.这些记录如果你不做特殊的处理,他是零散的分布于nameode⽇志中的,所以你要把他从茫茫的记录中筛选出来,单独放到⼀个⽂件中,这个hadoop也是可以做到的,配置log4j的配置⽂件,增加下⾯的配置信息.
#
# hdfs audit logging
#
hdfs.audit.logger=INFO,RFAAUDIT
hdfs.audit.log.maxfilesize=256MB
hdfs.audit.log.maxbackupindex=100
apache.hadoop.hdfs.server.namenode.FSNamesystem.audit=${hdfs.audit.logger}
apache.hadoop.hdfs.server.namenode.FSNamesystem.audit=false
log4j.appender.RFAAUDIT=org.apache.log4j.RollingFileAppender
log4j.appender.RFAAUDIT.File=${hadoop.log.dir}/hdfs-audit.log
log4j.appender.RFAAUDIT.layout=org.apache.log4j.PatternLayout
log4j.appender.RFAAUDIT.layout.ConversionPattern=%d{ISO8601} %p %c{2}: %m%n
log4j.appender.RFAAUDIT.MaxFileSize=${hdfs.audit.log.maxfilesize}
log4j.appender.RFAAUDIT.MaxBackupIndex=${hdfs.audit.log.maxbackupindex}
这样就会单独的输出名字为hdfs-audit.log的⽂件数据了.分析的⽅式就是写个程序做⽂本解析,进⾏count计数即可.我们对这个⽂件还做了但分钟级别qps请求量的趋势统计,分⽤户级别的请求量分析,⼤家也可以这么去做.
总的来说,离线的统计⽅式基本可以采⽤这样的⽅式去做,配lo4j单独打出某个类的⽇志,单类⽂件进
⾏解析.
微观层⾯监控
微观层⾯的监控就要⽐宏观层⾯的监控要复杂许多,⾸先同样你要了解⼀定的理论只是,在Hadoop中,⼀个job是以怎么样的⽅式执⾏,如何转化,到最后的任务结束.当然在这⾥不可能⼀次性讲清楚.现在只要知道,这么⼏个名次,Application,Job,Task,Container,我们所说的细粒度监控指的也就是对这些变量进⾏监控.当然这些指标的量级是很⼤的,Application应⽤数和Job数也是可以1天过万的,这些job⽣成的task⼩的⼗⼏,多则上千个task,总的也可能达到1天上百万个task在跑.对于微观层⾯的监控,采⽤分析⽇志的⽅式,就不见得会很适合,应该并没有⼀个完整的地⽅会把每次task的启动信息⼤全,所以我们需要借助⼀下Hadoop⾃⾝对job的监控,就是JobHistory,这个类中就保存了历史执⾏过的job的执⾏信息,1个job⾥⾯会有所有执⾏过得task信息,task⾥⼜会包含有很多task attempt的信息。我们可以模拟JobHistory解析jHistoryFile格式的job信息⽂件进⾏信息的分析。当然你可以⾃⼰到job的Path,做纯⽂本的解读。这⽅⾯的内容可以阅读我的这篇⽂章,。在task级别还有1个可以做的⽅⾯是增加counter,增加更多的⾃定义counte,counter的指标可以更加多元化,⽐如task Gc次数,full Gc总次数,reduce过程最后产⽣的⽂件数等等,这些指标都能细粒度的反映出这个task的执⾏好坏,如何加⾃定义的counter,⼤家也可以阅读我的这篇⽂章。还有1个微观层次的监控是基于⽤户的监控,将获取到的task,job这些按照⽤户进⾏聚合,排序,进⾏⼆次分析,就能到问题⽤户,使⽤资源的⼤户。
基于Hadoop源码的改造监控升级
这个监控改造是⼀个升级,补充了前者监控中的不⾜,因为前⾯2个都是属于离线分析,事后分析,我们当然需要实时的结果数据,当然我们不会再做⼀个类似的实时数据收集展⽰平台,我们直接改JobHistory界⾯,ResourceManager后台显⽰界⾯,展⽰更多的页⾯信息在界⾯上,⽼实说,⽬前的Hadoop版本中的⼀些Ganglia监控指标和JobHistoty的显⽰信息,实在有限,分为2种情况,Ganglia上是我们想要的监控⽬标上⾯没有,所以我们只能⾃⼰再加,JobHistory上则是指标太多,导致上⾯只显⽰了公共常见的⼀些信息,很多都是要点击到页⾯⾥才能看,因此我们做的改进是把⾥⾯的信息放出来。当然这些改造都是我们内部⾃⼰对Hadoop的源码进⾏改造的。
不⾜之处
1.这个不⾜之处是⽬前对于我们部门来说可以补充去做的地⽅,冷热数据的分析,这个也可以通过hdfs-audit⽇志⽂件,根据访问命中次数,然后动态调整相应的副本数,提⾼读写效率。
2.集所有⽂件的结构分析,⽐如所有⽂件的⼤⼩范围分布情况,是不是⼩⽂件在集中占了很⼤的⽐例,这个需要对fsimage⽂件做分析,这个我们之前也做过,但是没有做出⼯具,只是临时的解析了⼀下。
3.Container数据的获得,Container的数据在JobHistory上没有的,上⾯只有1个containerId。container的信息也很有⽤,上⾯有许多的优先级,还有附加的信息都可以了解到机器资源的使⽤情况等等。
⼯具分享链接
下⾯是我近端时间做分析⼯具的⼀些部分核⼼代码,供⼤家学习使⽤:
JobHistory⽂件⼿动分析⼯具:
NodeManager定时状态信息获取⼯具:
JobHistory⽂件程序分析⼯具:
HDFS RPC分⽤户,IP请求分析⼯具:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论