hdfs的jmx监控

hadoop提供了一个统一的监控策略,就是通过在jvm中收集metrics注册到jmx中,再通过rest接口对外提供数据,本文针对hdfs的jmx进行分析。

介绍

Hadoop的http监控端口基本所有人都知道,namenode 50070,jobtracker 50030,datanode 50075,tasktracker 50060。不过当用户访问这些端口的时候,会自动跳转到dfshealth.jsp或者jobtracker.jsp>这样的监控页面。jmx的访问很简 单,只需要把网页的名字换成jmx就可以了。http://your_namenode:50070/dfshealth的地址替换成http://your_namenode:50070/jmx
即可,其他如50030,50060等等,也依次类推,HBase的系统信息也可以用这种方法获取。
返回值全部是JSON,非常便于自己进行处理。返回的信息也非常详细,内存状态,内存池状态,java堆信息等等。甚至还有操作系统信息,版本,JVM版本信息等等,很全面。
对于http://your_namenode:50070/jmx 这样地址的数据访问可以通过HttpClient进行数据访问,再将得到的数据通过
由于返回的Json数据量很大,而且基本上不可能全部需要,对于这种情况可以通过添加?qry方式获得部分数据,例如http://your_namenode:50070/jmx?qry=Hadoop:service=HBase,name=Master,sub=Server

namenode的metrics分析

Hadoop:service=NameNode,name=JvmMetrics

对应类
JvmMetrics

作用
采用jvm相关的数据,包括gc,memory,thread,log信息,这是针对NameNode

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
"name" : "Hadoop:service=NameNode,name=JvmMetrics",
"modelerType" : "JvmMetrics",
"tag.Context" : "jvm",
"tag.ProcessName" : "NameNode",
"tag.SessionId" : null,
"tag.Hostname" : "idc07-daily-yoga-103716163.host.idcvdian.com",
"MemNonHeapUsedM" : 109.17598,
"MemNonHeapCommittedM" : 111.76953,
"MemNonHeapMaxM" : -1.0,
"MemHeapUsedM" : 2193.152,
"MemHeapCommittedM" : 18201.625,
"MemHeapMaxM" : 18201.625,
"MemMaxM" : 18201.625,
"GcCountParNew" : 4970,
"GcTimeMillisParNew" : 301880,
"GcCountConcurrentMarkSweep" : 2,
"GcTimeMillisConcurrentMarkSweep" : 1037,
"GcCount" : 4972,
"GcTimeMillis" : 302917,
"GcNumWarnThresholdExceeded" : 0,
"GcNumInfoThresholdExceeded" : 1,
"GcTotalExtraSleepTime" : 420004,
"ThreadsNew" : 0,
"ThreadsRunnable" : 10,
"ThreadsBlocked" : 0,
"ThreadsWaiting" : 11,
"ThreadsTimedWaiting" : 823,
"ThreadsTerminated" : 0,
"LogFatal" : 0,
"LogError" : 3,
"LogWarn" : 177,
"LogInfo" : 35261040
}

Hadoop:service=NameNode,name=IPCLoggerChannel

对应类
IPCLoggerChannelMetrics

作用
IPCLoggerChannel是namenode向journalnode同步editlog的rpc通道,而IPCLoggerChannelMetrics则记录了该rpc的一样信息,包括同步延迟,未同步数据量等。

样例

1
2
3
4
5
6
7
8
9
10
{
"name" : "Hadoop:service=NameNode,name=IPCLoggerChannel-10.37.16.165-8485",
"modelerType" : "IPCLoggerChannel-10.37.16.165-8485",
"tag.Context" : "dfs",
"tag.IsOutOfSync" : "false",
"tag.Hostname" : "idc07-daily-yoga-103716163.host.idcvdian.com",
"QueuedEditsSize" : 0,
"CurrentLagTxns" : 0,
"LagTimeMillis" : 0
}

Hadoop:service=NameNode,name=RpcActivityForPort8020

对应类
RpcMetrics

作用
为rpc服务提供metrics,核心的数据是rpc在队列中的平均等待时间和rpc的平均执行时间(不包括在队列中的等待时间),rpc处于打开中的链接数量,这3个指标可以表现出rpc服务端的压力。如果需要进一步了解rpc的metrics,hadoop提供了分位点算法,比如75%,95%,99%的rpc等待时间,rpc执行时间,这样能够更详细的看到rpc的分布情况,通过配置rpc.metrics.percentiles.interval,单位秒,用于控制metrics的数据滚动周期,可以配置多个,用逗号隔开。

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"name" : "Hadoop:service=NameNode,name=RpcActivityForPort8020",
"modelerType" : "RpcActivityForPort8020",
"tag.port" : "8020",
"tag.Context" : "rpc",
"tag.NumOpenConnectionsPerUser" : "{\"flink\":9,\"storm\":1,\"spark\":1,\"www\":66,\"hdfs\":7,\"hbase\":5,\"mapred\":1}",
"tag.Hostname" : "idc07-daily-yoga-103716163.host.idcvdian.com",
"ReceivedBytes" : 91602050651,
"SentBytes" : 297563822208,
"RpcQueueTimeNumOps" : 236585336,
"RpcQueueTimeAvgTime" : 0.09014084507042254,
"RpcProcessingTimeNumOps" : 236585336,
"RpcProcessingTimeAvgTime" : 1.323943661971831,
"RpcAuthenticationFailures" : 0,
"RpcAuthenticationSuccesses" : 0,
"RpcAuthorizationFailures" : 0,
"RpcAuthorizationSuccesses" : 1876208,
"RpcClientBackoff" : 0,
"RpcSlowCalls" : 0,
"NumOpenConnections" : 90,
"CallQueueLength" : 0
}

Hadoop:service=NameNode,name=FSNamesystem

对应类
org.apache.hadoop.hdfs.server.namenode.FSNamesystem

作用
hdfs namespace相关的度量信息,包括总block数,总文件数,hdfs存储空间,datanode统计信息等
可以通过hdfs dfsadmin -report或者hdfs fsck /来查看这些信息

下面列几个block相关的重要数据,可以参考类BlockManager

  • BlockTotal:block总数
  • MissingBlocks:丢失的块数量,如果某个block当前副本数是0,并且这个block没有下线的副本,那么这个快就是丢失的block
  • MissingReplOneBlocks:丢失的并且期望副本是1的block数量,在MissingBlocks基础上,多了一个期望副本是1的限制
  • UnderReplicatedBlocks:正在副本重置的block数量,包括UnderReplicatedBlocks对象的5个优先级所有的block数量
  • PendingReplicationBlocks: 等待副本重置的block的数量,参考类PendingReplicationBlocks
  • CorruptBlocks:所有损坏的block,也就是说这个block的所有副本都是Corrupt状态

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{
"name" : "Hadoop:service=NameNode,name=FSNamesystem",
"modelerType" : "FSNamesystem",
"tag.Context" : "dfs",
"tag.HAState" : "active",
"tag.TotalSyncTimes" : "2692 746 ",
"tag.Hostname" : "idc07-daily-yoga-103716163.host.idcvdian.com",
"MissingBlocks" : 0,
"MissingReplOneBlocks" : 0,
"ExpiredHeartbeats" : 0,
"TransactionsSinceLastCheckpoint" : 186482,
"TransactionsSinceLastLogRoll" : 7740,
"LastWrittenTransactionId" : 155107781,
"LastCheckpointTime" : 1548136284084,
"CapacityTotal" : 183706440458240,
"CapacityTotalGB" : 171090.0,
"CapacityUsed" : 1886357456810,
"CapacityUsedGB" : 1757.0,
"CapacityRemaining" : 171316371079293,
"CapacityRemainingGB" : 159551.0,
"CapacityUsedNonDFS" : 0,
"TotalLoad" : 50,
"SnapshottableDirectories" : 0,
"Snapshots" : 0,
"LockQueueLength" : 0,
"BlocksTotal" : 17639,
"NumFilesUnderConstruction" : 17,
"NumActiveClients" : 6,
"FilesTotal" : 169684,
"PendingReplicationBlocks" : 0,
"UnderReplicatedBlocks" : 2,
"CorruptBlocks" : 0,
"ScheduledReplicationBlocks" : 0,
"PendingDeletionBlocks" : 275,
"ExcessBlocks" : 0,
"NumTimedOutPendingReplications" : 0,
"PostponedMisreplicatedBlocks" : 0,
"PendingDataNodeMessageCount" : 0,
"MillisSinceLastLoadedEdits" : 0,
"BlockCapacity" : 67108864,
"StaleDataNodes" : 0,
"TotalFiles" : 169684,
"TotalSyncCount" : 4298
}

Hadoop:service=NameNode,name=StartupProgress

对应类
StartupProgress

作用
记录了namenode启动过程,namenode启动过程大概有4个核心数据

  1. FSImage文件的加载
  2. Edits文件的加载
  3. SavingPoint
  4. SafeMode

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"name" : "Hadoop:service=NameNode,name=StartupProgress",
"modelerType" : "StartupProgress",
"tag.Hostname" : "idc07-daily-yoga-103716163.host.idcvdian.com",
"ElapsedTime" : 63527,
"PercentComplete" : 1.0,
"LoadingFsImageCount" : 0,
"LoadingFsImageElapsedTime" : 1723,
"LoadingFsImageTotal" : 0,
"LoadingFsImagePercentComplete" : 1.0,
"LoadingEditsCount" : 27625,
"LoadingEditsElapsedTime" : 0,
"LoadingEditsTotal" : 27625,
"LoadingEditsPercentComplete" : 1.0,
"SavingCheckpointCount" : 0,
"SavingCheckpointElapsedTime" : 0,
"SavingCheckpointTotal" : 0,
"SavingCheckpointPercentComplete" : 1.0,
"SafeModeCount" : 1036,
"SafeModeElapsedTime" : 55696,
"SafeModeTotal" : 1036,
"SafeModePercentComplete" : 1.0
}

java开头的域

这些信息是jvm自带的jmx信息,也就是jvm帮你注册的一些metrics,下面列几个重要的信息

  • java.lang:type=Runtime
    记录了java的执行环境,也就是所有java -Dkey=value的中的配置
  • java.lang:type=Threading
    记录了jvm的线程信息,包括线程id和线程数量等
  • java.lang:type=Memory
    记录了当前jvm的内存使用情况,包括jvm维护的Heap和基于操作系统的nonHeap,这里详细解释一下几个数据的意义
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    {
    "name" : "java.lang:type=Memory",
    "modelerType" : "sun.management.MemoryImpl",
    "Verbose" : true,
    "ObjectPendingFinalizationCount" : 0,
    "HeapMemoryUsage" : {
    "committed" : 94245027840,
    "init" : 94489280512,
    "max" : 94245027840,
    "used" : 63494503464
    },
    "NonHeapMemoryUsage" : {
    "committed" : 152473600,
    "init" : 2555904,
    "max" : -1,
    "used" : 149752440
    },
    "ObjectName" : "java.lang:type=Memory"
    }

上面是一个典型的Memory的jmx信息,HeapMemoryUsage包含了Heap数据,NonHeapMemoryUsage包含了nonHeap数据,单位都是byte。

  • committed: 表示操作系统已经允许使用的内存大小,如果你配置的-Xms小于-Xmx,那么jvm在启动后committed的值会介于两者之间,然后随着jvm内存使用增大而增大,直到等于-Xmx。需要注意的是,committed不代表已经在操作系统上malloc了内存,由于memory page都是lazy分配的,只有在真正被访问的时候才会被分配到内存,这点可以修改jvm配置-XX:+AlwaysPreTouch,在启动时就完全加载,避免lazy操作。
  • init: jvm初始化的内存大小,可以在启动jvm的时候通过-Xms来修改
  • max: jvm最大的内存大小,可以在启动jvm的时候通过-Xmx来修改
  • used: jvm已经使用的内存大小,这个值和Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()是一样的
    再给一个官方文档的图

    |——–|
    init
    |—————|
    used
    |—————————|
    committed
    |———————————————-|
    max

参考

stackoverflow上关于MemoryUsage的讨论
官网给出的metrics解释
hdp论坛对StartuoProgress的讲解

ulysses wechat
订阅+